summaryrefslogtreecommitdiffstats
path: root/btime.c
diff options
context:
space:
mode:
authorDean Jansa <djansa@redhat.com>2010-09-03 12:57:38 -0500
committerDean Jansa <djansa@redhat.com>2010-09-03 12:57:38 -0500
commit158d69d419595ba2c79e85b9d6d0d9b324654433 (patch)
treeeec97af3398ad7711ebab468f2f0b968d5401a0a /btime.c
parent0b8f4c9e6a7438d9829d526ab1879149818312d8 (diff)
downloadqarsh-158d69d419595ba2c79e85b9d6d0d9b324654433.zip
qarsh-158d69d419595ba2c79e85b9d6d0d9b324654433.tar.gz
qarsh-158d69d419595ba2c79e85b9d6d0d9b324654433.tar.xz
update btime and hbeat libs to understand ipv6 as well as ipv4.
Diffstat (limited to 'btime.c')
-rw-r--r--btime.c100
1 files changed, 63 insertions, 37 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
*