Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > 52f70f7c994a43049ad37181c4e43de2 > files > 5

licq-1.3.5-3mdv2008.0.src.rpm

Index: /trunk/licq/include/licq_socket.h
===================================================================
--- licq-1.3.5/include/licq_socket.h (revision 4714)
+++ licq-1.3.5/include/licq_socket.h (revision 6146)
@@ -251,4 +251,5 @@
   fd_set SocketSet()   {  return m_sSockets.SocketSet(); }
   int LargestSocket()  {  return m_sSockets.Largest(); }
+  unsigned short Num() {  return m_sSockets.Num(); }
 
 protected:
Index: licq-1.3.5/src/socket.cpp
===================================================================
--- licq-1.3.5/src/socket.cpp (revision 5629)
+++ licq-1.3.5/src/socket.cpp (revision 6146)
@@ -818,6 +818,24 @@
   socklen_t sizeofSockaddr = sizeof(struct sockaddr_in);
 
-  newSocket.m_nDescriptor = accept(m_nDescriptor, (struct sockaddr *)&newSocket.m_sRemoteAddr, &sizeofSockaddr);
-  newSocket.SetLocalAddress();
+  // Make sure we stay under FD_SETSIZE
+  // See:
+  // * http://www.securityfocus.com/archive/1/490711
+  // * http://securityvulns.com/docs7669.html
+  // for more details
+  // This probably has no affect, since we are using multiple threads, but keep it here 
+  // to be used as a sanity check.
+  int newDesc = accept(m_nDescriptor, (struct sockaddr *)&newSocket.m_sRemoteAddr, &sizeofSockaddr);
+  if (newDesc < FD_SETSIZE)
+  {
+    newSocket.m_nDescriptor = newDesc;
+    newSocket.SetLocalAddress();
+  }
+  else
+  {
+    gLog.Error(tr("%sCannot accept new connection, too many descriptors in use.\n"), L_ERRORxSTR);
+    close(newDesc);
+
+    // TODO throw an exception, or do something to tell the caller it failed
+  }
 }
 
Index: licq-1.3.5/src/icqd-threads.cpp
===================================================================
--- licq-1.3.5/src/icqd-threads.cpp (revision 5450)
+++ licq-1.3.5/src/icqd-threads.cpp (revision 6146)
@@ -24,4 +24,5 @@
 #include "gettext.h"
 
+#define MAX_CONNECTS  256
 #define DEBUG_THREADS(x)
 //#define DEBUG_THREADS(x) gLog.Info(x)
@@ -781,6 +782,19 @@
               tcp->RecvConnection(*newSocket);
               gSocketManager.DropSocket(tcp);
-              gSocketManager.AddSocket(newSocket);
-              gSocketManager.DropSocket(newSocket);
+
+              // Make sure we can handle another socket before accepting it
+              if (gSocketManager.Num() > MAX_CONNECTS)
+              {
+                // Too many sockets, drop this one
+                char remoteIp[32];
+                gLog.Warn(tr("%sToo many connected sockets, rejecting connection from %s.\n"),
+                    L_WARNxSTR, newSocket->RemoteIpStr(remoteIp));
+                delete newSocket;
+              }
+              else
+              {
+                gSocketManager.AddSocket(newSocket);
+                gSocketManager.DropSocket(newSocket);
+              }
             }
           }
Index: licq-1.3.5/src/icqd-chat.cpp
===================================================================
--- licq-1.3.5/src/icqd-chat.cpp (revision 6136)
+++ licq-1.3.5/src/icqd-chat.cpp (revision 6146)
@@ -24,4 +24,5 @@
 #include "gettext.h"
 
+#define MAX_CONNECTS  256
 #define DEBUG_THREADS(x)
 
@@ -2384,14 +2385,22 @@
         else if (nCurrentSocket == chatman->chatServer.Descriptor())
         {
-          CChatUser *u = new CChatUser;
-          u->m_pClient = new CChatClient;
-
-          chatman->chatServer.RecvConnection(u->sock);
-          chatman->sockman.AddSocket(&u->sock);
-          chatman->sockman.DropSocket(&u->sock);
-
-          u->state = CHAT_STATE_HANDSHAKE;
-          chatman->chatUsers.push_back(u);
-          gLog.Info(tr("%sChat: Received connection.\n"), L_TCPxSTR);
+          if (chatman->sockman.Num() >= MAX_CONNECTS)
+          {
+            // Too many sockets, drop this one
+            gLog.Warn(tr("%sToo many connected clients, rejecting new connection.\n"), L_WARNxSTR);
+          }
+          else
+          {
+            CChatUser *u = new CChatUser;
+            u->m_pClient = new CChatClient;
+
+            chatman->chatServer.RecvConnection(u->sock);
+            chatman->sockman.AddSocket(&u->sock);
+            chatman->sockman.DropSocket(&u->sock);
+
+            u->state = CHAT_STATE_HANDSHAKE;
+            chatman->chatUsers.push_back(u);
+            gLog.Info(tr("%sChat: Received connection.\n"), L_TCPxSTR);
+          }
         }