summaryrefslogtreecommitdiffstats
path: root/btime.c
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2013-09-11 16:35:04 -0400
committerNathan Straz <nstraz@redhat.com>2013-09-11 17:52:01 -0400
commit806ec3c06915b19c3ab6bb3cb8e1e146bfba5c29 (patch)
treed4f89be09817a14dffff2414f279ebb3142cfc0a /btime.c
parent2cfe3b04213c1a7a5023622abfdedadbf8436b80 (diff)
downloadqarsh-806ec3c06915b19c3ab6bb3cb8e1e146bfba5c29.zip
qarsh-806ec3c06915b19c3ab6bb3cb8e1e146bfba5c29.tar.gz
qarsh-806ec3c06915b19c3ab6bb3cb8e1e146bfba5c29.tar.xz
Split btime into two parts
We don't need to lookup the addresses every time we get btime. Do it once during hbeat_init and reuse the socket in hbeat. This cleans up the qarsh strace so the hbeat is only a send and recv.
Diffstat (limited to 'btime.c')
-rw-r--r--btime.c140
1 files changed, 66 insertions, 74 deletions
diff --git a/btime.c b/btime.c
index 15d52f1..962615c 100644
--- a/btime.c
+++ b/btime.c
@@ -31,34 +31,20 @@
#include "btime_int.h"
-static int same_addr(struct sockaddr_storage *a, struct sockaddr_storage *b);
static void gen_cookie(char *s);
/*
- * btime --
- *
- * Return the boot time of a remote host if that host is running the
- * btimed deamon.
+ * btime_init --
*
- * Returns:
- * btime, or 0 on failure.
+ * Prepare a socket to use for getting boot time from btimed
*/
-unsigned int
-btime(const char *host)
+int
+btime_init(const char *host)
{
- int sd;
- char cookie[BTIME_MSGLEN];
- char response[BTIME_MSGLEN];
+ int sd = 0;
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;
- unsigned int btime = 0;
- ssize_t nbytes;
- int retry;
- fd_set sdset;
- struct timeval timeout;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
@@ -80,8 +66,8 @@ btime(const char *host)
if (serv_aip == NULL) {
fprintf(stderr, "Could not create socket: %s\n", strerror(errno));
- freeaddrinfo(serv_ail);
- return 0;
+ sd = 0;
+ goto free_serv;
}
memset(&hints, 0, sizeof hints);
@@ -90,7 +76,8 @@ btime(const char *host)
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;
+ sd = 0;
+ goto free_serv;
}
for (my_aip = my_ail; my_aip != NULL; my_aip = my_aip->ai_next) {
@@ -104,15 +91,47 @@ btime(const char *host)
if (my_aip == NULL) {
fprintf(stderr, "Could not bind to local address: %s\n",
strerror(errno));
- freeaddrinfo(my_ail);
- return 0;
+ sd = 0;
+ goto free_my;
+ }
+
+ if (connect(sd, serv_aip->ai_addr, serv_aip->ai_addrlen) < 0) {
+ fprintf(stderr, "Could not connect to host: %s\n",
+ strerror(errno));
+ sd = 0;
}
+free_my:
+ freeaddrinfo(my_ail);
+free_serv:
+ freeaddrinfo(serv_ail);
+
+ return sd;
+}
+
+/*
+ * btime_do --
+ *
+ * Get the boot time from btimed using an already prepared socket
+ *
+ * Returns:
+ * btime, or 0 on failure.
+ */
+unsigned int
+btime_do(const int sd)
+{
+ char cookie[BTIME_MSGLEN];
+ char response[BTIME_MSGLEN];
+ unsigned int btime = 0;
+ ssize_t nbytes;
+ int retry;
+ fd_set sdset;
+ struct timeval timeout;
+
memset(cookie, 0, BTIME_MSGLEN);
gen_cookie(cookie);
for (retry = 0; retry < MAX_RETRY; retry++) {
- if ((nbytes = sendto(sd, &cookie, BTIME_MSGLEN, MSG_DONTWAIT,
- serv_aip->ai_addr, serv_aip->ai_addrlen)) < 0) {
+ if ((nbytes = send(sd, &cookie, BTIME_MSGLEN, MSG_DONTWAIT)) < 0) {
if (errno == EAGAIN) {
usleep(retry * 100);
} else {
@@ -137,15 +156,12 @@ btime(const char *host)
break;
}
- memset(&resp_addr, 0, sizeof resp_addr);
memset(response, 0, BTIME_MSGLEN);
- resp_addr_len = sizeof resp_addr;
- nbytes = recvfrom(sd, &response, BTIME_MSGLEN, MSG_DONTWAIT,
- (struct sockaddr *)&resp_addr, &resp_addr_len);
- if (nbytes == 0) {
- /* Nothing received */
- continue;
- } else if (response[0] == 'B' && response[1] == 'T') {
+ nbytes = recv(sd, &response, BTIME_MSGLEN, MSG_DONTWAIT);
+
+ if (nbytes == 0) continue; /* Nothing received */
+
+ if (response[0] == 'B' && response[1] == 'T') {
/* Check for new style cookie */
if (memcmp(cookie, response, COOKIE_LEN) == 0) {
btime = strtoul(response+COOKIE_LEN, NULL, 10);
@@ -155,58 +171,34 @@ btime(const char *host)
retry = 1;
continue;
}
- } else if (!same_addr((struct sockaddr_storage *)serv_aip->ai_addr, &resp_addr)) {
- /* If no cookie, check peer */
- 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);
- retry = 1;
- continue;
- } else {
- /* If peer matches, accept the bare btime */
- btime = strtoul(response, (char **)NULL, 10);
- break;
}
} while (retry);
- close(sd);
- freeaddrinfo(serv_ail);
- freeaddrinfo(my_ail);
-
return btime;
}
-/* same_addr
- *
- * Compare two struct sockaddr_storage
+/*
+ * btime --
+ *
+ * Return the boot time of a remote host if that host is running the
+ * btimed deamon.
*
* Returns:
- * 1 if the addresses match
- * 0 if the addresses are different
+ * btime, or 0 on failure.
*/
-static int
-same_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
+
+unsigned int
+btime(const char *host)
{
- 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;
- }
+ int s;
+ unsigned int b;
+ s = btime_init(host);
+ b = btime_do(s);
+ close(s);
+ return b;
}
+
/* gen_cookie
*
* Generate a random string that btimed will send back to us.