Revert "socket: use getaddrinfo"
authorlittlesat <littlesat99@yahoo.com>
Thu, 21 May 2015 22:07:18 +0000 (00:07 +0200)
committerlittlesat <littlesat99@yahoo.com>
Thu, 21 May 2015 22:07:18 +0000 (00:07 +0200)
This reverts commit d743e974b95b18c303dfebc27d253f6b323f08d9.

As it unintented seems to increase the CPU load to approx. 50%

lib/network/serversocket.cpp
lib/network/serversocket.h
lib/network/socket.cpp
lib/network/socket.h

index 14cfb2a..78aa3c9 100644 (file)
@@ -1,5 +1,4 @@
 #include <errno.h>
-#include <string.h>
 #include <lib/network/serversocket.h>
 #include <arpa/inet.h>
 
@@ -10,138 +9,82 @@ bool eServerSocket::ok()
 
 void eServerSocket::notifier(int)
 {
-       int clientfd;
-       socklen_t clientlen;
-       struct sockaddr client_addr;
-       char straddr[INET6_ADDRSTRLEN];
+       int clientfd, clientlen;
+       struct sockaddr_in client_addr;
 
 #ifdef DEBUG_SERVERSOCKET
        eDebug("[eServerSocket] incoming connection!");
 #endif
 
-       clientlen = sizeof(client_addr);
-       clientfd = accept(getDescriptor(), &client_addr, &clientlen);
-       if (clientfd < 0)
-       {
+       clientlen=sizeof(client_addr);
+       clientfd=accept(getDescriptor(),
+                       (struct sockaddr *) &client_addr,
+                       (socklen_t*)&clientlen);
+       if(clientfd<0)
                eDebug("[eServerSocket] error on accept: %m");
-               return;
-       }
 
-       if (client_addr.sa_family == AF_LOCAL)
-       {
-               strRemoteHost = "(local)";
-       }
-       else
-       {
-               strRemoteHost = inet_ntop(client_addr.sa_family, client_addr.sa_data, straddr, sizeof(straddr));
-       }
+       strRemoteHost = inet_ntoa(client_addr.sin_addr);
        newConnection(clientfd);
 }
 
 eServerSocket::eServerSocket(int port, eMainloop *ml): eSocket(ml)
 {
-       int res;
-       struct addrinfo *addr = NULL;
-       struct addrinfo hints;
-       char portnumber[16];
-
-       okflag = 0;
+       struct sockaddr_in serv_addr;
        strRemoteHost = "";
 
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = AF_UNSPEC; /* both ipv4 and ipv6 */
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_protocol = 0; /* any */
-#ifdef AI_ADDRCONFIG
-       hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_ADDRCONFIG; /* only return ipv6 if we have an ipv6 address ourselves, and ipv4 if we have an ipv4 address ourselves */
-#else
-       hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* AI_ADDRCONFIG is not available */
-#endif
-       snprintf(portnumber, sizeof(portnumber), "%d", port);
+       bzero(&serv_addr, sizeof(serv_addr));
+       serv_addr.sin_family=AF_INET;
+       serv_addr.sin_addr.s_addr=INADDR_ANY;
+       serv_addr.sin_port=htons(port);
 
-       if ((res = getaddrinfo(NULL, portnumber, &hints, &addr)) || !addr)
-       {
-               eDebug("[eServerSocket] getaddrinfo: %s", gai_strerror(res));
-               return;
-       }
+       okflag=1;
+       int val=1;
+
+       setsockopt(getDescriptor(), SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
 
-       if (startListening(addr) >= 0)
+       if(bind(getDescriptor(),
+               (struct sockaddr *) &serv_addr,
+               sizeof(serv_addr))<0)
        {
-               okflag = 1;
-               rsn->setRequested(eSocketNotifier::Read);
+               eDebug("[eServerSocket] ERROR on bind: %m");
+               okflag=0;
        }
-       freeaddrinfo(addr);
+       listen(getDescriptor(), 0);
+
+       rsn->setRequested(eSocketNotifier::Read);
 }
 
-eServerSocket::eServerSocket(std::string path, eMainloop *ml) : eSocket(ml)
+eServerSocket::eServerSocket(std::string path, eMainloop *ml) : eSocket(ml, AF_LOCAL)
 {
-       struct sockaddr_un serv_addr_un;
-       struct addrinfo addr;
-
-       okflag = 0;
+       struct sockaddr_un serv_addr;
        strRemoteHost = "";
 
-       memset(&serv_addr_un, 0, sizeof(serv_addr_un));
-       serv_addr_un.sun_family = AF_LOCAL;
-       strcpy(serv_addr_un.sun_path, path.c_str());
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sun_family = AF_LOCAL;
+       strcpy(serv_addr.sun_path, path.c_str());
 
-       memset(&addr, 0, sizeof(addr));
-       addr.ai_family = AF_LOCAL;
-       addr.ai_socktype = SOCK_STREAM;
-       addr.ai_protocol = 0; /* any */
-       addr.ai_addr = (struct sockaddr *)&serv_addr_un;
-       addr.ai_addrlen = sizeof(serv_addr_un);
+       okflag=1;
 
        unlink(path.c_str());
-
-       if (startListening(&addr) >= 0)
+       if(bind(getDescriptor(),
+               (struct sockaddr *) &serv_addr,
+               sizeof(serv_addr))<0)
        {
-               okflag = 1;
-               rsn->setRequested(eSocketNotifier::Read);
+               eDebug("[eServerSocket] ERROR on bind: %m");
+               okflag=0;
        }
+       listen(getDescriptor(), 0);
+
+       rsn->setRequested(eSocketNotifier::Read);
 }
 
 eServerSocket::~eServerSocket()
 {
-#ifdef DEBUG_SERVERSOCKET
+#if 0
        eDebug("[eServerSocket] destructed");
 #endif
 }
 
-int eServerSocket::startListening(struct addrinfo *addr)
-{
-       struct addrinfo *ptr = addr;
-       for (ptr = addr; ptr != NULL; ptr = ptr->ai_next)
-       {
-               if (setSocket(socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol), 1) < 0)
-               {
-                       continue;
-               }
-
-               int val = 1;
-               setsockopt(getDescriptor(), SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
-
-               if (bind(getDescriptor(), ptr->ai_addr, ptr->ai_addrlen) < 0)
-               {
-                       eDebug("[eServerSocket] ERROR on bind: %m");
-                       close();
-                       continue;
-               }
-       }
-
-       if (getDescriptor() < 0)
-       {
-               return -1;
-       }
-
-       if (listen(getDescriptor(), 0) < 0)
-       {
-               close();
-               return -1;
-       }
-       return 0;
-}
-
 int eServerSocket::bind(int sockfd, struct sockaddr *addr, socklen_t addrlen)
 {
        int result;
index 0b290bb..a4df9b5 100644 (file)
@@ -9,8 +9,7 @@ class eServerSocket: public eSocket
        int okflag;
        std::string strRemoteHost;
 protected:
-       virtual void newConnection(int socket) = 0;
-       int startListening(struct addrinfo *addr);
+       virtual void newConnection(int socket)=0;
        int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
        int listen(int sockfd, int backlog);
        int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
index 638ec6d..847fc7b 100644 (file)
@@ -3,7 +3,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <time.h>
-#include <string.h>
 #include <linux/serial.h>
 #include <lib/network/socket.h>
 
@@ -11,19 +10,19 @@ void eSocket::close()
 {
        if (writebuffer.empty())
        {
-               int wasconnected = (mystate == Connection) || (mystate == Closing);
-               rsn = 0;
+               int wasconnected=(mystate==Connection) || (mystate==Closing);
+               rsn=0;
                if (socketdesc >= 0)
                {
                        ::close(socketdesc);
-                       socketdesc = -1;
+                       socketdesc=-1;
                }
-               mystate = Invalid;
+               mystate=Invalid;
                if (wasconnected)
                        connectionClosed_();
        } else
        {
-               mystate = Closing;
+               mystate=Closing;
                rsn->setRequested(rsn->getRequested()|eSocketNotifier::Write);
        }
 }
@@ -84,16 +83,16 @@ int eSocket::state()
        return mystate;
 }
 
-int eSocket::setSocket(int s, int iss)
+int eSocket::setSocket(int s, int iss, eMainloop *ml)
 {
-       socketdesc = s;
+       socketdesc=s;
        if (socketdesc < 0) return -1;
-       issocket = iss;
+       issocket=iss;
        fcntl(socketdesc, F_SETFL, O_NONBLOCK);
        last_break = -1;
 
        rsn = 0;
-       rsn = eSocketNotifier::create(mainloop, getDescriptor(),
+       rsn=eSocketNotifier::create(ml, getDescriptor(),
                eSocketNotifier::Read|eSocketNotifier::Hungup);
        CONNECT(rsn->activated, eSocket::notifier);
        return 0;
@@ -232,96 +231,80 @@ int eSocket::getDescriptor()
        return socketdesc;
 }
 
-int eSocket::connect(struct addrinfo *addr)
-{
-       int res;
-       struct addrinfo *ptr = addr;
-       for (ptr = addr; ptr != NULL; ptr = ptr->ai_next)
-       {
-               close();
-               if (setSocket(socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol), 1) < 0)
-               {
-                       continue;
-               }
-               mystate = Idle;
-
-               res = ::connect(socketdesc, ptr->ai_addr, ptr->ai_addrlen);
-               if ((res < 0) && (errno != EINPROGRESS) && (errno != EINTR))
-               {
-                       error_(errno);
-                       continue;
-               }
-               if (res < 0)    // EINPROGRESS or EINTR
-               {
-                       rsn->setRequested(rsn->getRequested() | eSocketNotifier::Write);
-                       mystate = Connecting;
-                       return 0;
-               }
-               else
-               {
-                       mystate = Connection;
-                       connected_();
-                       return 1;
-               }
-       }
-       return -1;
-}
-
 int eSocket::connectToHost(std::string hostname, int port)
 {
+       sockaddr_in  serv_addr;
+       struct hostent *server;
        int res;
-       struct addrinfo *addr = NULL;
-       struct addrinfo hints;
-       char portnumber[16];
 
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = AF_UNSPEC; /* both ipv4 and ipv6 */
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_protocol = 0; /* any */
-#ifdef AI_ADDRCONFIG
-       hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG; /* only return ipv6 if we have an ipv6 address ourselves, and ipv4 if we have an ipv4 address ourselves */
-#else
-       hints.ai_flags = AI_NUMERICSERV; /* AI_ADDRCONFIG is not available */
-#endif
-       snprintf(portnumber, sizeof(portnumber), "%d", port);
-
-       if ((res = getaddrinfo(hostname.c_str(), portnumber, &hints, &addr)) || !addr)
+       if (mystate == Invalid)
        {
-               eDebug("[eSocket] can't resolve %s (getaddrinfo: %s)", hostname.c_str(), gai_strerror(res));
-               return -2;
+               /* the socket has been closed, create a new socket descriptor */
+               int s=socket(AF_INET, SOCK_STREAM, 0);
+               mystate=Idle;
+               setSocket(s, 1, mainloop);
        }
 
-       res = connect(addr);
-       if (res < 0)
+       if(socketdesc < 0){
+               error_(errno);
+               return(-1);
+       }
+       server=gethostbyname(hostname.c_str());
+       if(server==NULL)
+       {
+               eDebug("[eSocket] can't resolve %s", hostname.c_str());
+               error_(errno);
+               return(-2);
+       }
+       bzero(&serv_addr, sizeof(serv_addr));
+       serv_addr.sin_family=AF_INET;
+       bcopy(server->h_addr, &serv_addr.sin_addr.s_addr, server->h_length);
+       serv_addr.sin_port=htons(port);
+       res=::connect(socketdesc, (const sockaddr*)&serv_addr, sizeof(serv_addr));
+       if ((res < 0) && (errno != EINPROGRESS) && (errno != EINTR))
        {
                eDebug("[eSocket] can't connect to host: %s", hostname.c_str());
+               close();
+               error_(errno);
+               return(-3);
+       }
+       if (res < 0)    // EINPROGRESS or EINTR
+       {
+               rsn->setRequested(rsn->getRequested()|eSocketNotifier::Write);
+               mystate=Connecting;
+       } else
+       {
+               mystate=Connection;
+               connected_();
        }
-       freeaddrinfo(addr);
-       return res;
+       return(0);
 }
 
-eSocket::eSocket(eMainloop *ml): readbuffer(32768), writebuffer(32768), mainloop(ml)
+eSocket::eSocket(eMainloop *ml, int domain): readbuffer(32768), writebuffer(32768), mainloop(ml)
 {
-       socketdesc = -1;
-       mystate = Invalid;
+       int s=socket(domain, SOCK_STREAM, 0);
+#if 0
+       eDebug("[eSocket] initalized socket %d", socketdesc);
+#endif
+       mystate=Idle;
+       setSocket(s, 1, ml);
 }
 
 eSocket::eSocket(int socket, int issocket, eMainloop *ml): readbuffer(32768), writebuffer(32768), mainloop(ml)
 {
-       setSocket(socket, issocket);
-       mystate = Connection;
+       setSocket(socket, issocket, ml);
+       mystate=Connection;
 }
 
 eSocket::~eSocket()
 {
-       if (socketdesc >= 0)
+       if(socketdesc>=0)
        {
                ::close(socketdesc);
-               socketdesc = -1;
        }
 }
 
-eUnixDomainSocket::eUnixDomainSocket(eMainloop *ml) : eSocket(ml)
+eUnixDomainSocket::eUnixDomainSocket(eMainloop *ml) : eSocket(ml, AF_LOCAL)
 {
 }
 
@@ -335,21 +318,39 @@ eUnixDomainSocket::~eUnixDomainSocket()
 
 int eUnixDomainSocket::connectToPath(std::string path)
 {
+       sockaddr_un serv_addr_un;
        int res;
-       struct sockaddr_un serv_addr_un;
-       struct addrinfo addr;
 
-       memset(&serv_addr_un, 0, sizeof(serv_addr_un));
+       if (mystate == Invalid)
+       {
+               /* the socket has been closed, create a new socket descriptor */
+               int s=socket(AF_LOCAL, SOCK_STREAM, 0);
+               mystate=Idle;
+               setSocket(s, 1, mainloop);
+       }
+
+       if(socketdesc < 0){
+               error_(errno);
+               return(-1);
+       }
+       bzero(&serv_addr_un, sizeof(serv_addr_un));
        serv_addr_un.sun_family = AF_LOCAL;
        strcpy(serv_addr_un.sun_path, path.c_str());
-
-       memset(&addr, 0, sizeof(addr));
-       addr.ai_family = AF_LOCAL;
-       addr.ai_socktype = SOCK_STREAM;
-       addr.ai_protocol = 0; /* any */
-       addr.ai_addr = (struct sockaddr *)&serv_addr_un;
-       addr.ai_addrlen = sizeof(serv_addr_un);
-
-       res = connect(&addr);
-       return res;
+       res=::connect(socketdesc, (const sockaddr*)&serv_addr_un, sizeof(serv_addr_un));
+       if ((res < 0) && (errno != EINPROGRESS) && (errno != EINTR))
+       {
+               close();
+               error_(errno);
+               return(-3);
+       }
+       if (res < 0)    // EINPROGRESS or EINTR
+       {
+               rsn->setRequested(rsn->getRequested()|eSocketNotifier::Write);
+               mystate=Connecting;
+       } else
+       {
+               mystate=Connection;
+               connected_();
+       }
+       return(0);
 }
index 99c9bbb..da4aaff 100644 (file)
@@ -29,15 +29,14 @@ protected:
        ePtr<eSocketNotifier> rsn;
        eMainloop *mainloop;
        virtual void notifier(int);
-       int connect(struct addrinfo *addr);
 public:
-       eSocket(eMainloop *ml);
+       eSocket(eMainloop *ml, int domain = AF_INET);
        eSocket(int socket, int issocket, eMainloop *ml);
        virtual ~eSocket();
        int connectToHost(std::string hostname, int port);
        int getDescriptor();
        int writeBlock(const char *data, unsigned int len);
-       int setSocket(int socketfd, int issocket);
+       int setSocket(int socketfd, int issocket, eMainloop *ml);
        int bytesToWrite();
        int readBlock(char *data, unsigned int maxlen);
        int bytesAvailable();