summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan Lledó <joanlluislledo@gmail.com>2018-04-30 13:11:17 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-05-01 01:35:03 +0200
commit05403a6e3a72c085e25b46c3173efde4cf64c21f (patch)
tree6d5b62bef9cadf4104a6a9227d0345d630d27700
parent37496853cd98e546142c1bef8deaecb78e8db8a2 (diff)
MAX_SOCKETS: New patch implementing unlimited number of sockets
-rw-r--r--debian/patches/max_sockets247
1 files changed, 247 insertions, 0 deletions
diff --git a/debian/patches/max_sockets b/debian/patches/max_sockets
new file mode 100644
index 00000000..c76afcab
--- /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
+