]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_ident.cpp
Converted more stuff to 'Implements' system
[user/henk/code/inspircd.git] / src / modules / m_ident.cpp
index 68934ae68d9cbf5f0d84168a33a7306e2f219c77..c55c514998c5f3f1fd1c3ba467303f832a0ec212 100644 (file)
@@ -14,6 +14,8 @@
  * ---------------------------------------------------
  */
 
+using namespace std;
+
 #include <stdio.h>
 #include <string>
 #include <stdlib.h>
@@ -54,21 +56,34 @@ Server *Srv;
 class RFC1413
 {
  protected:
-       int fd;                 // file descriptor
-       userrec* u;             // user record that the lookup is associated with
-       sockaddr_in addr;       // address we're connecting to
-       in_addr addy;           // binary ip address
-       int state;              // state (this class operates on a state engine)
-       char ibuf[MAXBUF];      // input buffer
-       sockaddr_in sock_us;    // our port number
-       sockaddr_in sock_them;  // their port number
-       socklen_t uslen;        // length of our port number
-       socklen_t themlen;      // length of their port number
-       int nrecv;              // how many bytes we've received
-       time_t timeout_end;     // how long until the operation times out
-       bool timeout;           // true if we've timed out and should bail
+       int fd;                  // file descriptor
+       userrec* u;              // user record that the lookup is associated with
+       sockaddr_in addr;        // address we're connecting to
+       in_addr addy;            // binary ip address
+       int state;               // state (this class operates on a state engine)
+       char ibuf[MAXBUF];       // input buffer
+       sockaddr_in sock_us;     // our port number
+       sockaddr_in sock_them;   // their port number
+       socklen_t uslen;         // length of our port number
+       socklen_t themlen;       // length of their port number
+       int nrecv;               // how many bytes we've received
+       time_t timeout_end;      // how long until the operation times out
+       bool timeout;            // true if we've timed out and should bail
+       char ident_request[128]; // buffer used to make up the request string
  public:
 
+       // The destructor makes damn sure the socket is freed :)
+
+       ~RFC1413()
+       {
+               if (this->fd != -1)
+               {
+                       shutdown(this->fd,2);
+                       close(this->fd);
+                       this->fd = -1;
+               }
+       }
+
        // establish an ident connection, maxtime is the time to spend trying
        // returns true if successful, false if something was catastrophically wrong.
        // note that failed connects are not reported here but detected in RFC1413::Poll()
@@ -100,6 +115,9 @@ class RFC1413
                        {
                                // ... so that error isnt fatal, like the rest.
                                Srv->Log(DEBUG,"Ident: connect failed for: "+std::string(user->ip));
+                               shutdown(this->fd,2);
+                                close(this->fd);
+                               this->fd = -1;
                                return false;
                        }
                 }
@@ -118,6 +136,9 @@ class RFC1413
                {
                        timeout = true;
                        Srv->SendServ(u->fd,"NOTICE "+std::string(u->nick)+" :*** Could not find your ident, using "+std::string(u->ident)+" instead.");
+                       shutdown(this->fd,2);
+                       close(this->fd);
+                       this->fd = -1;
                        return false;
                }
                pollfd polls;
@@ -141,24 +162,26 @@ class RFC1413
                        switch (this->state)
                        {
                                case IDENT_STATE_CONNECT:
-                                       Srv->Log(DEBUG,"*** IDENT IN STATE 1");
                                        uslen = sizeof(sock_us);
                                        themlen = sizeof(sock_them);
                                        if ((getsockname(this->u->fd,(sockaddr*)&sock_us,&uslen) || getpeername(this->u->fd, (sockaddr*)&sock_them, &themlen)))
                                        {
                                                Srv->Log(DEBUG,"Ident: failed to get socket names, bailing to state 3");
+                                               shutdown(this->fd,2);
+                                                close(this->fd);
+                                               this->fd = -1;
                                                state = IDENT_STATE_DONE;
                                        }
                                        else
                                        {
                                                // send the request in the following format: theirsocket,oursocket
-                                               Write(this->fd,"%d,%d",ntohs(sock_them.sin_port),ntohs(sock_us.sin_port));
+                                               snprintf(ident_request,127,"%d,%d\r\n",ntohs(sock_them.sin_port),ntohs(sock_us.sin_port));
+                                               send(this->fd,ident_request,strlen(ident_request),0);
                                                Srv->Log(DEBUG,"Sent ident request, moving to state 2");
                                                state = IDENT_STATE_WAITDATA;
                                        }
                                break;
                                case IDENT_STATE_WAITDATA:
-                                       Srv->Log(DEBUG,"*** IDENT IN STATE 2");
                                        nrecv = recv(this->fd,ibuf,sizeof(ibuf),0);
                                        if (nrecv > 0)
                                        {
@@ -167,8 +190,9 @@ class RFC1413
                                                // 6195, 23 : ERROR : NO-USER
                                                ibuf[nrecv] = '\0';
                                                Srv->Log(DEBUG,"Received ident response: "+std::string(ibuf));
-                                               close(this->fd);
                                                shutdown(this->fd,2);
+                                               close(this->fd);
+                                               this->fd = -1;
                                                char* savept;
                                                char* section = strtok_r(ibuf,":",&savept);
                                                while (section)
@@ -203,6 +227,9 @@ class RFC1413
                                        }
                                break;
                                case IDENT_STATE_DONE:
+                                       shutdown(this->fd,2);
+                                       close(this->fd);
+                                       this->fd = -1;
                                        Srv->Log(DEBUG,"Ident lookup is complete!");
                                break;
                                default:
@@ -210,6 +237,7 @@ class RFC1413
                                break;
                        }
                }
+               return true;
        }
 
        // returns true if the operation is completed,
@@ -217,7 +245,7 @@ class RFC1413
 
        bool Done()
        {
-               return ((state == 3) || (timeout == true));
+               return ((state == IDENT_STATE_DONE) || (timeout == true));
        }
 };
 
@@ -235,13 +263,14 @@ class ModuleIdent : public Module
                delete Conf;
        }
 
-       ModuleIdent()
+       ModuleIdent(Server* Me)
+               : Module::Module(Me)
        {
-               Srv = new Server;
+               Srv = Me;
                ReadSettings();
        }
 
-       virtual void OnRehash()
+       virtual void OnRehash(std::string parameter)
        {
                ReadSettings();
        }
@@ -291,10 +320,21 @@ class ModuleIdent : public Module
                }
                return true;
        }
+
+        virtual void OnUserDisconnect(userrec* user)
+        {
+                // when the user quits tidy up any ident lookup they have pending to keep things tidy
+                // and to prevent a memory and FD leaks
+               RFC1413* ident = (RFC1413*)user->GetExt("ident_data");
+                if (ident)
+                {
+                        delete ident;
+                        user->Shrink("ident_data");
+                }
+        }
        
        virtual ~ModuleIdent()
        {
-               delete Srv;
        }
        
        virtual Version GetVersion()
@@ -315,9 +355,9 @@ class ModuleIdentFactory : public ModuleFactory
        {
        }
        
-       virtual Module * CreateModule()
+       virtual Module * CreateModule(Server* Me)
        {
-               return new ModuleIdent;
+               return new ModuleIdent(Me);
        }
        
 };