#include <sys_defs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#ifdef NO_HERRNO
static int h_errno = TRY_AGAIN;
#define HSTRERROR(err) "Host not found"
#else
#define HSTRERROR(err) (\
err == TRY_AGAIN ? "Host not found, try again" : \
err == HOST_NOT_FOUND ? "Host not found" : \
err == NO_DATA ? "Host name has no address" : \
err == NO_RECOVERY ? "Name server failure" : \
strerror(errno) \
)
#endif
#include <msg.h>
#include <mymalloc.h>
#include <valid_hostname.h>
#include <stringops.h>
#include "qmqpd.h"
void qmqpd_peer_init(QMQPD_STATE *state)
{
struct sockaddr_in sin;
SOCKADDR_SIZE len = sizeof(sin);
struct hostent *hp;
int i;
if (getpeername(vstream_fileno(state->client),
(struct sockaddr *) & sin, &len) >= 0) {
errno = 0;
}
if (errno == ECONNRESET || errno == ECONNABORTED) {
state->name = mystrdup("unknown");
state->addr = mystrdup("unknown");
}
else if (errno == 0 && sin.sin_family == AF_INET) {
state->addr = mystrdup(inet_ntoa(sin.sin_addr));
hp = gethostbyaddr((char *) &(sin.sin_addr),
sizeof(sin.sin_addr), AF_INET);
if (hp == 0) {
state->name = mystrdup("unknown");
} else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
state->name = mystrdup("unknown");
} else {
state->name = mystrdup(hp->h_name);
#define REJECT_PEER_NAME(state) { \
myfree(state->name); \
state->name = mystrdup("unknown"); \
}
hp = gethostbyname(state->name);
if (hp == 0) {
msg_warn("%s: hostname %s verification failed: %s",
state->addr, state->name, HSTRERROR(h_errno));
REJECT_PEER_NAME(state);
} else if (hp->h_length != sizeof(sin.sin_addr)) {
msg_warn("%s: hostname %s verification failed: bad address size %d",
state->addr, state->name, hp->h_length);
REJECT_PEER_NAME(state);
} else {
for (i = 0; ; i++) {
if (hp->h_addr_list[i] == 0) {
msg_warn("%s: address not listed for hostname %s",
state->addr, state->name);
REJECT_PEER_NAME(state);
break;
}
if (memcmp(hp->h_addr_list[i],
(char *) &sin.sin_addr,
sizeof(sin.sin_addr)) == 0)
break;
}
}
}
}
else {
state->name = mystrdup("localhost");
state->addr = mystrdup("127.0.0.1");
}
state->namaddr =
concatenate(state->name, "[", state->addr, "]", (char *) 0);
}
void qmqpd_peer_reset(QMQPD_STATE *state)
{
myfree(state->name);
myfree(state->addr);
myfree(state->namaddr);
}