summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2005-12-01 23:59:40 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2005-12-01 23:59:40 +0000
commitd56e60139a8c8f9fad434917ea236e8d2b1ea5ae (patch)
treebc908a0db845e41537067a4b7e43753f67894404
parent0ae2cb132ba4a631edbc232f483f72724856f5fb (diff)
Multithreaded DNS -- not tested!!!!
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@2088 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/dns.h1
-rw-r--r--include/inspircd.h1
-rw-r--r--include/users.h7
-rw-r--r--src/commands.cpp14
-rw-r--r--src/dns.cpp32
-rw-r--r--src/inspircd.cpp60
-rw-r--r--src/users.cpp5
7 files changed, 114 insertions, 6 deletions
diff --git a/include/dns.h b/include/dns.h
index d0cb97804..6fcabee47 100644
--- a/include/dns.h
+++ b/include/dns.h
@@ -85,6 +85,7 @@ public:
* called DNS::ReverseLookup() or DNS::ForwardLookup.
*/
std::string GetResult();
+ std::string GetResultIP();
/** This method returns the file handle used by the dns query socket or zero if the
* query is invalid for some reason, e.g. the dns server not responding.
*/
diff --git a/include/inspircd.h b/include/inspircd.h
index 05a76f48e..ec5f7b26c 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -124,3 +124,4 @@ const char* FindServerNamePtr(std::string servername);
std::string GetVersionString();
+void* dns_task(void* arg);
diff --git a/include/users.h b/include/users.h
index 2329fda01..388977359 100644
--- a/include/users.h
+++ b/include/users.h
@@ -19,6 +19,7 @@
#include "inspstring.h"
#include "connection.h"
#include <string>
+#include <pthread.h>
#ifndef __USERS_H__
#define __USERS_H__
@@ -218,8 +219,6 @@ class userrec : public connection
userrec();
- virtual ~userrec() { }
-
/** Returns the full displayed host of the user
* This member function returns the hostname of the user as seen by other users
* on the server, in nick!ident&at;host form.
@@ -318,6 +317,10 @@ class userrec : public connection
/** Shuts down and closes the user's socket
*/
void CloseSocket();
+
+ virtual ~userrec();
+
+ pthread_t dnsthread;
};
/** A lightweight userrec used by WHOWAS
diff --git a/src/commands.cpp b/src/commands.cpp
index 04d54d18a..f02c4bfcc 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -50,6 +50,7 @@ using namespace std;
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <pthread.h>
#ifndef RUSAGE_SELF
#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN -1
@@ -1719,9 +1720,16 @@ void handle_nick(char **parameters, int pcnt, userrec *user)
user->registered = (user->registered | 2);
// dont attempt to look up the dns until they pick a nick... because otherwise their pointer WILL change
// and unless we're lucky we'll get a duff one later on.
- user->dns_done = (!lookup_dns(user->nick));
- if (user->dns_done)
- log(DEBUG,"Aborting dns lookup of %s because dns server experienced a failure.",user->nick);
+ //user->dns_done = (!lookup_dns(user->nick));
+ //if (user->dns_done)
+ // log(DEBUG,"Aborting dns lookup of %s because dns server experienced a failure.",user->nick);
+
+ // initialize their dns lookup thread
+ if (pthread_create(&user->dnsthread, NULL, dns_task, (void *)user) != 0)
+ {
+ log(DEBUG,"Failed to create DNS lookup thread for user %s",user->nick);
+ }
+
}
if (user->registered == 3)
{
diff --git a/src/dns.cpp b/src/dns.cpp
index bc2ca8c17..738fd0116 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -667,7 +667,13 @@ bool DNS::ReverseLookup(std::string ip)
bool DNS::ForwardLookup(std::string host)
{
- return false;
+ statsDns++;
+ this->fd = dns_getip4(host.c_str());
+ if (this->fd == -1)
+ {
+ return false;
+ }
+ return true;
}
bool DNS::HasResult()
@@ -693,6 +699,30 @@ std::string DNS::GetResult()
return result;
} else {
statsDnsBad++;
+ if (this->fd != -1)
+ {
+ dns_close(this->fd);
+ }
+ return "";
+ }
+}
+
+std::string DNS::GetResultIP()
+{
+ char r[1024];
+ result = dns_getresult(this->fd);
+ if (this->fd != -1)
+ {
+ dns_close(this->fd);
+ }
+ if (result)
+ {
+ sprintf(r,"%d.%d.%d.%d",result[0],result[1],result[2],result[3]);
+ return r;
+ }
+ else
+ {
+ log(DEBUG,"DANGER WILL ROBINSON! NXDOMAIN for forward lookup, but we got a reverse lookup!");
return "";
}
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index c3426c913..c2b5ebf9b 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -51,6 +51,7 @@ using namespace std;
#include <vector>
#include <deque>
#include <sched.h>
+#include <pthread.h>
#include "users.h"
#include "ctables.h"
#include "globals.h"
@@ -67,6 +68,7 @@ using namespace std;
#include "hashcomp.h"
#include "socketengine.h"
#include "socket.h"
+#include "dns.h"
int LogLevel = DEFAULT;
char ServerName[MAXBUF];
@@ -1180,6 +1182,15 @@ void kill_link_silent(userrec *user,const char* r)
}
+/*void *task(void *arg)
+{
+ for (;;) {
+ cout << (char *)arg;
+ cout.flush();
+ }
+ return NULL;
+}*/
+
int main(int argc, char** argv)
{
Start();
@@ -1206,6 +1217,7 @@ int main(int argc, char** argv)
}
}
}
+
strlcpy(MyExecutable,argv[0],MAXBUF);
// initialize the lowercase mapping table
@@ -1318,6 +1330,48 @@ void AddWhoWas(userrec* u)
}
}
+void* dns_task(void* arg)
+{
+ userrec* u = (userrec*)arg;
+ log(DEBUG,"DNS thread for user %s",u->nick);
+ DNS dns1;
+ DNS dns2;
+ std::string host;
+ std::string ip;
+ if (dns1.ReverseLookup(u->ip))
+ {
+ log(DEBUG,"DNS Step 1");
+ while (!dns1.HasResult())
+ {
+ usleep(100);
+ }
+ host = dns1.GetResult();
+ if (host != "")
+ {
+ log(DEBUG,"DNS Step 2: '%s'",host.c_str());
+ if (dns2.ForwardLookup(host))
+ {
+ while (!dns2.HasResult())
+ {
+ usleep(100);
+ }
+ ip = dns2.GetResultIP();
+ log(DEBUG,"DNS Step 3 '%s'(%d) '%s'(%d)",ip.c_str(),ip.length(),u->ip,strlen(u->ip));
+ if (ip == std::string(u->ip))
+ {
+ log(DEBUG,"DNS Step 4");
+ if (host.length() < 160)
+ {
+ log(DEBUG,"DNS Step 5");
+ strcpy(u->host,host.c_str());
+ }
+ }
+ }
+ }
+ }
+ u->dns_done = true;
+ return NULL;
+}
/* add a client connection to the sockets list */
void AddClient(int socket, char* host, int port, bool iscached, char* ip)
@@ -1443,6 +1497,12 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
}
fd_ref_table[socket] = clientlist[tempnick];
engine_add_fd;
+
+ // initialize their dns lookup thread
+ //if (pthread_create(&clientlist[tempnick]->dnsthread, NULL, dns_task, (void *)clientlist[tempnick]) != 0)
+ //{
+ // log(DEBUG,"Failed to create DNS lookup thread for user %s",clientlist[tempnick]->nick);
+ //}
}
/* shows the message of the day, and any other on-logon stuff */
diff --git a/src/users.cpp b/src/users.cpp
index 32c29a75d..fc286895f 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -60,6 +60,11 @@ userrec::userrec()
invites.clear();
}
+userrec::~userrec()
+{
+ pthread_kill(this->dnsthread,9);
+}
+
void userrec::CloseSocket()
{
shutdown(this->fd,2);