[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH 6/7] MAX_SOCKETS: New patch implementing unlimited number of sockets



---
 debian/patches/max_sockets | 247 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 247 insertions(+)
 create mode 100644 debian/patches/max_sockets

diff --git a/debian/patches/max_sockets b/debian/patches/max_sockets
new file mode 100644
index 0000000..bdc7293
--- /dev/null
+++ b/debian/patches/max_sockets
@@ -0,0 +1,247 @@
+--- a/src/core/init.c
++++ b/src/core/init.c
+@@ -173,6 +173,9 @@
+ #if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
+   #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
+ #endif
++#if (LWIP_SOCKET_OPEN_COUNT && !MEMP_MEM_MALLOC)
++  #error "LWIP_SOCKET_OPEN_COUNT requires MEMP_MEM_MALLOC=1 in your lwipopts.h"
++#endif
+ #if (LWIP_PPP_API && (NO_SYS==1))
+   #error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h"
+ #endif
+--- a/src/include/lwip/opt.h
++++ b/src/include/lwip/opt.h
+@@ -1791,6 +1791,16 @@
+ #endif
+ 
+ /**
++ * LWIP_SOCKET_OPEN_COUNT==1: Number of sockets is not limited to MEMP_NUM_NETCONN.
++ * When enabled, sockets are allocated in the heap and the amount of sockets is
++ * only limited by the heap size. Handle with care regarding execution speed.
++ * To use this, MEMP_MEM_MALLOC also has to be enabled.
++ */
++#if !defined LWIP_SOCKET_OPEN_COUNT || defined __DOXYGEN__
++#define LWIP_SOCKET_OPEN_COUNT              0
++#endif
++
++/**
+  * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
+  * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
+  * in seconds. (does not require sockets.c, and will affect tcp.c)
+--- a/src/api/sockets.c
++++ b/src/api/sockets.c
+@@ -198,6 +198,12 @@
+ 
+ /** Contains all internal pointers and states used for a socket */
+ struct lwip_sock {
++#if LWIP_SOCKET_OPEN_COUNT
++  /** Next element in the linked list */
++  struct lwip_sock *next;
++  /** Socket number*/
++  int count;
++#endif /* LWIP_SOCKET_OPEN_COUNT */
+   /** sockets currently are built on netconns, each socket has one netconn */
+   struct netconn *conn;
+   /** data that was left from the previous read */
+@@ -287,8 +293,13 @@
+ static void lwip_socket_drop_registered_memberships(int s);
+ #endif /* LWIP_IGMP */
+ 
++#if LWIP_SOCKET_OPEN_COUNT
++/** The global linked list of available sockets */
++static struct lwip_sock *sockets = NULL;
++#else /* LWIP_SOCKET_OPEN_COUNT */
+ /** The global array of available sockets */
+ static struct lwip_sock sockets[NUM_SOCKETS];
++#endif /* LWIP_SOCKET_OPEN_COUNT */
+ /** The global list of tasks waiting for select */
+ static struct lwip_select_cb *select_cb_list;
+ /** This counter is increased from lwip_select when the list is changed
+@@ -359,15 +370,26 @@
+ 
+   s -= LWIP_SOCKET_OFFSET;
+ 
+-  if ((s < 0) || (s >= NUM_SOCKETS)) {
++  if ((s < 0)
++#if !LWIP_SOCKET_OPEN_COUNT
++      || (s >= NUM_SOCKETS)
++#endif /* !LWIP_SOCKET_OPEN_COUNT */
++      ) {
+     LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s + LWIP_SOCKET_OFFSET));
+     set_errno(EBADF);
+     return NULL;
+   }
+ 
++#if LWIP_SOCKET_OPEN_COUNT
++  for(sock = sockets; sock != NULL; sock = sock->next) {
++    if(sock->count == s)
++      break;
++  }
++#else /* LWIP_SOCKET_OPEN_COUNT */
+   sock = &sockets[s];
++#endif /* LWIP_SOCKET_OPEN_COUNT */
+ 
+-  if (!sock->conn) {
++  if (!sock || !sock->conn) {
+     LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s + LWIP_SOCKET_OFFSET));
+     set_errno(EBADF);
+     return NULL;
+@@ -386,13 +408,26 @@
+ tryget_socket(int s)
+ {
+   s -= LWIP_SOCKET_OFFSET;
+-  if ((s < 0) || (s >= NUM_SOCKETS)) {
++  if ((s < 0)
++#if !LWIP_SOCKET_OPEN_COUNT
++      || (s >= NUM_SOCKETS)
++#endif /* !LWIP_SOCKET_OPEN_COUNT */
++      ) {
+     return NULL;
+   }
++#if LWIP_SOCKET_OPEN_COUNT
++  struct lwip_sock *sock;
++  for(sock = sockets; sock != NULL; sock = sock->next) {
++    if(sock->count == s)
++      break;
++  }
++  return sock;
++#else /* LWIP_SOCKET_OPEN_COUNT */
+   if (!sockets[s].conn) {
+     return NULL;
+   }
+   return &sockets[s];
++#endif /* LWIP_SOCKET_OPEN_COUNT */
+ }
+ 
+ /**
+@@ -407,30 +442,70 @@
+ alloc_socket(struct netconn *newconn, int accepted)
+ {
+   int i;
++  struct lwip_sock *newsock = NULL;
++#if LWIP_SOCKET_OPEN_COUNT
++  struct lwip_sock **it;
++#endif /* LWIP_SOCKET_OPEN_COUNT */
++
+   SYS_ARCH_DECL_PROTECT(lev);
+ 
++#if LWIP_SOCKET_OPEN_COUNT
++  newsock = (struct lwip_sock*)mem_malloc(sizeof(struct lwip_sock));
++  if(!newsock) {
++    return -1;
++  }
++  /* Protect socket list */
++  SYS_ARCH_PROTECT(lev);
++  it = &sockets;
++  i = LWIP_SOCKET_OFFSET;
++  while(*it) {
++    if((*it)->count != i) {
++      /* There's a gap in the list, fill it */
++      break;
++    }
++    i++;
++    it = &(*it)->next;
++  }
++  /* Add the new socket in the first gap found or in the end */
++  newsock->count = i;
++  newsock->next = (*it);
++  (*it) = newsock;
++  newsock->conn = newconn;
++  SYS_ARCH_UNPROTECT(lev);
++#else /* LWIP_SOCKET_OPEN_COUNT */
+   /* allocate a new socket identifier */
+   for (i = 0; i < NUM_SOCKETS; ++i) {
+     /* Protect socket array */
+     SYS_ARCH_PROTECT(lev);
+     if (!sockets[i].conn && (sockets[i].select_waiting == 0)) {
+-      sockets[i].conn       = newconn;
++      newsock = &sockets[i];
++      sockets[i].conn = newconn;
+       /* The socket is not yet known to anyone, so no need to protect
+          after having marked it as used. */
+       SYS_ARCH_UNPROTECT(lev);
+-      sockets[i].lastdata   = NULL;
+-      sockets[i].lastoffset = 0;
+-      sockets[i].rcvevent   = 0;
+-      /* TCP sendbuf is empty, but the socket is not yet writable until connected
+-       * (unless it has been created by accept()). */
+-      sockets[i].sendevent  = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
+-      sockets[i].errevent   = 0;
+-      sockets[i].err        = 0;
+-      return i + LWIP_SOCKET_OFFSET;
++      break;
+     }
+     SYS_ARCH_UNPROTECT(lev);
+   }
+-  return -1;
++  if(!newsock) {
++    return -1;
++  }
++  i += LWIP_SOCKET_OFFSET;
++#endif /* LWIP_SOCKET_OPEN_COUNT */
++
++  LWIP_ASSERT("i >= 0", i >= 0);
++
++  newsock->lastdata   = NULL;
++  newsock->lastoffset = 0;
++  newsock->rcvevent   = 0;
++  /* TCP sendbuf is empty, but the socket is not yet writable until connected
++   * (unless it has been created by accept()). */
++  newsock->sendevent  = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
++  newsock->errevent   = 0;
++  newsock->err        = 0;
++  newsock->select_waiting = 0;
++
++  return i;
+ }
+ 
+ /** Free a socket. The socket's netconn must have been
+@@ -442,9 +517,14 @@
+ static void
+ free_socket(struct lwip_sock *sock, int is_tcp)
+ {
+-  void *lastdata;
+-
+-  lastdata         = sock->lastdata;
++  void *lastdata = sock->lastdata;
++#if LWIP_SOCKET_OPEN_COUNT
++  struct lwip_sock **it = &sockets;
++
++  while(*it != sock) it = &(*it)->next;
++  *it = (*it)->next;
++  mem_free(sock);
++#else /* LWIP_SOCKET_OPEN_COUNT */
+   sock->lastdata   = NULL;
+   sock->lastoffset = 0;
+   sock->err        = 0;
+@@ -452,6 +532,7 @@
+   /* Protect socket array */
+   SYS_ARCH_SET(sock->conn, NULL);
+   /* don't use 'sock' after this line, as another task might have allocated it */
++#endif /* LWIP_SOCKET_OPEN_COUNT */
+ 
+   if (lastdata != NULL) {
+     if (is_tcp) {
+@@ -512,7 +593,9 @@
+     sock_set_errno(sock, ENFILE);
+     return -1;
+   }
++#if !LWIP_SOCKET_OPEN_COUNT
+   LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET));
++#endif /* !LWIP_SOCKET_OPEN_COUNT */
+   LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback);
+   nsock = &sockets[newsock - LWIP_SOCKET_OFFSET];
+ 
+--- a/port/include/lwipopts.h
++++ b/port/include/lwipopts.h
+@@ -26,6 +26,9 @@
+ /* Don't rename Sockets API functions */
+ #define LWIP_COMPAT_SOCKETS   0
+ 
++/* Don't limit the number of sockets */
++#define LWIP_SOCKET_OPEN_COUNT  1
++
+ /* We're using lwip_poll() */
+ #define LWIP_POLL               1
+ 
-- 
2.14.0


Reply to: