From 554e104095a25a0e6585385c6775c5534efa4cde Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Thu, 6 Feb 2025 08:34:57 +0100 Subject: [PATCH 01/16] next release will probably be 2.2.2 --- doc/doxygen/lwip.Doxyfile | 2 +- src/Filelists.cmake | 4 ++-- src/include/lwip/init.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/doxygen/lwip.Doxyfile b/doc/doxygen/lwip.Doxyfile index f68fa0c5..36526a72 100644 --- a/doc/doxygen/lwip.Doxyfile +++ b/doc/doxygen/lwip.Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "lwIP" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "2.2.1" +PROJECT_NUMBER = "2.2.2.dev" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/src/Filelists.cmake b/src/Filelists.cmake index 228e0f0c..c65f30a3 100644 --- a/src/Filelists.cmake +++ b/src/Filelists.cmake @@ -14,11 +14,11 @@ endif() set(LWIP_VERSION_MAJOR "2") set(LWIP_VERSION_MINOR "2") -set(LWIP_VERSION_REVISION "1") +set(LWIP_VERSION_REVISION "2") # LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases # LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions # Numbers 1..31 are reserved for release candidates -set(LWIP_VERSION_RC "LWIP_RC_RELEASE") +set(LWIP_VERSION_RC "LWIP_RC_DEVELOPMENT") if ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_RELEASE") set(LWIP_VERSION_STRING diff --git a/src/include/lwip/init.h b/src/include/lwip/init.h index f579da48..6232085b 100644 --- a/src/include/lwip/init.h +++ b/src/include/lwip/init.h @@ -54,11 +54,11 @@ extern "C" { /** x.X.x: Minor version of the stack */ #define LWIP_VERSION_MINOR 2 /** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION 1 +#define LWIP_VERSION_REVISION 2 /** For release candidates, this is set to 1..254 * For official releases, this is set to 255 (LWIP_RC_RELEASE) * For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC LWIP_RC_RELEASE +#define LWIP_VERSION_RC LWIP_RC_DEVELOPMENT /** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ #define LWIP_RC_RELEASE 255 From ba306bcdaa5e734456d157a896534a5203a216a9 Mon Sep 17 00:00:00 2001 From: Matthias Dietrich Date: Thu, 21 Mar 2024 23:29:28 +0100 Subject: [PATCH 02/16] Fix missing END_TEST in test_ip6_reass unit test Signed-off-by: Simon Goldschmidt --- test/unit/ip6/test_ip6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/ip6/test_ip6.c b/test/unit/ip6/test_ip6.c index a030ee5a..d37a6120 100644 --- a/test/unit/ip6/test_ip6.c +++ b/test/unit/ip6/test_ip6.c @@ -519,6 +519,7 @@ START_TEST(test_ip6_reass) test_ip6_reass_helper(130, t3, NUM_SEGS, 8); test_ip6_reass_helper(130, t4, NUM_SEGS, 1448); } +END_TEST /** Create the suite including all tests for this module */ Suite * From e55896319ba0e00f958b537e90104d7b88fabfca Mon Sep 17 00:00:00 2001 From: Jarno Malmari Date: Fri, 10 Mar 2023 14:52:54 +0200 Subject: [PATCH 03/16] Fix compilation with LWIP_DEBUG Signed-off-by: Simon Goldschmidt --- src/apps/http/altcp_proxyconnect.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/apps/http/altcp_proxyconnect.c b/src/apps/http/altcp_proxyconnect.c index 3d5e7e83..d487620e 100644 --- a/src/apps/http/altcp_proxyconnect.c +++ b/src/apps/http/altcp_proxyconnect.c @@ -576,6 +576,10 @@ const struct altcp_functions altcp_proxyconnect_functions = { altcp_default_get_tcp_addrinfo, altcp_default_get_ip, altcp_default_get_port +#if LWIP_TCP_KEEPALIVE + , altcp_default_keepalive_disable + , altcp_default_keepalive_enable +#endif #ifdef LWIP_DEBUG , altcp_default_dbg_get_tcp_state #endif From ffce5ab1c77690c99a97463ec4cec56e5b0ea8dc Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Mon, 3 Mar 2025 21:45:32 +0100 Subject: [PATCH 04/16] try to fix unit test compiling with clang --- test/unit/tcp/test_tcp.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/unit/tcp/test_tcp.c b/test/unit/tcp/test_tcp.c index 2efcbbf3..690ee408 100644 --- a/test/unit/tcp/test_tcp.c +++ b/test/unit/tcp/test_tcp.c @@ -534,15 +534,13 @@ START_TEST(test_tcp_fast_retx_recover) EXPECT_RET(txcounters.num_tx_calls == 0); EXPECT_RET(txcounters.num_tx_bytes == 0); memset(&txcounters, 0, sizeof(txcounters)); + + do { - int i = 0; - do - { - err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY); - i++; - }while(err == ERR_OK); - EXPECT_RET(err != ERR_OK); - } + err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY); + }while(err == ERR_OK); + EXPECT_RET(err != ERR_OK); + err = tcp_output(pcb); EXPECT_RET(err == ERR_OK); /*EXPECT_RET(txcounters.num_tx_calls == 0); From 845948800683f6e18d11db07d99466eb1ff99b9b Mon Sep 17 00:00:00 2001 From: Oswin Bult Date: Fri, 21 Mar 2025 18:48:50 +0300 Subject: [PATCH 05/16] Apply patch #10406: simplify sign extension --- src/apps/snmp/snmp_asn1.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/apps/snmp/snmp_asn1.c b/src/apps/snmp/snmp_asn1.c index 6df34dbd..0664ad9f 100644 --- a/src/apps/snmp/snmp_asn1.c +++ b/src/apps/snmp/snmp_asn1.c @@ -463,14 +463,8 @@ snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value if ((len > 0) && (len < 5)) { PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - if (data & 0x80) { - /* negative, start from -1 */ - *value = -1; - *value = (*value << 8) | data; - } else { - /* positive, start from 0 */ - *value = data; - } + /* sign extension */ + *value = (s8_t)data; len--; /* shift in the remaining value */ while (len > 0) { From 6c8874bf5dbfe3760e6a1e4d0b4ed64376e60137 Mon Sep 17 00:00:00 2001 From: Mike Kleshov Date: Fri, 21 Mar 2025 19:25:31 +0300 Subject: [PATCH 06/16] Apply patch #10047: HTTP11_CONNECTIONKEEPALIVE2 not needed any more --- src/apps/http/httpd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/apps/http/httpd.c b/src/apps/http/httpd.c index 3e9d2348..cf3abacf 100644 --- a/src/apps/http/httpd.c +++ b/src/apps/http/httpd.c @@ -120,7 +120,6 @@ #define CRLF "\r\n" #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE #define HTTP11_CONNECTIONKEEPALIVE "Connection: keep-alive" -#define HTTP11_CONNECTIONKEEPALIVE2 "Connection: Keep-Alive" #endif #if LWIP_HTTPD_DYNAMIC_FILE_READ @@ -2100,8 +2099,7 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct altcp_pcb *pc #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE /* This is HTTP/1.0 compatible: for strict 1.1, a connection would always be persistent unless "close" was specified. */ - if (!is_09 && (lwip_strnistr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) || - lwip_strnistr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) { + if (!is_09 && lwip_strnistr(data, HTTP11_CONNECTIONKEEPALIVE, data_len)) { hs->keepalive = 1; } else { hs->keepalive = 0; From f877b457a1bb759d48567326ec020be7e3a3d989 Mon Sep 17 00:00:00 2001 From: Mike Kleshov Date: Fri, 21 Mar 2025 19:35:05 +0300 Subject: [PATCH 07/16] Apply patch #10511: remove code with no effect in httpd.c --- src/apps/http/httpd.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/apps/http/httpd.c b/src/apps/http/httpd.c index cf3abacf..48a4733d 100644 --- a/src/apps/http/httpd.c +++ b/src/apps/http/httpd.c @@ -2118,12 +2118,6 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct altcp_pcb *pc struct pbuf *q = inp; #endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ err = http_post_request(q, hs, data, data_len, uri, sp2); - if (err != ERR_OK) { - /* restore header for next try */ - *sp1 = ' '; - *sp2 = ' '; - uri[uri_len] = ' '; - } if (err == ERR_ARG) { goto badrequest; } From 31d8988f89699aa357b0468a700483ea340e9da9 Mon Sep 17 00:00:00 2001 From: MinghaoWang Date: Fri, 21 Mar 2025 22:34:52 +0300 Subject: [PATCH 08/16] Apply patch #10358: preserve dhcp memory type flag --- src/core/ipv4/dhcp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index 12e00683..c149dd12 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -773,9 +773,6 @@ dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) * @ingroup dhcp4 * Removes a struct dhcp from a netif. * - * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the - * struct dhcp since the memory is passed back to the heap. - * * @param netif the netif from which to remove the struct dhcp */ void dhcp_cleanup(struct netif *netif) @@ -811,6 +808,7 @@ dhcp_start(struct netif *netif) { struct dhcp *dhcp; err_t result; + u8_t saved_flags; LWIP_ASSERT_CORE_LOCKED(); LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); @@ -846,9 +844,10 @@ dhcp_start(struct netif *netif) /* dhcp is cleared below, no need to reset flag*/ } - /* clear data structure */ + /* clear data structure but preserve DHCP_FLAG_EXTERNAL_MEM for dhcp_cleanup() */ + saved_flags = dhcp->flags; memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */ + dhcp->flags = saved_flags & DHCP_FLAG_EXTERNAL_MEM; #if LWIP_DHCP_DOES_ACD_CHECK From ca0395c5ae54273b4fd542ef25b57d4b759678f8 Mon Sep 17 00:00:00 2001 From: Mike Kleshov Date: Wed, 2 Apr 2025 10:22:43 +0300 Subject: [PATCH 09/16] Revert "Apply patch #10511: remove code with no effect in httpd.c" This reverts commit f877b457a1bb759d48567326ec020be7e3a3d989. --- src/apps/http/httpd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/apps/http/httpd.c b/src/apps/http/httpd.c index 48a4733d..cf3abacf 100644 --- a/src/apps/http/httpd.c +++ b/src/apps/http/httpd.c @@ -2118,6 +2118,12 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct altcp_pcb *pc struct pbuf *q = inp; #endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ err = http_post_request(q, hs, data, data_len, uri, sp2); + if (err != ERR_OK) { + /* restore header for next try */ + *sp1 = ' '; + *sp2 = ' '; + uri[uri_len] = ' '; + } if (err == ERR_ARG) { goto badrequest; } From 571c46253f49cfe228b6fd8dd7cf81439a3aee28 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Mon, 17 Mar 2025 12:27:40 +0700 Subject: [PATCH 10/16] src/core: fix gcc analyzer warning Make ip4_addr_isany check first to avoid warning: "check of 'ipaddr' for NULL after already dereferencing it [-Werror=analyzer-deref-before-check]" --- src/core/ipv4/etharp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ipv4/etharp.c b/src/core/ipv4/etharp.c index 3092dc94..5f63b543 100644 --- a/src/core/ipv4/etharp.c +++ b/src/core/ipv4/etharp.c @@ -940,9 +940,9 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) netif_addr_idx_t i; /* non-unicast address? */ - if (ip4_addr_isbroadcast(ipaddr, netif) || - ip4_addr_ismulticast(ipaddr) || - ip4_addr_isany(ipaddr)) { + if (ip4_addr_isany(ipaddr) || + ip4_addr_isbroadcast(ipaddr, netif) || + ip4_addr_ismulticast(ipaddr)) { LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); return ERR_ARG; } From 92522e45388ac5ef4911baff97a74415f5f4834b Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 26 May 2025 19:15:39 +0200 Subject: [PATCH 11/16] codeql: Use ubuntu-latest instead of 20.04 --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0876355f..5bf915e4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -25,7 +25,7 @@ jobs: # - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/using-larger-runners # Consider using larger runners for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} permissions: actions: read From 56b29f8bcfaefe2974dca67bde16cc7c391feaeb Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Tue, 3 Jun 2025 21:04:39 +0200 Subject: [PATCH 12/16] ip4_frag/ip6_frag: fix potential NULL-pointer access on memory errors --- CHANGELOG | 5 ++++ src/core/ipv4/ip4_frag.c | 28 ++++++++++--------- src/core/ipv6/ip6_frag.c | 58 +++++++++++++++++++++------------------- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 90a5834c..355175b6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,11 @@ HISTORY * [Enter new changes just after this line - do not remove this line] + ++ Bugfixes: + + 2025-06-03: Simon Goldschmidt + * ip4_frag/ip6_frag: fix potential NULL-pointer access on memory errors + (STABLE-2.2.1): ++ New features: diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c index 53031447..2652487b 100644 --- a/src/core/ipv4/ip4_frag.c +++ b/src/core/ipv4/ip4_frag.c @@ -175,19 +175,21 @@ ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *p MIB2_STATS_INC(mib2.ipreasmfails); #if LWIP_ICMP - iprh = (struct ip_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Then, copy the original header into it. */ - SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); - icmp_time_exceeded(p, ICMP_TE_FRAG); - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed = (u16_t)(pbufs_freed + clen); - pbuf_free(p); + if (ipr->p != NULL) { + iprh = (struct ip_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + icmp_time_exceeded(p, ICMP_TE_FRAG); + clen = pbuf_clen(p); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed = (u16_t)(pbufs_freed + clen); + pbuf_free(p); + } } #endif /* LWIP_ICMP */ diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c index ba91cfd4..66b12509 100644 --- a/src/core/ipv6/ip6_frag.c +++ b/src/core/ipv6/ip6_frag.c @@ -154,35 +154,37 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr) struct ip6_reass_helper *iprh; #if LWIP_ICMP6 - iprh = (struct ip6_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Restore the part that we've overwritten with our helper structure, or we - * might send garbage (and disclose a pointer) in the ICMPv6 reply. */ - MEMCPY(p->payload, ipr->orig_hdr, sizeof(*iprh)); - /* Then, move back to the original ipv6 header (we are now pointing to Fragment header). - This cannot fail since we already checked when receiving this fragment. */ - if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) { - LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed", 0); + if (ipr->p != NULL) { + iprh = (struct ip6_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Restore the part that we've overwritten with our helper structure, or we + * might send garbage (and disclose a pointer) in the ICMPv6 reply. */ + MEMCPY(p->payload, ipr->orig_hdr, sizeof(*iprh)); + /* Then, move back to the original ipv6 header (we are now pointing to Fragment header). + This cannot fail since we already checked when receiving this fragment. */ + if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) { + LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed", 0); + } + else { + /* Reconstruct the zoned source and destination addresses, so that we do + * not end up sending the ICMP response over the wrong link. */ + ip6_addr_t src_addr, dest_addr; + ip6_addr_copy_from_packed(src_addr, IPV6_FRAG_SRC(ipr)); + ip6_addr_set_zone(&src_addr, ipr->src_zone); + ip6_addr_copy_from_packed(dest_addr, IPV6_FRAG_DEST(ipr)); + ip6_addr_set_zone(&dest_addr, ipr->dest_zone); + /* Send the actual ICMP response. */ + icmp6_time_exceeded_with_addrs(p, ICMP6_TE_FRAG, &src_addr, &dest_addr); + } + clen = pbuf_clen(p); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed = (u16_t)(pbufs_freed + clen); + pbuf_free(p); } - else { - /* Reconstruct the zoned source and destination addresses, so that we do - * not end up sending the ICMP response over the wrong link. */ - ip6_addr_t src_addr, dest_addr; - ip6_addr_copy_from_packed(src_addr, IPV6_FRAG_SRC(ipr)); - ip6_addr_set_zone(&src_addr, ipr->src_zone); - ip6_addr_copy_from_packed(dest_addr, IPV6_FRAG_DEST(ipr)); - ip6_addr_set_zone(&dest_addr, ipr->dest_zone); - /* Send the actual ICMP response. */ - icmp6_time_exceeded_with_addrs(p, ICMP6_TE_FRAG, &src_addr, &dest_addr); - } - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed = (u16_t)(pbufs_freed + clen); - pbuf_free(p); } #endif /* LWIP_ICMP6 */ From b1edb7780f5f7192cb4a7751f89d4eb6a19ad67f Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Fri, 4 Oct 2024 11:01:47 +0200 Subject: [PATCH 13/16] tftp: bind to TFTP port only when in server mode The TFTP app should not bind to the TFTP server port when configured as a client. Instead, the local port should be chosen from the dynamic range (49152 ~ 65535) so that if the application is stopped and started again, the remote server will not consider the new packets as part of the same context (which would cause an error since a new RRQ would be unexpected). Signed-off-by: Jerome Forissier Reviewed-by: Ilias Apalodimas --- src/apps/tftp/tftp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/apps/tftp/tftp.c b/src/apps/tftp/tftp.c index aab1d9ce..59cf95b8 100644 --- a/src/apps/tftp/tftp.c +++ b/src/apps/tftp/tftp.c @@ -454,10 +454,12 @@ tftp_init_common(u8_t mode, const struct tftp_context *ctx) return ERR_MEM; } - ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT); - if (ret != ERR_OK) { - udp_remove(pcb); - return ret; + if (mode & LWIP_TFTP_MODE_SERVER) { + ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT); + if (ret != ERR_OK) { + udp_remove(pcb); + return ret; + } } tftp_state.handle = NULL; From e7ab7e0773268c0274d96f4bcc43da72691c1d07 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 28 Nov 2024 12:51:10 +0100 Subject: [PATCH 14/16] autoip: Choose next address after rate limit AutoIP now selects a new address after rate limit timeout, AutoIP tries a new address by incrementing the tried_llipaddr counter in the ACD_DECLINE case of the callback. In lwIP pre-2.2.0, address conflict detection was handled within autoip.c, and the incrementing happened in autoip_restart() (line 150). When ACD was extracted into a separate module in 2.2.0, this increment was missing for the rate-limiting path. Without this change, devices continuously retry the same IP address after rate limiting, causing them to fail Bonjour Conformance Tests. --- src/core/ipv4/autoip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ipv4/autoip.c b/src/core/ipv4/autoip.c index 461a0053..ea3f411c 100644 --- a/src/core/ipv4/autoip.c +++ b/src/core/ipv4/autoip.c @@ -223,9 +223,10 @@ autoip_conflict_callback(struct netif *netif, acd_callback_enum_t state) autoip_restart(netif); break; case ACD_DECLINE: - /* "delete" conflicting address so a new one will be selected in - * autoip_start() */ + /* "delete" conflicting address and increment tried addr so a new one + * will be selected in autoip_start() */ ip4_addr_set_any(&autoip->llipaddr); + autoip->tried_llipaddr++; autoip_stop(netif); break; default: From 41a36098b39241d4a14d3c7f781ad91aad3ff3e7 Mon Sep 17 00:00:00 2001 From: Sergey Fionov Date: Wed, 13 Mar 2024 22:16:35 +0200 Subject: [PATCH 15/16] tcp: Fix TCP timestamps for big-endian systems Current parsing code is building reverse-order integer, and then calls htonl() to assign right value to "ts_recent" field of pcb. This works correctly on little-endian machines, where htonl() reverses bytes. However, on big-endian machines, htonl() is no-op, so bytes stay reversed. This patch fixes it by building non-reversed integer. --- src/core/tcp_in.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 1b17e40f..37c6bb61 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -1993,17 +1993,17 @@ tcp_parseopt(struct tcp_pcb *pcb) return; } /* TCP timestamp option with valid length */ - tsval = tcp_get_next_optbyte(); - tsval |= (tcp_get_next_optbyte() << 8); + tsval = (tcp_get_next_optbyte() << 24); tsval |= (tcp_get_next_optbyte() << 16); - tsval |= (tcp_get_next_optbyte() << 24); + tsval |= (tcp_get_next_optbyte() << 8); + tsval |= tcp_get_next_optbyte(); if (flags & TCP_SYN) { - pcb->ts_recent = lwip_ntohl(tsval); + pcb->ts_recent = tsval; /* Enable sending timestamps in every segment now that we know the remote host supports it. */ tcp_set_flags(pcb, TF_TIMESTAMP); } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) { - pcb->ts_recent = lwip_ntohl(tsval); + pcb->ts_recent = tsval; } /* Advance to next option (6 bytes already read) */ tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6; From 4599f551dead9eac233b91c0b9ee5879f5d0620a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 9 Jun 2025 08:44:23 +0200 Subject: [PATCH 16/16] dhcp: Clear flags Do not assume that mem_malloc() returns cleared memory. --- src/core/ipv4/dhcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index c149dd12..5c401368 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -831,6 +831,8 @@ dhcp_start(struct netif *netif) return ERR_MEM; } + /* clear the flags, the rest is cleared below */ + dhcp->flags = 0; /* store this dhcp client in the netif */ netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp\n"));