Added keepalive_timeout configuration option; fixed SO_KEEPALIVE
authorAri Johnson <ari@cobramush.org>
Tue, 20 Feb 2007 19:39:22 +0000 (19:39 +0000)
committerAri Johnson <ari@cobramush.org>
Tue, 20 Feb 2007 19:39:22 +0000 (19:39 +0000)
game/mushcnf.dst
hdrs/conf.h
src/conf.c
src/mysocket.c

index 1f791b7037e1909c2bd5e1b5065687cff30d32e0..17a83b68899a7bae48de989e0709ad4ff1587116 100644 (file)
@@ -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 
index 2bbd23c49130b368572afd5f51bd07dec6667744..cdca18072c8e04d9b69175c0fa2473460715772b 100644 (file)
@@ -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 */
index 9fb25a71ee0324075282ccb2b57f0cd29dc812f0..2d49958eb2b1ff323d8e555817672e49a0eba732 100644 (file)
@@ -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"));
index ceab1738f01f94b21d9d61f22f23d19df6a9a897..d361b97fc80002f605955934da2169a684eb0242 100644 (file)
@@ -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.