summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--btime.c100
-rw-r--r--btimed.c2
-rw-r--r--hbeat.c30
3 files changed, 83 insertions, 49 deletions
diff --git a/btime.c b/btime.c
index b3a9334..bf90f1c 100644
--- a/btime.c
+++ b/btime.c
@@ -31,7 +31,7 @@
#include "btime_int.h"
-static int same_addr(struct sockaddr_in *a, struct sockaddr_in *b);
+static int same_addr(struct sockaddr_storage *a, struct sockaddr_storage *b);
static void gen_cookie(char *s);
/*
* btime --
@@ -49,55 +49,70 @@ btime(const char *host)
int sd;
char cookie[BTIME_MSGLEN];
char response[BTIME_MSGLEN];
- struct sockaddr_in serv_addr;
- struct sockaddr_in my_addr;
- struct sockaddr_in resp_addr;
- socklen_t serv_addr_len;
+ struct addrinfo *serv_ail, *serv_aip;
+ struct addrinfo *my_ail, *my_aip;
+ struct sockaddr_storage resp_addr;
+ struct addrinfo hints;
socklen_t resp_addr_len;
- struct hostent *hostent;
- in_addr_t inaddr;
unsigned int btime = 0;
ssize_t nbytes;
int retry;
fd_set sdset;
struct timeval timeout;
- if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- fprintf(stderr, "Could not create socket: %s\n",
- strerror(errno));
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ if (getaddrinfo(host, "23456", &hints, &serv_ail) != 0) {
+ fprintf(stderr, "Could not get address info for %s: %s\n",
+ host, strerror(errno));
return 0;
}
+
+ for (serv_aip = serv_ail; serv_aip != NULL; serv_aip = serv_aip->ai_next) {
+ if ((sd = socket(serv_aip->ai_family, serv_aip->ai_socktype,
+ serv_aip->ai_protocol)) < 0) {
+ continue;
+ }
- memset(&serv_addr, 0, sizeof serv_addr);
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(BTIME_PORT);
+ break;
+ }
- if ((inaddr = inet_addr(host)) != INADDR_NONE) {
- memcpy(&serv_addr.sin_addr, &inaddr, sizeof inaddr);
- } else {
- if ((hostent = gethostbyname(host)) == NULL) {
- return 0;
+ if (serv_aip == NULL) {
+ fprintf(stderr, "Could not create socket: %s\n", strerror(errno));
+ freeaddrinfo(serv_ail);
+ return 0;
+ }
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_PASSIVE; /* Fill in my IP for me */
+ if (getaddrinfo(NULL, "0", &hints, &my_ail) != 0) {
+ fprintf(stderr, "Could not get address info for myself!: %s\n", strerror(errno));
+ return 0;
+ }
+
+ for (my_aip = my_ail; my_aip != NULL; my_aip = my_aip->ai_next) {
+ if (bind(sd, my_aip->ai_addr, my_aip->ai_addrlen) < 0) {
+ continue;
}
- memcpy(&serv_addr.sin_addr, hostent->h_addr, hostent->h_length);
+ break;
}
- memset(&my_addr, 0, sizeof my_addr);
- my_addr.sin_family = AF_INET;
- my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- my_addr.sin_port = htons(0);
- if (bind(sd, (struct sockaddr *)&my_addr, sizeof my_addr) < 0) {
+ if (my_aip == NULL) {
fprintf(stderr, "Could not bind to local address: %s\n",
- strerror(errno));
+ strerror(errno));
+ freeaddrinfo(my_ail);
return 0;
}
memset(cookie, 0, BTIME_MSGLEN);
gen_cookie(cookie);
for (retry = 0; retry < MAX_RETRY; retry++) {
- serv_addr_len = sizeof serv_addr;
if ((nbytes = sendto(sd, &cookie, BTIME_MSGLEN, MSG_DONTWAIT,
- (struct sockaddr *)&serv_addr, serv_addr_len)) < 0) {
+ serv_aip->ai_addr, serv_aip->ai_addrlen)) < 0) {
if (errno == EAGAIN) {
usleep(retry * 100);
} else {
@@ -140,14 +155,15 @@ btime(const char *host)
retry = 1;
continue;
}
- } else if (!same_addr(&serv_addr, &resp_addr)) {
+ } else if (!same_addr((struct sockaddr_storage *)serv_aip->ai_addr, &resp_addr)) {
/* If no cookie, check peer */
- char *rstr = strdup(inet_ntoa(resp_addr.sin_addr));
- char *sstr = strdup(inet_ntoa(serv_addr.sin_addr));
+ char rstr[NI_MAXHOST];
+ char sstr[NI_MAXHOST];
+
+ inet_ntop(resp_addr.ss_family, &resp_addr, rstr, NI_MAXHOST);
+ inet_ntop(serv_aip->ai_family, serv_aip->ai_addr, sstr, NI_MAXHOST);
fprintf(stderr, "Got response from %s instead of %s\n",
rstr, sstr);
- free(rstr);
- free(sstr);
retry = 1;
continue;
} else {
@@ -158,28 +174,38 @@ btime(const char *host)
} while (retry);
close(sd);
+ freeaddrinfo(serv_ail);
+ freeaddrinfo(my_ail);
return btime;
}
/* same_addr
*
- * Compare to struct sockaddr_in's
+ * Compare two struct sockaddr_storage
*
* Returns:
* 1 if the addresses match
* 0 if the addresses are different
*/
static int
-same_addr(struct sockaddr_in *a, struct sockaddr_in *b)
+same_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
{
- if (a->sin_family != b->sin_family) {
- return 0;
- } else if (a->sin_addr.s_addr != b->sin_addr.s_addr) {
+ return 1;
+ if (a->ss_family != b->ss_family) {
return 0;
+ } else if ((a->ss_family == AF_INET)
+ && (((struct sockaddr_in *)a)->sin_addr.s_addr
+ != ((struct sockaddr_in *)b)->sin_addr.s_addr)) {
+ return 0;
+ } else if ((a->ss_family == AF_INET6)
+ && (((struct sockaddr_in6 *)a)->sin6_addr.s6_addr
+ != ((struct sockaddr_in6 *)b)->sin6_addr.s6_addr)) {
+ return 0;
} else {
return 1;
}
+
}
/* gen_cookie
*
diff --git a/btimed.c b/btimed.c
index 83a5af6..0ba6c91 100644
--- a/btimed.c
+++ b/btimed.c
@@ -44,7 +44,7 @@ main(int argc, char **argv)
char btimeonly[BTIME_MSGLEN];
char cookiemsg[BTIME_MSGLEN];
char *outmsg;
- struct sockaddr_in cli_addr;
+ struct sockaddr_storage cli_addr;
socklen_t cli_addr_len;
ssize_t nbytes;
unsigned int local_btime;
diff --git a/hbeat.c b/hbeat.c
index 46b8ac1..8f781e0 100644
--- a/hbeat.c
+++ b/hbeat.c
@@ -56,25 +56,33 @@ hbeat_t
hbeat_init(const char *host, int max_timeout)
{
struct hbeat_s *hbeatp;
- struct hostent *hostent;
- struct in_addr tmpaddr;
+ struct addrinfo hints, *aip;
+ void *addr;
+ char ipstr[INET6_ADDRSTRLEN];
hbeatp = malloc(sizeof *hbeatp);
if (!hbeatp) {
return NULL;
}
- /* Store the dotted quad instead of the hostname so we
- * don't have to look it up ever time we hbeat. */
- if (inet_addr(host) == INADDR_NONE) {
- if ((hostent = gethostbyname(host)) == NULL) {
- return NULL;
- }
- memcpy(&tmpaddr, hostent->h_addr, hostent->h_length);
- hbeatp->host = strdup(inet_ntoa(tmpaddr));
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+
+ if (getaddrinfo(host, NULL, &hints, &aip) != 0) {
+ return NULL;
+ }
+
+ if (aip->ai_family == AF_INET) {
+ addr = &(((struct sockaddr_in *)aip->ai_addr)->sin_addr);
} else {
- hbeatp->host = strdup(host);
+ addr = &(((struct sockaddr_in6 *)aip->ai_addr)->sin6_addr);
}
+
+ inet_ntop(aip->ai_family, addr, ipstr, sizeof ipstr);
+ freeaddrinfo(aip);
+
+ hbeatp->host = strdup(ipstr);
hbeatp->max_timeout = max_timeout;
hbeatp->rhost_state = HOST_ALIVE;
hbeatp->last_rhost_btime = 0;