diff options
author | Andrey Nazarov <skuller@skuller.net> | 2008-10-30 17:12:38 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2008-10-30 17:12:38 +0000 |
commit | d65e02496cd9873f5bb0297661b19762b44ddfec (patch) | |
tree | 3efd54fd5e823ed2f56b374c5ee3f2ecd65592e5 /source/cl_main.c | |
parent | d95e79eb44efe2cd2e021527abbbf31933432375 (diff) |
Added ICMP error queue support on Linux.
Client no longer drops connection immediately after an ICMP error
is received, but waits some time for valid packets from server.
Fixed FreeBSD build.
Diffstat (limited to 'source/cl_main.c')
-rw-r--r-- | source/cl_main.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/source/cl_main.c b/source/cl_main.c index e3a5aa3..ab10ac7 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -614,6 +614,7 @@ void CL_Disconnect( comErrorType_t type, const char *text ) { cls.connect_time = 0; cls.connect_count = 0; cls.passive = qfalse; + cls.errorReceived = qfalse; // stop demo if( cls.demo.recording ) { @@ -1420,10 +1421,30 @@ CL_PacketEvent ================= */ static void CL_PacketEvent( neterr_t ret ) { + if( ret == NET_ERROR ) { + // + // error packet from server + // + if( cls.state < ca_connected ) { + return; + } + if( !cls.netchan ) { + return; // dump it if not connected + } + if( !NET_IsEqualBaseAdr( &net_from, &cls.netchan->remote_address ) ) { + return; + } + if( net_from.port && net_from.port != cls.netchan->remote_address.port ) { + return; + } + cls.errorReceived = qtrue; // drop connection soon + return; + } + // // remote command packet // - if ( ret == NET_OK && *( int * )msg_read.data == -1 ) { + if( *( int * )msg_read.data == -1 ) { CL_ConnectionlessPacket(); return; } @@ -1432,11 +1453,11 @@ static void CL_PacketEvent( neterr_t ret ) { return; } - if ( !cls.netchan ) { + if( !cls.netchan ) { return; // dump it if not connected } - if ( ret == NET_OK && msg_read.cursize < 8 ) { + if( msg_read.cursize < 8 ) { Com_DPrintf( "%s: runt packet\n", NET_AdrToString( &net_from ) ); return; } @@ -1444,19 +1465,16 @@ static void CL_PacketEvent( neterr_t ret ) { // // packet from server // - if ( !NET_IsEqualAdr( &net_from, &cls.netchan->remote_address ) ) { + if( !NET_IsEqualAdr( &net_from, &cls.netchan->remote_address ) ) { Com_DPrintf( "%s: sequenced packet without connection\n", NET_AdrToString( &net_from ) ); return; } - if( ret == NET_ERROR ) { - Com_Error( ERR_DISCONNECT, "Connection reset by peer" ); - } - - if ( !cls.netchan->Process( cls.netchan ) ) + if( !cls.netchan->Process( cls.netchan ) ) return; // wasn't accepted for some reason + cls.errorReceived = qfalse; // don't drop CL_ParseServerMessage(); @@ -2627,11 +2645,20 @@ static void CL_CheckForReply( void ) { #endif static void CL_CheckTimeout( void ) { - unsigned delta = cl_timeout->value * 1000; + unsigned delta; if( NET_IsLocalAddress( &cls.netchan->remote_address ) ) { return; } + + if( cls.errorReceived ) { + delta = 5000; + if( com_localTime - cls.netchan->last_received > delta ) { + Com_Error( ERR_DISCONNECT, "Server connection was reset." ); + } + } + + delta = cl_timeout->value * 1000; if( com_localTime - cls.netchan->last_received > delta ) { // timeoutcount saves debugger if ( ++cl.timeoutcount > 5 ) { |