diff options
author | Dean Jansa <djansa@redhat.com> | 2010-09-03 12:57:38 -0500 |
---|---|---|
committer | Dean Jansa <djansa@redhat.com> | 2010-09-03 12:57:38 -0500 |
commit | 158d69d419595ba2c79e85b9d6d0d9b324654433 (patch) | |
tree | eec97af3398ad7711ebab468f2f0b968d5401a0a | |
parent | 0b8f4c9e6a7438d9829d526ab1879149818312d8 (diff) | |
download | qarsh-158d69d419595ba2c79e85b9d6d0d9b324654433.tar.gz qarsh-158d69d419595ba2c79e85b9d6d0d9b324654433.tar.xz qarsh-158d69d419595ba2c79e85b9d6d0d9b324654433.zip |
update btime and hbeat libs to understand ipv6 as well as ipv4.
-rw-r--r-- | btime.c | 100 | ||||
-rw-r--r-- | btimed.c | 2 | ||||
-rw-r--r-- | hbeat.c | 30 |
3 files changed, 83 insertions, 49 deletions
@@ -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 * @@ -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; @@ -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; |