Multithreaded DNS -- not tested!!!!

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@2088 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
brain 2005-12-01 23:59:40 +00:00
parent 0ae2cb132b
commit d56e60139a
7 changed files with 114 additions and 6 deletions

View File

@ -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.
*/

View File

@ -124,3 +124,4 @@ const char* FindServerNamePtr(std::string servername);
std::string GetVersionString();
void* dns_task(void* arg);

View File

@ -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

View File

@ -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)
{

View File

@ -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 "";
}
}

View File

@ -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 */

View File

@ -60,6 +60,11 @@ userrec::userrec()
invites.clear();
}
userrec::~userrec()
{
pthread_kill(this->dnsthread,9);
}
void userrec::CloseSocket()
{
shutdown(this->fd,2);