Skip to content

Add patch to fix the maximum number of TCP PCBs in TIME_WAIT #191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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