summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dns.cpp51
1 files changed, 24 insertions, 27 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index 947635571..025f4979c 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -35,6 +35,7 @@ using namespace std;
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <map>
#include "dns.h"
#include "inspircd.h"
#include "helperfuncs.h"
@@ -63,7 +64,6 @@ static int lastcreate = -1;
class s_connection
{
public:
- struct s_connection *next; /* next in list */
unsigned char id[2];
unsigned int _class;
unsigned int type;
@@ -80,7 +80,9 @@ class s_rr_middle
unsigned int rdlength;
};
-static s_connection *connection_head = NULL; /* linked list of open DNS queries; populated by dns_add_query(), decimated by dns_getresult_s() */
+typedef std::map<int,s_connection*> connlist;
+typedef connlist::iterator connlist_iter;
+connlist connections;
class s_header
{
@@ -227,13 +229,13 @@ static int dns_send_requests(const s_header *h, const s_connection *s, const int
}
static s_connection *dns_add_query(s_header *h) { /* build DNS query, add to list */
- s_connection * s;
- s = new s_connection;
+ s_connection * s = new s_connection;
+ int id = rand() % 65536;
/* set header flags */
- h->id[0] = s->id[0] = rand() % 255; /* verified by dns_getresult_s() */
- h->id[1] = s->id[1] = rand() % 255;
+ h->id[0] = s->id[0] = id >> 8; /* verified by dns_getresult_s() */
+ h->id[1] = s->id[1] = id & 0xFF;
h->flags1 = 0 | FLAGS1_MASK_RD;
h->flags2 = 0;
h->qdcount = 1;
@@ -270,8 +272,8 @@ static s_connection *dns_add_query(s_header *h) { /* build DNS query, add to lis
return NULL;
}
/* create new connection object, add to linked list */
- s->next = connection_head;
- connection_head = s;
+ if (connections.find(s->fd) == connections.end())
+ connections[s->fd] = s;
if (wantclose == 1) {
shutdown(lastcreate,2);
@@ -427,34 +429,29 @@ char* DNS::dns_getresult(const int cfd) { /* retrieve result of DNS query */
char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS query (buffered) */
s_header h;
- s_connection *c, *prev;
- int l,i,q,curanswer,o;
+ s_connection *c;
+ int l, i, q, curanswer, o;
s_rr_middle rr;
unsigned char buffer[sizeof(s_header)];
unsigned short p;
if (res)
- {
- res[0] = 0;
- }
+ *res = 0;
- prev = NULL;
- c = connection_head;
- while (c != NULL) { /* find query in list of open queries */
- if (c->fd == cfd)
- break;
- prev = c;
- c = c->next;
- }
- if (c == NULL) {
+ /* FireDNS used a linked list for this. How ugly (and slow). */
+ connlist_iter n_iter = connections.find(cfd);
+ if (n_iter == connections.end())
+ {
log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d",cfd);
- return NULL; /* query not found */
+ return NULL;
}
- /* query found-- pull from list: */
- if (prev != NULL)
- prev->next = c->next;
else
- connection_head = c->next;
+ {
+ /* Remove the query from the list */
+ c = (s_connection*)n_iter->second;
+ /* We don't delete c here, because its done later when needed */
+ connections.erase(n_iter);
+ }
l = recv(c->fd,buffer,sizeof(s_header),0);
dns_close(c->fd);