shithub: choc

Download patch

ref: b8656b5283c8a5beb2b397335af3ce7034d46651
parent: 945355d29ffb0e52e2bccdca8eda1e7fe4dac7ac
author: Simon Howard <fraggle@soulsphere.org>
date: Wed Jan 30 13:31:08 EST 2019

net: Send resend requests to server on deadlock.

The server already triggers resend requests if it detects a potential
deadlock has occurred, but the same scenario can occur if one of the
clients loses enough game data packets from the server. So detect this
on the client side too and trigger artificial resend requests.

Big thanks go to MadDog and Mortrixs for providing network logs of
the deadlock occurring which allowed me to figure out the cause.

--- a/src/net_client.c
+++ b/src/net_client.c
@@ -611,8 +611,10 @@
     int i;
     int resend_start, resend_end;
     unsigned int nowtime;
+    boolean maybe_deadlocked;
 
     nowtime = I_GetTimeMS();
+    maybe_deadlocked = nowtime - gamedata_recv_time > 1000;
 
     resend_start = -1;
     resend_end = -1;
@@ -631,15 +633,26 @@
                    && recvobj->resend_time != 0
                    && nowtime > recvobj->resend_time + 300;
 
+        // if no game data has been received in a long time, we may be in
+        // a deadlock scenario where tics from the server have been lost, so
+        // we've stopped generating any more, so the server isn't sending us
+        // any, so we don't get any to trigger a resend request. So force the
+        // first few tics in the receive window to be requested.
+        if (i == 0 && !recvobj->active && recvobj->resend_time == 0
+         && maybe_deadlocked)
+        {
+            need_resend = true;
+        }
+
         if (need_resend)
         {
             // Start a new run of resend tics?
- 
+
             if (resend_start < 0)
             {
                 resend_start = i;
             }
-            
+
             resend_end = i;
         }
         else if (resend_start >= 0)