summaryrefslogtreecommitdiff
path: root/src/net_query.c
diff options
context:
space:
mode:
authorSimon Howard2010-12-02 21:34:51 +0000
committerSimon Howard2010-12-02 21:34:51 +0000
commit0ff67f43d6d13d9675e305abc652188ea95a88fe (patch)
tree269b2bf90025016b3b04e844e12336cd8f46a628 /src/net_query.c
parent59d2ed0f2de6b2156142c87d48b0f55fa56b2acf (diff)
downloadchocolate-doom-0ff67f43d6d13d9675e305abc652188ea95a88fe.tar.gz
chocolate-doom-0ff67f43d6d13d9675e305abc652188ea95a88fe.tar.bz2
chocolate-doom-0ff67f43d6d13d9675e305abc652188ea95a88fe.zip
Make multiple query attempts to servers before giving up. Display a
warning if the master server does not respond. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2187
Diffstat (limited to 'src/net_query.c')
-rw-r--r--src/net_query.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/src/net_query.c b/src/net_query.c
index 3dee1b00..6a934413 100644
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -36,8 +36,18 @@
#include "net_structrw.h"
#include "net_sdl.h"
+// DNS address of the Internet master server.
+
#define MASTER_SERVER_ADDRESS "master.chocolate-doom.org"
+// Time to wait for a response before declaring a timeout.
+
+#define QUERY_TIMEOUT_SECS 1
+
+// Number of query attempts to make before giving up on a server.
+
+#define QUERY_MAX_ATTEMPTS 5
+
typedef enum
{
QUERY_TARGET_SERVER, // Normal server target.
@@ -50,7 +60,7 @@ typedef enum
QUERY_TARGET_QUEUED, // Query not yet sent
QUERY_TARGET_QUERIED, // Query sent, waiting response
QUERY_TARGET_RESPONDED, // Response received
- QUERY_TARGET_TIMED_OUT
+ QUERY_TARGET_NO_RESPONSE
} query_target_state_t;
typedef struct
@@ -60,6 +70,7 @@ typedef struct
net_addr_t *addr;
net_querydata_t data;
unsigned int query_time;
+ unsigned int query_attempts;
boolean printed;
} query_target_t;
@@ -179,6 +190,7 @@ static query_target_t *GetTargetForAddr(net_addr_t *addr, boolean create)
target->type = QUERY_TARGET_SERVER;
target->state = QUERY_TARGET_QUEUED;
target->printed = false;
+ target->query_attempts = 0;
target->addr = addr;
++num_targets;
@@ -329,11 +341,19 @@ static void NET_Query_GetResponse(net_query_callback_t callback,
static void SendOneQuery(void)
{
+ unsigned int now;
unsigned int i;
+ now = I_GetTimeMS();
+
for (i = 0; i < num_targets; ++i)
{
- if (targets[i].state == QUERY_TARGET_QUEUED)
+ // Not queried yet?
+ // Or last query timed out without a response?
+
+ if (targets[i].state == QUERY_TARGET_QUEUED
+ || (targets[i].state == QUERY_TARGET_QUERIED
+ && now - targets[i].query_time > QUERY_TIMEOUT_SECS * 1000))
{
break;
}
@@ -365,6 +385,7 @@ static void SendOneQuery(void)
//printf("Queried %s\n", NET_AddrToString(targets[i].addr));
targets[i].state = QUERY_TARGET_QUERIED;
targets[i].query_time = I_GetTimeMS();
+ ++targets[i].query_attempts;
}
// Time out servers that have been queried and not responded.
@@ -378,10 +399,15 @@ static void CheckTargetTimeouts(void)
for (i = 0; i < num_targets; ++i)
{
+ // We declare a target to be "no response" when we've sent
+ // multiple query packets to it (QUERY_MAX_ATTEMPTS) and
+ // received no response to any of them.
+
if (targets[i].state == QUERY_TARGET_QUERIED
- && now - targets[i].query_time > 5000)
+ && targets[i].query_attempts >= QUERY_MAX_ATTEMPTS
+ && now - targets[i].query_time > QUERY_TIMEOUT_SECS * 1000)
{
- targets[i].state = QUERY_TARGET_TIMED_OUT;
+ targets[i].state = QUERY_TARGET_NO_RESPONSE;
}
}
}
@@ -395,7 +421,7 @@ static boolean AllTargetsDone(void)
for (i = 0; i < num_targets; ++i)
{
if (targets[i].state != QUERY_TARGET_RESPONDED
- && targets[i].state != QUERY_TARGET_TIMED_OUT)
+ && targets[i].state != QUERY_TARGET_NO_RESPONSE)
{
return false;
}
@@ -432,7 +458,7 @@ static void NET_Query_QueryLoop(net_query_callback_t callback,
// Don't thrash the CPU
- I_Sleep(100);
+ I_Sleep(50);
CheckTargetTimeouts();
}
@@ -599,6 +625,14 @@ int NET_MasterQuery(net_query_callback_t callback, void *user_data)
NET_Query_QueryLoop(callback, user_data);
+ // Check that we got a response from the master, and display
+ // a warning if we didn't.
+
+ if (target->state == QUERY_TARGET_NO_RESPONSE)
+ {
+ fprintf(stderr, "NET_MasterQuery: no response from master server.\n");
+ }
+
return GetNumResponses();
}