summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNate Straz <nstraz@redhat.com>2006-08-03 14:48:40 +0000
committerNathan Straz <nstraz@redhat.com>2008-09-23 09:37:46 -0400
commitd1b5e0346ac271397d4d1df2417c3378f46ef4cb (patch)
treec2a2dde809428605f4cafaa604483feec1f49df8
parentc750cf3977831da3646bbfa0085147c27f4422ce (diff)
downloadqarsh-d1b5e0346ac271397d4d1df2417c3378f46ef4cb.zip
qarsh-d1b5e0346ac271397d4d1df2417c3378f46ef4cb.tar.gz
qarsh-d1b5e0346ac271397d4d1df2417c3378f46ef4cb.tar.xz
Add cookies to the heartbeat packet for added safety.v1.10-1
Two factors forced this change. 1. ports were being re-used so quickly that we could get lingering packets from past hosts when getting the btime for a new host. 2. We can't control which IP a btime response is sent from if a system has more than one interface. Adding a cookie allows us to know that a response came from whom we sent it.
-rw-r--r--btime.c60
-rw-r--r--btime_int.h2
-rw-r--r--btimed.c23
-rw-r--r--qarsh.spec7
4 files changed, 71 insertions, 21 deletions
diff --git a/btime.c b/btime.c
index bb0857e..5e151be 100644
--- a/btime.c
+++ b/btime.c
@@ -13,6 +13,7 @@
#include "btime_int.h"
static int same_addr(struct sockaddr_in *a, struct sockaddr_in *b);
+static void gen_cookie(char *s);
/*
* btime --
*
@@ -27,15 +28,16 @@ unsigned int
btime(const char *host)
{
int sd;
- char msg[BTIME_MSGLEN];
+ char cookie[BTIME_MSGLEN];
+ char response[BTIME_MSGLEN];
struct sockaddr_in serv_addr;
struct sockaddr_in my_addr;
struct sockaddr_in resp_addr;
- int serv_addr_len;
- int resp_addr_len;
+ socklen_t serv_addr_len;
+ socklen_t resp_addr_len;
struct hostent *hostent;
in_addr_t inaddr;
- unsigned int btime;
+ unsigned int btime = 0;
ssize_t nbytes;
int retry;
@@ -69,10 +71,11 @@ btime(const char *host)
return 0;
}
- memset(msg, 0, BTIME_MSGLEN);
+ 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, &msg, BTIME_MSGLEN, MSG_DONTWAIT,
+ if ((nbytes = sendto(sd, &cookie, BTIME_MSGLEN, MSG_DONTWAIT,
(struct sockaddr *)&serv_addr, serv_addr_len)) < 0) {
if (errno == EAGAIN) {
usleep(retry * 100);
@@ -87,18 +90,34 @@ btime(const char *host)
memset(&resp_addr, 0, sizeof resp_addr);
- memset(msg, 0, BTIME_MSGLEN);
+ memset(response, 0, BTIME_MSGLEN);
for (retry = 0; retry < MAX_RETRY; retry++) {
resp_addr_len = sizeof resp_addr;
- if ((nbytes = recvfrom(sd, &msg, BTIME_MSGLEN, MSG_DONTWAIT,
+ if ((nbytes = recvfrom(sd, &response, BTIME_MSGLEN, MSG_DONTWAIT,
(struct sockaddr *)&resp_addr, &resp_addr_len)) < 0) {
if (errno == EAGAIN) {
usleep(retry * 100);
+ continue;
} else {
/* Non EAGAIN error... */
break;
}
+ }
+
+ if (nbytes == 0) {
+ /* Nothing received, try again */
+ continue;
+ } else 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);
+ break;
+ } else {
+ fprintf(stderr, "Ignoring invalid cookie\n");
+ continue;
+ }
} else if (!same_addr(&serv_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));
fprintf(stderr, "Got response from %s instead of %s\n",
@@ -107,16 +126,12 @@ btime(const char *host)
free(sstr);
continue;
} else {
+ /* If peer matches, accept the bare btime */
+ btime = strtoul(response, (char **)NULL, 10);
break;
}
}
- if (nbytes == 0) {
- btime = 0;
- } else {
- btime = strtoul(msg, (char **)NULL, 10);
- }
-
close(sd);
return btime;
@@ -141,3 +156,20 @@ same_addr(struct sockaddr_in *a, struct sockaddr_in *b)
return 1;
}
}
+/* gen_cookie
+ *
+ * Generate a random string that btimed will send back to us.
+ */
+static void gen_cookie(char *s)
+{
+ char *a = s;
+ int i;
+
+ *a++ = 'B';
+ *a++ = 'T';
+ for (i = 0; i < COOKIE_RANDOM_PARTS; i++) {
+ *(int *)a = random();
+ a += sizeof(int);
+ }
+ *a = '\n';
+}
diff --git a/btime_int.h b/btime_int.h
index b2cafcd..73adaa4 100644
--- a/btime_int.h
+++ b/btime_int.h
@@ -9,4 +9,6 @@
#define BTIME_MSGLEN 128
#define MAX_RETRY 5
+#define COOKIE_RANDOM_PARTS 4
+#define COOKIE_LEN (3 + (COOKIE_RANDOM_PARTS * sizeof(int)))
#endif /* __BTIME_INT_H */
diff --git a/btimed.c b/btimed.c
index 544d108..c02b0bc 100644
--- a/btimed.c
+++ b/btimed.c
@@ -22,9 +22,11 @@ main(int argc, char **argv)
{
int sd;
char inmsg[BTIME_MSGLEN];
- char outmsg[BTIME_MSGLEN];
+ char btimeonly[BTIME_MSGLEN];
+ char cookiemsg[BTIME_MSGLEN];
+ char *outmsg;
struct sockaddr_in cli_addr;
- int cli_addr_len;
+ socklen_t cli_addr_len;
ssize_t nbytes;
unsigned int local_btime;
@@ -37,13 +39,14 @@ main(int argc, char **argv)
alarm(30);
/* Generate the standard btime message */
- memset(outmsg, 0, BTIME_MSGLEN);
+ memset(btimeonly, 0, BTIME_MSGLEN);
local_btime = get_btime();
- sprintf(outmsg, "%u\n", local_btime);
+ sprintf(btimeonly, "%u\n", local_btime);
syslog(LOG_INFO, "started with btime = %u", local_btime);
for (;;) {
memset(&cli_addr, 0, sizeof cli_addr);
+ memset(inmsg, 0, BTIME_MSGLEN);
cli_addr_len = sizeof cli_addr;
nbytes = recvfrom(sd, &inmsg, BTIME_MSGLEN, MSG_WAITALL,
(struct sockaddr *)&cli_addr, &cli_addr_len);
@@ -55,8 +58,18 @@ main(int argc, char **argv)
syslog(LOG_INFO, "exitting");
exit(0);
}
+ if (inmsg[0] == 'B' && inmsg[1] == 'T' ) {
+ /* New style heartbeat with cookie */
+ /* Copy cookie to message and append timestamp */
+ memset(cookiemsg, 0, BTIME_MSGLEN);
+ memcpy(cookiemsg, inmsg, COOKIE_LEN);
+ strcpy(cookiemsg + COOKIE_LEN, btimeonly);
+ outmsg = cookiemsg;
+ } else {
+ outmsg = btimeonly;
+ }
- sendto(sd, &outmsg, BTIME_MSGLEN, MSG_DONTWAIT,
+ sendto(sd, outmsg, BTIME_MSGLEN, MSG_DONTWAIT,
(struct sockaddr *)&cli_addr, cli_addr_len);
/* We want to exit after 30 seconds of inactivity */
alarm(30);
diff --git a/qarsh.spec b/qarsh.spec
index 21a0105..da03625 100644
--- a/qarsh.spec
+++ b/qarsh.spec
@@ -1,7 +1,7 @@
Summary: QA Remote Shell
Name: qarsh
-Version: 1.9
-Release: 2
+Version: 1.10
+Release: 1
Group: QA
License: GPL
Buildroot: %{_tmppath}/%{name}-%{version}-root
@@ -67,6 +67,9 @@ fi
%config /etc/xinetd.d/btimed
%changelog
+* Thu Aug 03 2006 Nathan Straz <nstraz@redhat.com> 1.10-1
+- Add cookies to the heartbeat packet.
+
* Thu Jun 08 2006 1.9-2
- Add some debugging messages to find the mysterious client rebooted bug.