From 15cbdfb7b0cd3db3bdfd7f84ced54e785b2a3186 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 8 Jan 2006 02:53:05 +0000 Subject: 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 --- src/net_common.c | 83 +++++++++++++++++++++++++++++++++++++++++++++----------- src/net_common.h | 9 +++++- src/net_defs.h | 7 ++++- src/net_server.c | 8 ++++-- 4 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/net_common.c b/src/net_common.c index 27d82965..8af6b8d6 100644 --- 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 @@ void NET_Conn_InitServer(net_connection_t *conn, net_addr_t *addr) 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 @@ static void NET_Conn_ParseACK(net_connection_t *conn, net_packet_t *packet) 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 @@ static void NET_Conn_ParseDisconnect(net_connection_t *conn, net_packet_t *packe 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 @@ static void NET_Conn_ParseDisconnectACK(net_connection_t *conn, 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 @@ boolean NET_Conn_Packet(net_connection_t *conn, net_packet_t *packet, 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_Disconnect(net_connection_t *conn) 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 @@ void NET_Conn_Run(net_connection_t *conn) 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 @@ void NET_Conn_Run(net_connection_t *conn) 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 @@ void NET_Conn_Run(net_connection_t *conn) 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 @@ void NET_Conn_Run(net_connection_t *conn) // 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 @@ void NET_Conn_Run(net_connection_t *conn) 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 @@ void NET_Conn_Run(net_connection_t *conn) // 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 diff --git a/src/net_common.h b/src/net_common.h index f24c6cec..530a0e0d 100644 --- 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 @@ typedef struct 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, diff --git a/src/net_defs.h b/src/net_defs.h index d01fa576..cc5658bf 100644 --- 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 @@ typedef enum { 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, diff --git a/src/net_server.c b/src/net_server.c index 82427b0b..c05a3847 100644 --- 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 @@ static void NET_SV_SendWaitingData(net_client_t *client) // send packet to client and free - NET_SendPacket(client->addr, packet); + NET_Conn_SendPacket(client, packet); NET_FreePacket(packet); } -- cgit v1.2.3