]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
Fixed broken syncing for glines and elines using idents - thanks to dotslasher for...
[user/henk/code/inspircd.git] / src / users.cpp
index 4100e3452c85d6f3d946cdfca677cfe38af3ef05..f695db7c47652d0618e0dab0b32956667138b2ae 100644 (file)
@@ -153,7 +153,7 @@ void userrec::StartDNSLookup()
        try
        {
                ServerInstance->Log(DEBUG,"Passing instance: %08x",this->ServerInstance);
-               res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), false);
+               res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), DNS_QUERY_REVERSE);
                this->ServerInstance->AddResolver(res_reverse);
        }
        catch (ModuleException& e)
@@ -162,10 +162,10 @@ void userrec::StartDNSLookup()
        }
 }
 
-UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, bool forward) :
-       Resolver(Instance, to_resolve, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE), bound_user(user)
+UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt) :
+       Resolver(Instance, to_resolve, qt), bound_user(user)
 {
-       this->fwd = forward;
+       this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA);
        this->bound_fd = user->GetFd();
 }
 
@@ -180,7 +180,12 @@ void UserResolver::OnLookupComplete(const std::string &result)
                        /* Check we didnt time out */
                        if (this->bound_user->registered != REG_ALL)
                        {
-                               bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, true);
+#ifdef IPV6
+                               const char *ip = this->bound_user->GetIPString();
+                               bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, (strstr(ip,"0::ffff:") == ip ? DNS_QUERY_A : DNS_QUERY_AAAA));
+#else
+                               bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, DNS_QUERY_A);
+#endif
                                this->ServerInstance->AddResolver(bound_user->res_forward);
                        }
                }
@@ -192,7 +197,9 @@ void UserResolver::OnLookupComplete(const std::string &result)
        else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
        {
                /* Both lookups completed */
-               if (this->bound_user->GetIPString() == result)
+               std::string result2 = "0::ffff:";
+               result2.append(result);
+               if (this->bound_user->GetIPString() == result || this->bound_user->GetIPString() == result2)
                {
                        std::string hostname = this->bound_user->stored_host;
                        if (hostname.length() < 65)
@@ -290,6 +297,7 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance)
        *password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = 0;
        server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
        reset_due = ServerInstance->Time();
+       age = ServerInstance->Time(true);
        lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
        ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
        haspassed = dns_done = false;
@@ -336,9 +344,9 @@ userrec::~userrec()
        }
 }
 
-/* XXX - minor point, other *Host functions return a char *, this one creates it. Might be nice to be consistant? */
-void userrec::MakeHost(char* nhost)
+char* userrec::MakeHost()
 {
+       static char nhost[MAXBUF];
        /* This is much faster than snprintf */
        char* t = nhost;
        for(char* n = ident; *n; n++)
@@ -347,6 +355,21 @@ void userrec::MakeHost(char* nhost)
        for(char* n = host; *n; n++)
                *t++ = *n;
        *t = 0;
+       return nhost;
+}
+
+char* userrec::MakeHostIP()
+{
+       static char ihost[MAXBUF];
+       /* This is much faster than snprintf */
+       char* t = ihost;
+       for(char* n = ident; *n; n++)
+               *t++ = *n;
+       *t++ = '@';
+       for(const char* n = this->GetIPString(); *n; n++)
+               *t++ = *n;
+       *t = 0;
+       return ihost;
 }
 
 void userrec::CloseSocket()
