Try to fix hangs caused by PT_CLIENTJOIN with a non-zero ack

This commit is contained in:
fickleheart 2019-03-30 22:48:55 -05:00
parent 9bc3acd17a
commit 0911ec79d1
1 changed files with 33 additions and 16 deletions

View File

@ -363,7 +363,11 @@ static boolean Processackpak(void)
{
UINT8 ack = netbuffer->ack;
getackpacket++;
if (cmpack(ack, node->firstacktosend) <= 0)
if (cmpack(ack, node->firstacktosend) <= 0
// UGLY PROBABLY-BAD HACK: If we get PT_CLIENTJOIN, assume this is an in-order packet?
&& netbuffer->packettype != PT_CLIENTJOIN
)
{
DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack));
duppacket++;
@ -385,6 +389,11 @@ static boolean Processackpak(void)
// Is a good packet so increment the acknowledge number,
// Then search for a "hole" in the queue
UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1);
// UGLY PROBABLY-BAD HACK: If we get PT_CLIENTJOIN, assume this is an in-order packet?
if (netbuffer->packettype == PT_CLIENTJOIN)
node->firstacktosend = (UINT8)((ack-1+MAXACKTOSEND) % MAXACKTOSEND);
if (!nextfirstack)
nextfirstack = 1;
@ -1190,6 +1199,29 @@ boolean HGetPacket(void)
if (nodejustjoined)
{
// If a new node sends an unexpected packet, just ignore it
if (server
&& !(netbuffer->packettype == PT_ASKINFO
|| netbuffer->packettype == PT_SERVERINFO
|| netbuffer->packettype == PT_PLAYERINFO
|| netbuffer->packettype == PT_REQUESTFILE
|| netbuffer->packettype == PT_ASKINFOVIAMS
|| netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}
if (netbuffer->ack > 1 && !(server && netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE("New node sent a packet with an out-of-sequence ack. Ghost connection? Ignoring...\n");
CONS_Alert(CONS_NOTICE, "New node sent a packet with an out-of-sequence ack. Ghost connection? Ignoring...\n");
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}
// Reinitialize vars for the new node just in case there's anything left over from other players.....
InitNode(&nodes[doomcom->remotenode]);
SV_AbortSendFiles(doomcom->remotenode);
@ -1222,21 +1254,6 @@ boolean HGetPacket(void)
DebugPrintpacket("GET");
#endif
// If a new node sends an unexpected packet, just ignore it
if (nodejustjoined && server
&& !(netbuffer->packettype == PT_ASKINFO
|| netbuffer->packettype == PT_SERVERINFO
|| netbuffer->packettype == PT_PLAYERINFO
|| netbuffer->packettype == PT_REQUESTFILE
|| netbuffer->packettype == PT_ASKINFOVIAMS
|| netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
//CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}
// Proceed the ack and ackreturn field
if (!Processackpak())
continue; // discarded (duplicated)