From 5723b2e75be3b7076d32a61062fa8e7bda951c1c Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Mon, 18 Jul 2016 12:28:40 +0200 Subject: [PATCH] Refactor RFC 868, time protocol plugin - Always do a dummy read to get peer address. - Refactor to new format used by other built-ins Signed-off-by: Joachim Nilsson --- plugins/time.c | 61 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/plugins/time.c b/plugins/time.c index 14e10af6..019e29eb 100644 --- a/plugins/time.c +++ b/plugins/time.c @@ -32,33 +32,58 @@ #define EPOCH_OFFSET 2208988800ULL /* Return number of seconds since midnight, 1st Jan, 1900 */ -static int cb(int type) +static char *rfctime(char *buf, size_t *len) { - int sd = STDIN_FILENO; time_t now; - struct sockaddr_storage sa; - socklen_t sa_len = sizeof(sa); - - if (SOCK_DGRAM == type) { - int dummy; - - /* Read empty datagram in UDP mode before sending reply. */ - if (-1 == recvfrom(sd, &dummy, sizeof(dummy), MSG_DONTWAIT, (struct sockaddr *)&sa, &sa_len)) - return -1; /* On error, close connection. */ - } now = time(NULL); if ((time_t)-1 == now) - return -1; /* On error, close connection. */ + return NULL; - /* Account for UNIX epoch offset */ + /* + * Account for UNIX epoch offset, and + * convert to network byte order + */ now += EPOCH_OFFSET; + now = htonl(now); - /* Convert to network byte order, not explicitly stated in RFC */ - now = htonl(now); + *len = sizeof(now); + memcpy(buf, &now, *len); - /* Send reply, ignore error, simply close connection. */ - return sendto(sd, &now, sizeof(now), MSG_DONTWAIT, (struct sockaddr *)&sa, sa_len); + return buf; +} + +static int recv_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t *sa_len) +{ + len = recvfrom(sd, buf, sizeof(buf), MSG_DONTWAIT, sa, sa_len); + if (-1 == len) + return -1; /* On error, close connection. */ + + return 0; +} + +static int send_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t sa_len) +{ + char *now; + + now = rfctime(buf, &len); + if (!now) + return -1; /* On error, close connection. */ + + return sendto(sd, now, len, MSG_DONTWAIT, sa, sa_len); +} + +static int cb(int type) +{ + int sd = STDIN_FILENO; + char buf[BUFSIZ]; + struct sockaddr_storage sa; + socklen_t sa_len = sizeof(sa); + + if (recv_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, &sa_len)) + return -1; /* On error, close connection. */ + + return send_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, sa_len); } static plugin_t plugin = {