From 5772ed20c13d65ac46e4ba60d153287a8a631ec5 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Sun, 11 Aug 2024 23:46:50 +1000 Subject: [PATCH] net_slist: improve warnings and debug messages Detects out-of-order packets in dpmaster replies. Hides IPv6 master timeouts by default. Adds more info to some messages. Uses consistent VM warnings for all the QC builtins. Also some nitpicking. Signed-off-by: bones_was_here --- mvm_cmds.c | 30 +++++++++++++---------- netconn.c | 72 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/mvm_cmds.c b/mvm_cmds.c index 812930fd..f04ac294 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -279,7 +279,7 @@ static void VM_M_getserverliststat(prvm_prog_t *prog) PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortflags; return; default: - VM_Warning(prog, "VM_M_getserverliststat: bad type %i!\n", type ); + VM_Warning(prog, "VM_M_getserverliststat: bad type (%i) passed!\n", type); } } @@ -323,13 +323,14 @@ static void VM_M_setserverlistmaskstring(prvm_prog_t *prog) mask = &serverlist_ormasks[masknr - 512 ]; else { - VM_Warning(prog, "VM_M_setserverlistmaskstring: invalid mask number %i\n", masknr ); + VM_Warning(prog, "VM_M_setserverlistmaskstring: invalid mask number (%i) passed!\n", masknr); return; } field = (int) PRVM_G_FLOAT( OFS_PARM1 ); - switch( field ) { + switch( field ) + { case SLIF_CNAME: mask->info.cname_len = dp_strlcpy(mask->info.cname, str, sizeof(mask->info.cname)); break; @@ -352,7 +353,7 @@ static void VM_M_setserverlistmaskstring(prvm_prog_t *prog) mask->info.game_len = dp_strlcpy(mask->info.game, str, sizeof(mask->info.game)); break; default: - VM_Warning(prog, "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field ); + VM_Warning(prog, "VM_M_setserverlistmaskstring: Bad field number (%i) passed!\n", field); return; } @@ -385,14 +386,15 @@ static void VM_M_setserverlistmasknumber(prvm_prog_t *prog) mask = &serverlist_ormasks[masknr - 512 ]; else { - VM_Warning(prog, "VM_M_setserverlistmasknumber: invalid mask number %i\n", masknr ); + VM_Warning(prog, "VM_M_setserverlistmasknumber: invalid mask number (%i) passed!\n", masknr); return; } number = (int)PRVM_G_FLOAT( OFS_PARM2 ); field = (int) PRVM_G_FLOAT( OFS_PARM1 ); - switch( field ) { + switch( field ) + { case SLIF_MAXPLAYERS: mask->info.maxplayers = number; break; @@ -421,7 +423,7 @@ static void VM_M_setserverlistmasknumber(prvm_prog_t *prog) mask->info.isfavorite = number != 0; break; default: - VM_Warning(prog, "VM_M_setserverlistmasknumber: Bad field number %i passed!\n", field ); + VM_Warning(prog, "VM_M_setserverlistmasknumber: Bad field number (%i) passed!\n", field); return; } @@ -469,12 +471,13 @@ static void VM_M_getserverliststring(prvm_prog_t *prog) { if(hostnr < 0 || (unsigned)hostnr >= serverlist_viewcount) { - Con_Print("VM_M_getserverliststring: bad hostnr passed!\n"); + VM_Warning(prog, "VM_M_getserverliststring: bad hostnr (%i) passed!\n", hostnr); return; } cache = ServerList_GetViewEntry(hostnr); } - switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) { + switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) + { case SLIF_CNAME: PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.cname, cache->info.cname_len); break; @@ -504,7 +507,7 @@ static void VM_M_getserverliststring(prvm_prog_t *prog) PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->line2, cache->line2_len); break; default: - Con_Print("VM_M_getserverliststring: bad field number passed!\n"); + VM_Warning(prog, "VM_M_getserverliststring: bad field number (%i) passed!\n", (int)PRVM_G_FLOAT(OFS_PARM0)); } } @@ -534,12 +537,13 @@ static void VM_M_getserverlistnumber(prvm_prog_t *prog) { if(hostnr < 0 || (unsigned)hostnr >= serverlist_viewcount) { - Con_Print("VM_M_getserverliststring: bad hostnr passed!\n"); + VM_Warning(prog, "VM_M_getserverliststring: bad hostnr (%i) passed!\n", hostnr); return; } cache = ServerList_GetViewEntry(hostnr); } - switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) { + switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) + { case SLIF_MAXPLAYERS: PRVM_G_FLOAT( OFS_RETURN ) = cache->info.maxplayers; break; @@ -569,7 +573,7 @@ static void VM_M_getserverlistnumber(prvm_prog_t *prog) PRVM_G_FLOAT( OFS_RETURN ) = cache->info.isfavorite; break; default: - Con_Print("VM_M_getserverlistnumber: bad field number passed!\n"); + VM_Warning(prog, "VM_M_getserverlistnumber: bad field number (%i) passed!\n", (int)PRVM_G_FLOAT(OFS_PARM0)); } } diff --git a/netconn.c b/netconn.c index 4ff6a576..61b8df8c 100644 --- a/netconn.c +++ b/netconn.c @@ -131,9 +131,9 @@ uint8_t serverlist_querystage = 0; static uint8_t dpmasterstatus[DPMASTER_COUNT] = {0}; static uint8_t qwmasterstatus[QWMASTER_COUNT] = {0}; -#define MASTER_TX_QUERY 1 // we sent the query -#define MASTER_RX_RESPONSE 2 // we got at least 1 packet of the response -#define MASTER_RX_COMPLETE 3 // we saw the EOT marker (assumes dpmaster >= 2.0, see dpmaster/doc/techinfo.txt) +#define MASTER_TX_QUERY 1 ///< we sent the query +#define MASTER_RX_RESPONSE 2 ///< we got at least 1 packet of the response +#define MASTER_RX_COMPLETE 3 ///< we saw the EOT marker (assumes dpmaster >= 2.0, see dpmaster/doc/techinfo.txt) /// the hash password for timestamp verification char serverlist_dpserverquerykey[12]; // challenge_t uses [12] @@ -1710,10 +1710,10 @@ static int NetConn_ClientParsePacket_ServerList_ProcessReply(const char *address if (n == serverlist_cachecount) { if (net_slist_debug.integer) - Con_Printf("^6Received LAN broadcast response from %s\n", addressstring); + Con_Printf("^6Received reply from unlisted %sserver %s\n", challenge ? "DarkPlaces " : "", addressstring); // find a slot - if (serverlist_cachecount == SERVERLIST_TOTALSIZE) + if (serverlist_cachecount >= SERVERLIST_TOTALSIZE) return -1; if (serverlist_maxcachecount <= serverlist_cachecount) @@ -1822,7 +1822,7 @@ static qbool NetConn_ClientParsePacket_ServerList_PrepareQuery(int protocol, con serverlist_entry_t *entry; // ignore the rest of the message if the serverlist is full - if (serverlist_cachecount == SERVERLIST_TOTALSIZE) + if (serverlist_cachecount >= SERVERLIST_TOTALSIZE) return false; for (n = 0; n < serverlist_cachecount; ++n) @@ -1863,14 +1863,21 @@ static void NetConn_ClientParsePacket_ServerList_ParseDPList(lhnetaddress_t *mas break; if (net_sourceaddresscheck.integer && masternum >= DPMASTER_COUNT) { - Con_Printf(CON_WARN "ignoring DarkPlaces %sserver list from unrecognised master %s\n", isextended ? "extended " : "", masteraddressstring); + Con_Printf(CON_WARN "ignoring DarkPlaces %sserver list from unrecognised master %s\n", + isextended ? "extended " : "", masteraddressstring); return; } masterreplycount++; - dpmasterstatus[masternum] = MASTER_RX_RESPONSE; - if (serverlist_consoleoutput || net_slist_debug.integer) - Con_Printf("^5Received DarkPlaces server list %sfrom %s\n", isextended ? "(extended) " : "", sv_masters[masternum].string); + if (dpmasterstatus[masternum] < MASTER_RX_RESPONSE) // Don't reduce status if it's already COMPLETE + dpmasterstatus[masternum] = MASTER_RX_RESPONSE; // which happens when packets are out of order. + + if (dpmasterstatus[masternum] == MASTER_RX_COMPLETE) + Con_Printf(CON_WARN "Received out of order DarkPlaces server list %sfrom %s\n", + isextended ? "(extended) " : "", sv_masters[masternum].string); + else if (serverlist_consoleoutput || net_slist_debug.integer) + Con_Printf("^5Received DarkPlaces server list %sfrom %s\n", + isextended ? "(extended) " : "", sv_masters[masternum].string); while (length >= 7) { @@ -2516,16 +2523,32 @@ void NetConn_QueryQueueFrame(void) // to avoid messing up the ping times on the servers if (serverlist_querystage < SLIST_QUERYSTAGE_SERVERS) { + lhnetaddress_t masteraddress; + if (currentrealtime < masterquerytime + net_slist_timeout.value) return; // Report the masters that timed out or whose response was incomplete. + // Some people have IPv6 DNS but no v6 connectivity + // so v6 master timeouts are currently silent by default. for (index = 0; index < DPMASTER_COUNT; ++index) - if (dpmasterstatus[index] && dpmasterstatus[index] < MASTER_RX_COMPLETE) - Con_Printf(CON_WARN "WARNING: dpmaster %s %s\n", sv_masters[index].string, dpmasterstatus[index] == MASTER_TX_QUERY ? "timed out" : "response incomplete"); + { + if (dpmasterstatus[index] == MASTER_TX_QUERY) + { + if (net_slist_debug.integer || + (LHNETADDRESS_FromString(&masteraddress, sv_masters[index].string, DPMASTER_PORT) + && LHNETADDRESS_GetAddressType(&masteraddress) != LHNETADDRESSTYPE_INET6)) + Con_Printf(CON_WARN "WARNING: dpmaster %s query timed out\n", sv_masters[index].string); + } + else if (dpmasterstatus[index] && dpmasterstatus[index] < MASTER_RX_COMPLETE) + Con_Printf(CON_WARN "WARNING: dpmaster %s list incomplete (packet loss)\n", sv_masters[index].string); + } + for (index = 0; index < QWMASTER_COUNT; ++index) - if (qwmasterstatus[index] && qwmasterstatus[index] < MASTER_RX_RESPONSE) // no EOT marker in QW lists - Con_Printf(CON_WARN "WARNING: qwmaster %s timed out\n", sv_qwmasters[index].string); + if (qwmasterstatus[index] && qwmasterstatus[index] < MASTER_RX_RESPONSE // no EOT marker in QW lists + && LHNETADDRESS_FromString(&masteraddress, sv_qwmasters[index].string, DPMASTER_PORT) + && LHNETADDRESS_GetAddressType(&masteraddress) != LHNETADDRESSTYPE_INET6) // some people have v6 DNS but no connectivity + Con_Printf(CON_WARN "WARNING: qwmaster %s query timed out\n", sv_qwmasters[index].string); serverlist_querystage = SLIST_QUERYSTAGE_SERVERS; } @@ -2607,15 +2630,26 @@ void NetConn_QueryQueueFrame(void) { // timeout pass begins next frame if (net_slist_debug.integer) - Con_Printf("^2Finished querying masters and servers in %f\n", currentrealtime - masterquerytime); + { + int mastersqueried = 0; + + for (index = 0; index < DPMASTER_COUNT; ++index) + if (dpmasterstatus[index]) + ++mastersqueried; + Con_Printf("^2Finished querying %i masters and %i servers in %f seconds\n", + mastersqueried, serverlist_cachecount, currentrealtime - masterquerytime); + } } else if (pass > queriesperserver) { // Nothing else to do until the next refresh cycle. - if (net_slist_debug.integer) - Con_Printf("^4Finished checking server timeouts in %f\n", currentrealtime - serverlist_cache[serverlist_cachecount - 1].querytime); serverlist_querystage = 0; pass = 0; + if (net_slist_debug.integer) + Con_Printf("^4Finished checking server timeouts in %f\n", + currentrealtime - serverlist_cache[serverlist_cachecount - 1].querytime); + if (serverlist_cachecount >= SERVERLIST_TOTALSIZE) + Con_Printf(CON_WARN "WARNING: too many servers, some will not be listed!\n"); } } #endif @@ -3850,8 +3884,8 @@ void NetConn_QueryMasters(qbool querydp, qbool queryqw) cmdname = "getservers"; extraoptions = ""; } - memcpy(request, "\377\377\377\377", 4); - dpsnprintf(request+4, sizeof(request)-4, "%s %s %u empty full%s", cmdname, gamenetworkfiltername, NET_PROTOCOL_VERSION, extraoptions); + dpsnprintf(request, sizeof(request), "\377\377\377\377%s %s %u empty full%s", + cmdname, gamenetworkfiltername, NET_PROTOCOL_VERSION, extraoptions); // search internet for (masternum = 0; masternum < DPMASTER_COUNT; ++masternum) -- 2.39.2