shithub: choc

Download patch

ref: 15cbdfb7b0cd3db3bdfd7f84ced54e785b2a3186
parent: e15ddb2d293570992ca8b486f4b6233a648105a1
author: Simon Howard <[email protected]>
date: Sat Jan 7 21:53:05 EST 2006

Send keepalives if the connection is not doing anything else.
Send all packets using a new NET_Conn_SendPacket to support this.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 264

--- a/src/net_common.c
+++ b/src/net_common.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: net_common.c 263 2006-01-08 00:10:48Z fraggle $
+// $Id: net_common.c 264 2006-01-08 02:53:05Z fraggle $
 //
 // Copyright(C) 2005 Simon Howard
 //
@@ -21,6 +21,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.2  2006/01/08 02:53:05  fraggle
+// Send keepalives if the connection is not doing anything else.
+// Send all packets using a new NET_Conn_SendPacket to support this.
+//
 // Revision 1.1  2006/01/08 00:10:48  fraggle
 // Move common connection code into net_common.c, shared by server
 // and client code.
@@ -36,6 +40,14 @@
 #include "net_io.h"
 #include "net_packet.h"
 
+// connections time out after 10 seconds
+
+#define CONNECTION_TIMEOUT_LEN 10
+
+// maximum time between sending packets
+
+#define KEEPALIVE_PERIOD 1
+
 // Initialise as a client connection
 
 void NET_Conn_InitClient(net_connection_t *conn, net_addr_t *addr)
@@ -56,6 +68,16 @@
     conn->addr = addr;
 }
 
+// Send a packet to a connection
+// All packets should be sent through this interface, as it maintains the
+// keepalive_send_time counter.
+
+void NET_Conn_SendPacket(net_connection_t *conn, net_packet_t *packet)
+{
+    conn->keepalive_send_time = I_GetTimeMS();
+    NET_SendPacket(conn->addr, packet);
+}
+
 // parse an ACK packet from a client
 
 static void NET_Conn_ParseACK(net_connection_t *conn, net_packet_t *packet)
@@ -74,7 +96,7 @@
 
         reply = NET_NewPacket(10);
         NET_WriteInt16(reply, NET_PACKET_TYPE_ACK);
-        NET_SendPacket(conn->addr, reply);
+        NET_Conn_SendPacket(conn, reply);
         NET_FreePacket(reply);
     }
     
@@ -97,7 +119,7 @@
     
     reply = NET_NewPacket(10);
     NET_WriteInt16(reply, NET_PACKET_TYPE_DISCONNECT_ACK);
-    NET_SendPacket(conn->addr, reply);
+    NET_Conn_SendPacket(conn, reply);
     NET_FreePacket(reply);
 
     conn->last_send_time = I_GetTimeMS();
