summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipxrelay.c57
1 files changed, 21 insertions, 36 deletions
diff --git a/ipxrelay.c b/ipxrelay.c
index b7c99a1..72eca97 100644
--- a/ipxrelay.c
+++ b/ipxrelay.c
@@ -17,7 +17,7 @@
#include <netinet/in.h>
#include <netdb.h>
-#define VERSION_STRING "0.1"
+#define VERSION_STRING "0.2"
const char *_progname;
@@ -110,48 +110,34 @@ struct ipx_header {
} __attribute__((packed));
/*
- * Simple timer to make sure that stale clients don't stay indefinitely
- * due to no activity at all. Note that there is no point to run the
- * timer if there are no currently registered clients, so disable the
- * timer in that case so that an idle server can consume zero CPU resources.
+ * Simple timeout to make sure that stale clients don't hog memory
+ * indefinitely due to no activity at all. Note that there is no
+ * point to run the timeout if there are no currently registered
+ * clients, so disable the timeout in that case so that an idle server
+ * can consume zero CPU resources.
*/
-static void sigalrm(int sig)
-{
- (void)sig;
- /* No action, just kick recvfrom() */
-}
-
-static void prepare_timer(void)
-{
- struct sigaction sa;
-
- memset(&sa, 0, sizeof sa);
-
- sa.sa_handler = sigalrm;
- sigaction(SIGALRM, &sa, NULL);
-}
-static void enable_timer(void)
+static void enable_timeout(int fd)
{
- struct itimerval it;
+ struct timeval timeout;
- it.it_interval.tv_sec = it.it_value.tv_sec = opt.timeout;
- it.it_interval.tv_usec = it.it_value.tv_usec = 0;
+ timeout.tv_sec = opt.timeout;
+ timeout.tv_usec = 0;
- setitimer(ITIMER_REAL, &it, NULL);
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
}
-static void disable_timer(void)
+static void disable_timeout(int fd)
{
- struct itimerval it;
+ struct timeval timeout;
- it.it_interval.tv_sec = it.it_value.tv_sec = 0;
- it.it_interval.tv_usec = it.it_value.tv_usec = 0;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
- setitimer(ITIMER_REAL, &it, NULL);
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
}
-static void cleanup_timeouts(time_t now)
+static void cleanup_timeouts(int fd, time_t now)
{
struct ipx_client *c, *p;
@@ -166,7 +152,7 @@ static void cleanup_timeouts(time_t now)
}
if (client_head.next == &client_head)
- disable_timer();
+ disable_timeout(fd);
}
static void bump_timeout(struct ipx_client *c, time_t now)
@@ -245,7 +231,7 @@ static int register_client(int fd, const struct ipx_header *hdr,
/* Was this the first client? */
if (c->next == &client_head)
- enable_timer();
+ enable_timeout(fd);
/* Send an acknowledgement packet */
reply.checksum = 0xffff;
@@ -272,12 +258,11 @@ static int ipx_relay_server(int fd)
int len, hlen;
struct ipx_client *s, *d;
- prepare_timer();
now = time(NULL);
while (1) {
/* Potentially redundant, but if so very cheap so we don't care */
- cleanup_timeouts(now);
+ cleanup_timeouts(fd, now);
fromlen = sizeof from;
len = recvfrom(fd, pkt.buf, sizeof pkt, 0, &from, &fromlen);
@@ -317,7 +302,7 @@ static int ipx_relay_server(int fd)
bump_timeout(s, now);
/* Handle timeouts here rather than sending to a dead client */
- cleanup_timeouts(now);
+ cleanup_timeouts(fd, now);
/* Now s->next is a linked list of all *other* clients */