From f023e47b9dac5be1d76013a4f74c322f6c520f2a Mon Sep 17 00:00:00 2001 From: Ari Johnson Date: Tue, 20 Feb 2007 19:39:22 +0000 Subject: [PATCH] Added keepalive_timeout configuration option; fixed SO_KEEPALIVE --- game/mushcnf.dst | 11 ++++++++++- hdrs/conf.h | 1 + src/conf.c | 3 +++ src/mysocket.c | 20 ++++++++++++++------ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/game/mushcnf.dst b/game/mushcnf.dst index 1f791b7..17a83b6 100644 --- a/game/mushcnf.dst +++ b/game/mushcnf.dst @@ -217,10 +217,19 @@ idle_timeout 0m # If you don't want a timeout, set it to 0. unconnected_idle_timeout 5m - # how many seconds till we consider someone idled? idle_time 30m +# Many common home network routers will drop a connection if there's +# been no activity for a few minutes; they tend to assume the web is +# the internet, and don't deal well with persistant connections like +# mushes use. This option will make the server automatically send a +# 'Are you still there?' query every few minutes to keep the +# connection active. +# NOTE: This doesn't work on all OSes, but does on the most popular +# ones for mush hosting such as linux. +keepalive_timeout 5m + # Should there be a limit on the number of logins the MUSH # can accept? If your operating system has a limited number of # file descriptors per process, you should set this to diff --git a/hdrs/conf.h b/hdrs/conf.h index 2bbd23c..cdca180 100644 --- a/hdrs/conf.h +++ b/hdrs/conf.h @@ -133,6 +133,7 @@ struct options_table { int idle_timeout; /**< Maximum idle time allowed, in minutes */ int idle_time; /** Time for the system to consider player 'idle' used in conjuntion with @AUNIDLE */ int unconnected_idle_timeout; /**< Maximum idle time for connections without dbrefs, in minutes */ + int keepalive_timeout; /**< Number of seconds between TCP keepalive pings */ int dump_interval; /**< Interval between database dumps, in seconds */ char dump_message[256]; /**< Message shown at start of nonforking dump */ char dump_complete[256]; /**< Message shown at end of nonforking dump */ diff --git a/src/conf.c b/src/conf.c index 9fb25a7..2d49958 100644 --- a/src/conf.c +++ b/src/conf.c @@ -291,6 +291,8 @@ COBRA_CONF conftable[] = { {"unconnected_idle_timeout", cf_time, &options.unconnected_idle_timeout, 100000, 0, "limits"} , + {"keepalive_timeout", cf_time, &options.keepalive_timeout, 10000, 0, "limits"} + , {"whisper_loudness", cf_int, &options.whisper_loudness, 100, 0, "limits"} , {"starting_quota", cf_int, &options.starting_quota, 10000, 0, "limits"} @@ -1066,6 +1068,7 @@ conf_default_set(void) options.idle_timeout = 0; options.idle_time = 0; options.unconnected_idle_timeout = 300; + options.keepalive_timeout = 300; options.dump_interval = 3601; strcpy(options.dump_message, T("GAME: Dumping database. Game may freeze for a minute")); diff --git a/src/mysocket.c b/src/mysocket.c index ceab173..d361b97 100644 --- a/src/mysocket.c +++ b/src/mysocket.c @@ -354,7 +354,7 @@ make_nonblocking(int s) } - +#ifndef INFOSLAVE /** Enable TCP keepalive on the given socket if we can. * \param s socket. */ @@ -362,25 +362,33 @@ make_nonblocking(int s) void set_keepalive(int s __attribute__ ((__unused__))) { -#ifdef CAN_KEEPALIVE +#ifdef SO_KEEPALIVE int keepalive = 1; -#ifdef CAN_KEEPIDLE - int keepidle = 900; +#if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE) + int keepidle = options.keepalive_timeout; #endif /* enable TCP keepalive */ if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &keepalive, sizeof(keepalive)) == -1) fprintf(stderr, "[%d] could not set SO_KEEPALIVE: errno %d", s, errno); -#ifdef CAN_KEEPIDLE + + /* And set the ping time to something reasonable instead of the + default 2 hours. Linux, NetBSD and o thers use TCP_KEEPIDLE to do + this. OS X and possibly others use TCP_KEEPALIVE. */ +#if defined(TCP_KEEPIDLE) if (setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, (void *) &keepidle, sizeof(keepidle)) == -1) + fprintf(stderr, "[%d] could not set TCP_KEEPIDLE: errno %d", s, errno); +#elif defined(TCP_KEEPALIVE) + if (setsockopt(s, IPPROTO_TCP, TCP_KEEPALIVE, + (void *) &keepidle, sizeof(keepidle)) == -1) fprintf(stderr, "[%d] could not set TCP_KEEPALIVE: errno %d", s, errno); #endif #endif return; } - +#endif /** Connect a socket, possibly making it nonblocking first. -- 2.30.2