Skip to content

Commit

Permalink
Add patch to fix the maximum number of TCP PCBs in TIME_WAIT (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
me-no-dev authored Jul 10, 2024
1 parent b662e2d commit 8856591
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
118 changes: 118 additions & 0 deletions patches/lwip_max_tcp_pcb.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
diff --git a/components/lwip/lwip/src/core/memp.c b/components/lwip/lwip/src/core/memp.c
index 352ce5a55127a658b6b3c9d8541298c42df332ff..39433cf476b3456b046e337e9b1f016299964a84 100644
--- a/components/lwip/lwip/src/core/memp.c
+++ b/components/lwip/lwip/src/core/memp.c
@@ -240,6 +240,10 @@ memp_init(void)
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
}

+#if MEMP_MEM_MALLOC && ESP_LWIP && LWIP_TCP
+static u32_t num_tcp_pcb = 0;
+#endif
+
static void *
#if !MEMP_OVERFLOW_CHECK
do_memp_malloc_pool(const struct memp_desc *desc)
@@ -251,6 +255,16 @@ do_memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int
SYS_ARCH_DECL_PROTECT(old_level);

#if MEMP_MEM_MALLOC
+#if ESP_LWIP
+#if LWIP_TCP
+ if(desc == memp_pools[MEMP_TCP_PCB]){
+ if(num_tcp_pcb >= MEMP_NUM_TCP_PCB){
+ return NULL;
+ }
+ }
+#endif
+#endif
+
memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size));
SYS_ARCH_PROTECT(old_level);
#else /* MEMP_MEM_MALLOC */
@@ -260,6 +274,12 @@ do_memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int
#endif /* MEMP_MEM_MALLOC */

if (memp != NULL) {
+#if MEMP_MEM_MALLOC && ESP_LWIP && LWIP_TCP
+ if (desc == memp_pools[MEMP_TCP_PCB]) {
+ num_tcp_pcb++;
+ }
+#endif
+
#if !MEMP_MEM_MALLOC
#if MEMP_OVERFLOW_CHECK == 1
memp_overflow_check_element(memp, desc);
@@ -369,6 +389,12 @@ do_memp_free_pool(const struct memp_desc *desc, void *mem)

SYS_ARCH_PROTECT(old_level);

+#if MEMP_MEM_MALLOC && ESP_LWIP && LWIP_TCP
+ if (desc == memp_pools[MEMP_TCP_PCB]) {
+ num_tcp_pcb--;
+ }
+#endif
+
#if MEMP_OVERFLOW_CHECK == 1
memp_overflow_check_element(memp, desc);
#endif /* MEMP_OVERFLOW_CHECK */
diff --git a/components/lwip/lwip/src/core/tcp.c b/components/lwip/lwip/src/core/tcp.c
index 3fbdd89ae07807208ff7466abb50f90b5e7727e4..fe6baaf250927cb4b89f8d1dbd41c73def88692b 100644
--- a/components/lwip/lwip/src/core/tcp.c
+++ b/components/lwip/lwip/src/core/tcp.c
@@ -1765,7 +1765,9 @@ tcp_kill_state(enum tcp_state state)
struct tcp_pcb *pcb, *inactive;
u32_t inactivity;

+#if !ESP_LWIP
LWIP_ASSERT("invalid state", (state == CLOSING) || (state == LAST_ACK));
+#endif

inactivity = 0;
inactive = NULL;
@@ -1870,17 +1872,41 @@ tcp_alloc(u8_t prio)
tcp_kill_state(CLOSING);
/* Try to allocate a tcp_pcb again. */
pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+#if ESP_LWIP
if (pcb == NULL) {
- /* Try killing oldest active connection with lower priority than the new one. */
- LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing oldest connection with prio lower than %d\n", prio));
- tcp_kill_prio(prio);
- /* Try to allocate a tcp_pcb again. */
+ /* Try killing oldest connection in FIN_WAIT_2. */
+ LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest FIN_WAIT_2 connection\n"));
+ tcp_kill_state(FIN_WAIT_2);
pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+ if (pcb == NULL) {
+ /* Try killing oldest connection in FIN_WAIT_1. */
+ LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest FIN_WAIT_1 connection\n"));
+ tcp_kill_state(FIN_WAIT_1);
+ pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+#endif
+ if (pcb == NULL) {
+ /* Try killing oldest active connection with lower priority than the new one. */
+ LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing oldest connection with prio lower than %d\n", prio));
+ tcp_kill_prio(prio);
+ /* Try to allocate a tcp_pcb again. */
+ pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
+ if (pcb != NULL) {
+ /* adjust err stats: memp_malloc failed multiple times before */
+ MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+ }
+ }
+#if ESP_LWIP
+ if (pcb != NULL) {
+ /* adjust err stats: memp_malloc failed multiple times before */
+ MEMP_STATS_DEC(err, MEMP_TCP_PCB);
+ }
+ }
if (pcb != NULL) {
/* adjust err stats: memp_malloc failed multiple times before */
MEMP_STATS_DEC(err, MEMP_TCP_PCB);
}
}
+#endif
if (pcb != NULL) {
/* adjust err stats: memp_malloc failed multiple times before */
MEMP_STATS_DEC(err, MEMP_TCP_PCB);
1 change: 1 addition & 0 deletions tools/install-esp-idf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ if [ ! -x $idf_was_installed ] || [ ! -x $commit_predefined ]; then
cd $IDF_PATH
patch -p1 -N -i ../patches/esp32s2_i2c_ll_master_init.diff
patch -p1 -N -i ../patches/mmu_map.diff
patch -p1 -N -i ../patches/lwip_max_tcp_pcb.diff
cd -
fi

Expand Down

0 comments on commit 8856591

Please sign in to comment.