@@ -633,27 +656,39 @@ void userrec::FlushWriteBuf()
 {
        try
        {
-               if (this->fd == FD_MAGIC_NUMBER)
+               if ((this->fd == FD_MAGIC_NUMBER) || (*this->GetWriteError()))
                {
                        sendq = "";
                }
                if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
                {
+                       int old_sendq_length = sendq.length();
                        const char* tb = this->sendq.c_str();
                        int n_sent = write(this->fd,tb,this->sendq.length());
                        if (n_sent == -1)
                        {
-                               if (errno != EAGAIN)
+                               if (errno == EAGAIN)
+                               {
+                                       ServerInstance->Log(DEBUG,"EAGAIN, want write");
+                                       this->ServerInstance->SE->WantWrite(this);
+                               }
+                               else
                                        this->SetWriteError(strerror(errno));
                        }
                        else
                        {
+                               /*ServerInstance->Log(DEBUG,"Wrote: %d of %d: %s", n_sent, old_sendq_length, sendq.substr(0, n_sent).c_str());*/
                                // advance the queue
                                tb += n_sent;
                                this->sendq = tb;
                                // update the user's stats counters
                                this->bytes_out += n_sent;
                                this->cmds_out++;
+                               if (n_sent != old_sendq_length)
+                               {
+                                       ServerInstance->Log(DEBUG,"Not all written, want write");
+                                       this->ServerInstance->SE->WantWrite(this);
+                               }
                        }
                }
        }
@@ -1322,7 +1357,7 @@ const char* userrec::GetIPString()
                        /* IP addresses starting with a : on irc are a Bad Thing (tm) */
                        if (*buf == ':')
                        {
-                               strlcpy(&temp[1], buf, sizeof(temp));
+                               strlcpy(&temp[1], buf, sizeof(temp) - 1);
                                *temp = '0';
                                return temp;
                        }
@@ -1364,7 +1399,7 @@ const char* userrec::GetIPString(char* buf)
                        /* IP addresses starting with a : on irc are a Bad Thing (tm) */
                        if (*buf == ':')
                        {
-                               strlcpy(&temp[1], buf, sizeof(temp));
+                               strlcpy(&temp[1], buf, sizeof(temp) - 1);
                                *temp = '0';
                                strlcpy(buf, temp, sizeof(temp));
                        }
@@ -1424,6 +1459,7 @@ void userrec::Write(std::string text)
                this->AddWriteBuf(text);
        }
        ServerInstance->stats->statsSent += text.length();
+       this->ServerInstance->SE->WantWrite(this);
 }
 
 /** Write()
@@ -1887,14 +1923,15 @@ void userrec::SplitChanList(userrec* dest, const std::string &cl)
 
        try
        {
-               prefix << ":" << ServerInstance->Config->ServerName << " 319 " << this->nick << " " << dest->nick << " :";
+               prefix << this->nick << " " << dest->nick << " :";
                line = prefix.str();
+               int namelen = strlen(ServerInstance->Config->ServerName) + 6;
        
                for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
                {
                        length = (pos == std::string::npos) ? cl.length() : pos;
        
-                       if (line.length() + length - start > 510)
+                       if (line.length() + namelen + length - start > 510)
                        {
                                this->Write(line);
                                line = prefix.str();
@@ -1913,7 +1950,7 @@ void userrec::SplitChanList(userrec* dest, const std::string &cl)
        
                if (line.length())
                {
-                       this->Write(line);
+                       ServerInstance->SendWhoisLine(this, dest, 319, "%s", line.c_str());
                }
        }
 
@@ -2012,12 +2049,23 @@ void userrec::ShowRULES()
        this->WriteServ("NOTICE %s :End of %s rules.",this->nick,ServerInstance->Config->ServerName);
 }
 
-void userrec::HandleEvent(EventType et)
+void userrec::HandleEvent(EventType et, int errornum)
 {
        /* WARNING: May delete this user! */
        try
        {
-               ServerInstance->ProcessUser(this);
+               switch (et)
+               {
+                       case EVENT_READ:
+                               ServerInstance->ProcessUser(this);
+                       break;
+                       case EVENT_WRITE:
+                               this->FlushWriteBuf();
+                       break;
+                       case EVENT_ERROR:
+                               this->SetWriteError(errornum ? strerror(errornum) : "EOF from client");
+                       break;
+               }
        }
        catch (...)
        {