summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorattilamolnar <attilamolnar@hush.com>2013-03-20 23:43:51 +0100
committerattilamolnar <attilamolnar@hush.com>2013-03-20 23:43:51 +0100
commit21f7e4a8cdad2f29fda2768215c3a5352a9fa632 (patch)
tree7b7c0234cd0acaa3d4feebd8d9e0b941ce0924ba
parentfd6a8e93920553e2e6655b0f396be61a6e6b832c (diff)
Fix infinite loop when all DNS request slots are in use
This is not the best way to detect this scenario, a better detection mechanism will replace this in the future
-rw-r--r--src/dns.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index bede73a6f..63bde0ecc 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -258,8 +258,28 @@ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id, const char* original)
return NULL;
/* Create an id */
+ unsigned int tries = 0;
do {
id = ServerInstance->GenRandomInt(DNS::MAX_REQUEST_ID);
+ if (++tries == DNS::MAX_REQUEST_ID*5)
+ {
+ // If we couldn't find an empty slot this many times, do a sequential scan as a last
+ // resort. If an empty slot is found that way, go on, otherwise throw an exception
+ id = -1;
+ for (int i = 0; i < DNS::MAX_REQUEST_ID; i++)
+ {
+ if (!requests[i])
+ {
+ id = i;
+ break;
+ }
+ }
+
+ if (id == -1)
+ throw ModuleException("DNS: All ids are in use");
+
+ break;
+ }
} while (requests[id]);
DNSRequest* req = new DNSRequest(this, id, original);