@@ -128,8 +150,8 @@
 boolean NET_Conn_Packet(net_connection_t *conn, net_packet_t *packet, 
                         int packet_type)
 {
-    //printf("Conn: %s: %i\n", NET_AddrToString(addr), packet_type);
-
+    conn->keepalive_recv_time = I_GetTimeMS();
+    
     switch (packet_type)
     {
         case NET_PACKET_TYPE_ACK:
@@ -141,6 +163,9 @@
         case NET_PACKET_TYPE_DISCONNECT_ACK:
             NET_Conn_ParseDisconnectACK(conn, packet);
             break;
+        case NET_PACKET_TYPE_KEEPALIVE:
+            // No special action needed.
+            break;
         default:
             // Not a common packet
 
@@ -167,11 +192,37 @@
 void NET_Conn_Run(net_connection_t *conn)
 {
     net_packet_t *packet;
+    unsigned int nowtime;
 
-    if (conn->state == NET_CONN_STATE_CONNECTING)
+    nowtime = I_GetTimeMS();
+
+    if (conn->state == NET_CONN_STATE_CONNECTED)
     {
+        // Check the keepalive counters
+
+        if (nowtime - conn->keepalive_recv_time > CONNECTION_TIMEOUT_LEN * 1000)
+        {
+            // Haven't received any packets from the other end in a long
+            // time.  Assume disconnected.
+
+            conn->state = NET_CONN_STATE_DISCONNECTED;
+        }
+        
+        if (nowtime - conn->keepalive_send_time > KEEPALIVE_PERIOD * 1000)
+        {
+            // We have not sent anything in a long time.
+            // Send a keepalive.
+
+            packet = NET_NewPacket(10);
+            NET_WriteInt16(packet, NET_PACKET_TYPE_KEEPALIVE);
+            NET_Conn_SendPacket(conn, packet);
+            NET_FreePacket(packet);
+        }
+    }
+    else if (conn->state == NET_CONN_STATE_CONNECTING)
+    {
         if (conn->last_send_time < 0
-         || I_GetTimeMS() - conn->last_send_time > 1000)
+         || nowtime - conn->last_send_time > 1000)
         {
             // It has been a second since the last SYN was sent, and no
             // reply.
@@ -183,9 +234,9 @@
                 packet = NET_NewPacket(10);
                 NET_WriteInt16(packet, NET_PACKET_TYPE_SYN);
                 NET_WriteInt32(packet, NET_MAGIC_NUMBER);
-                NET_SendPacket(conn->addr, packet);
+                NET_Conn_SendPacket(conn, packet);
                 NET_FreePacket(packet);
-                conn->last_send_time = I_GetTimeMS();
+                conn->last_send_time = nowtime;
 
                 ++conn->num_retries;
             }
@@ -198,7 +249,7 @@
     else if (conn->state == NET_CONN_STATE_WAITING_ACK)
     {
         if (conn->last_send_time < 0
-         || I_GetTimeMS() - conn->last_send_time > 1000)
+         || nowtime - conn->last_send_time > 1000)
         {
             // it has been a second since the last ACK was sent, and 
             // still no reply.
@@ -209,9 +260,9 @@
 
                 packet = NET_NewPacket(10);
                 NET_WriteInt16(packet, NET_PACKET_TYPE_ACK);
-                NET_SendPacket(conn->addr, packet);
+                NET_Conn_SendPacket(conn, packet);
                 NET_FreePacket(packet);
-                conn->last_send_time = I_GetTimeMS();
+                conn->last_send_time = nowtime;
 
                 ++conn->num_retries;
             }
@@ -228,7 +279,7 @@
         // Waiting for a reply to our DISCONNECT request.
 
         if (conn->last_send_time < 0
-         || I_GetTimeMS() - conn->last_send_time > 1000)
+         || nowtime - conn->last_send_time > 1000)
         {
             // it has been a second since the last disconnect packet 
             // was sent, and still no reply.
@@ -239,9 +290,9 @@
 
                 packet = NET_NewPacket(10);
                 NET_WriteInt16(packet, NET_PACKET_TYPE_DISCONNECT);
-                NET_SendPacket(conn->addr, packet);
+                NET_Conn_SendPacket(conn, packet);
                 NET_FreePacket(packet);
-                conn->last_send_time = I_GetTimeMS();
+                conn->last_send_time = nowtime;
 
                 ++conn->num_retries;
             }
@@ -259,7 +310,7 @@
         // We are disconnected, waiting in case we need to send
         // a DISCONNECT_ACK to the server again.
 
-        if (I_GetTimeMS() - conn->last_send_time > 5000)
+        if (nowtime - conn->last_send_time > 5000)
         {
             // Idle for 5 seconds, switch state
 
--- a/src/net_common.h
+++ b/src/net_common.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: net_common.h 263 2006-01-08 00:10:48Z fraggle $
+// $Id: net_common.h 264 2006-01-08 02:53:05Z fraggle $
 //
 // Copyright(C) 2005 Simon Howard
 //
@@ -21,6 +21,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.2  2006/01/08 02:53:05  fraggle
+// Send keepalives if the connection is not doing anything else.
+// Send all packets using a new NET_Conn_SendPacket to support this.
+//
 // Revision 1.1  2006/01/08 00:10:48  fraggle
 // Move common connection code into net_common.c, shared by server
 // and client code.
@@ -76,9 +80,12 @@
     net_addr_t *addr;
     int last_send_time;
     int num_retries;
+    int keepalive_send_time;
+    int keepalive_recv_time;
 } net_connection_t;
 
 
+void NET_Conn_SendPacket(net_connection_t *conn, net_packet_t *packet);
 void NET_Conn_InitClient(net_connection_t *conn, net_addr_t *addr);
 void NET_Conn_InitServer(net_connection_t *conn, net_addr_t *addr);
 boolean NET_Conn_Packet(net_connection_t *conn, net_packet_t *packet,
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: net_defs.h 238 2006-01-01 23:54:31Z fraggle $
+// $Id: net_defs.h 264 2006-01-08 02:53:05Z fraggle $
 //
 // Copyright(C) 2005 Simon Howard
 //
@@ -21,6 +21,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.5  2006/01/08 02:53:05  fraggle
+// Send keepalives if the connection is not doing anything else.
+// Send all packets using a new NET_Conn_SendPacket to support this.
+//
 // Revision 1.4  2006/01/01 23:54:31  fraggle
 // Client disconnect code
 //
@@ -111,6 +115,7 @@
 {
     NET_PACKET_TYPE_SYN,
     NET_PACKET_TYPE_ACK,
+    NET_PACKET_TYPE_KEEPALIVE,
     NET_PACKET_TYPE_WAITING_DATA,
     NET_PACKET_TYPE_GAMESTART,
     NET_PACKET_TYPE_GAMEDATA,
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: net_server.c 263 2006-01-08 00:10:48Z fraggle $
+// $Id: net_server.c 264 2006-01-08 02:53:05Z fraggle $
 //
 // Copyright(C) 2005 Simon Howard
 //
@@ -21,6 +21,10 @@
 // 02111-1307, USA.
 //
 // $Log$
+// Revision 1.13  2006/01/08 02:53:05  fraggle
+// Send keepalives if the connection is not doing anything else.
+// Send all packets using a new NET_Conn_SendPacket to support this.
+//
 // Revision 1.12  2006/01/08 00:10:48  fraggle
 // Move common connection code into net_common.c, shared by server
 // and client code.
@@ -353,7 +357,7 @@
     
     // send packet to client and free
 
-    NET_SendPacket(client->addr, packet);
+    NET_Conn_SendPacket(client, packet);
     NET_FreePacket(packet);
 }