From 7827ec59c29761dc0157d7277b727e01e36087d3 Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 13:21:38 +0100 Subject: [PATCH 1/9] ignore when the timestamp is supposedly in the future, so greater than the current tick --- src/wolfip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wolfip.c b/src/wolfip.c index 9fcfdb2..17e78da 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1815,6 +1815,8 @@ static int tcp_process_ts(struct tsocket *t, const struct wolfIP_tcp_seg *tcp, t->sock.tcp.last_ts = ts->val; if (ts->ecr == 0) return -1; /* No echoed timestamp; fall back to coarse RTT. */ + if (ee32(ts->ecr) > t->S->last_tick) + return -1; /* Echoed timestamp in the future; ignore. */ if (t->sock.tcp.rtt == 0) t->sock.tcp.rtt = (uint32_t)(t->S->last_tick - ee32(ts->ecr)); else { From 56d7f5591ac64641ff7e18255368d39b9ec26d81 Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 13:34:40 +0100 Subject: [PATCH 2/9] change time_sebnt from uint16_t to uint32_t to prevent causation when assigning now (whichi is uint64_t) --- src/wolfip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wolfip.c b/src/wolfip.c index 17e78da..2f83b6d 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -123,7 +123,8 @@ struct wolfIP_icmp_packet; struct PACKED pkt_desc { uint32_t pos, len; - uint16_t flags, time_sent; + uint16_t flags; + uint32_t time_sent; }; struct fifo { From 3ba89e565822f0449d9880c146ed8ae416e2f39a Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 14:08:53 +0100 Subject: [PATCH 3/9] proper unsigned and signed wrapping handling in tcp_seq_leq --- src/wolfip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wolfip.c b/src/wolfip.c index 2f83b6d..0257045 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1848,7 +1848,10 @@ static inline uint32_t tcp_seq_inc(uint32_t seq, uint32_t n) */ static inline int tcp_seq_leq(uint32_t a, uint32_t b) { - return ((int32_t)a - (int32_t)b) <= 0; + if (a <= b) + return (b - a) <= 0x80000000U; + else + return (a - b) >= 0x80000000U; } /* Receive an ack */ From e2abc674ec703c3bcb249878bc52df8c2e7e6c06 Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 14:31:22 +0100 Subject: [PATCH 4/9] guarding delta calculation to prevent underflow when wrapping --- src/wolfip.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wolfip.c b/src/wolfip.c index 0257045..4a2d2b2 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1892,7 +1892,11 @@ static void tcp_ack(struct tsocket *t, const struct wolfIP_tcp_seg *tcp) if (t->sock.tcp.snd_una != ack && tcp_seq_leq(t->sock.tcp.snd_una, ack) && tcp_seq_leq(ack, t->sock.tcp.seq)) { - uint32_t delta = ack - t->sock.tcp.snd_una; + uint32_t delta; + if (ack >= t->sock.tcp.snd_una) + delta = ack - t->sock.tcp.snd_una; + else + delta = ack + (UINT32_MAX - t->sock.tcp.snd_una) + 1; if (delta >= t->sock.tcp.bytes_in_flight) t->sock.tcp.bytes_in_flight = 0; else From 212562772ad5a3a07ec24e270f92c94fa2e4e8cd Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 14:49:36 +0100 Subject: [PATCH 5/9] ++ operator on ipcounter promotes to int, then implicitlyy truncates back, made the wrapping explicit --- src/wolfip.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wolfip.c b/src/wolfip.c index 4a2d2b2..3e35247 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1142,7 +1142,8 @@ static void wolfIP_send_ttl_exceeded(struct wolfIP *s, unsigned int if_idx, stru icmp.ip.ver_ihl = 0x45; icmp.ip.ttl = 64; icmp.ip.proto = WI_IPPROTO_ICMP; - icmp.ip.id = ee16(s->ipcounter++); + icmp.ip.id = ee16(s->ipcounter); + s->ipcounter = (uint16_t)(s->ipcounter + 1); icmp.ip.len = ee16(IP_HEADER_LEN + ICMP_TTL_EXCEEDED_SIZE); icmp.ip.src = ee32(wolfIP_ipconf_at(s, if_idx)->ip); icmp.ip.dst = orig->src; @@ -1743,7 +1744,8 @@ static int ip_output_add_header(struct tsocket *t, struct wolfIP_ip_packet *ip, ip->flags_fo = 0; ip->ttl = 64; ip->proto = proto; - ip->id = ee16(t->S->ipcounter++); + ip->id = ee16(t->S->ipcounter); + t->S->ipcounter = (uint16_t)(t->S->ipcounter + 1); ip->csum = 0; iphdr_set_checksum(ip); @@ -3111,7 +3113,8 @@ static void icmp_input(struct wolfIP *s, unsigned int if_idx, struct wolfIP_ip_p tmp = ip->src; ip->src = ip->dst; ip->dst = tmp; - ip->id = ee16(s->ipcounter++); + ip->id = ee16(s->ipcounter); + s->ipcounter = (uint16_t)(s->ipcounter + 1); ip->csum = 0; iphdr_set_checksum(ip); eth_output_add_header(s, if_idx, ip->eth.src, &ip->eth, ETH_TYPE_IP); From 2cb0b904dc636d5a5dd8da481c6f5dc500e44c98 Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 15:00:00 +0100 Subject: [PATCH 6/9] change flags to uint32_t restore the 4 byte alignment after pkt_desc was changed from 12 bytes to 14 bytes (2 byytes of alignment padding) --- src/wolfip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wolfip.c b/src/wolfip.c index 3e35247..a78894a 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -123,7 +123,7 @@ struct wolfIP_icmp_packet; struct PACKED pkt_desc { uint32_t pos, len; - uint16_t flags; + uint32_t flags; uint32_t time_sent; }; From 14f524216e846133cef377d6bd5254bc366f3c12 Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 15:10:11 +0100 Subject: [PATCH 7/9] - shift and multiply in uint64_t to prevent ovverride when rtt is large - same fix + guard against last_tick < time_sent --- src/wolfip.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/wolfip.c b/src/wolfip.c index a78894a..cd71e62 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1823,8 +1823,9 @@ static int tcp_process_ts(struct tsocket *t, const struct wolfIP_tcp_seg *tcp, if (t->sock.tcp.rtt == 0) t->sock.tcp.rtt = (uint32_t)(t->S->last_tick - ee32(ts->ecr)); else { - t->sock.tcp.rtt = (uint32_t)(7 * (t->sock.tcp.rtt << 3)) + - ((t->S->last_tick - ee32(ts->ecr)) << 3); + uint64_t rtt_scaled = (uint64_t)t->sock.tcp.rtt << 3; + uint64_t sample_scaled = (t->S->last_tick - ee32(ts->ecr)) << 3; + t->sock.tcp.rtt = (uint32_t)(7 * rtt_scaled + sample_scaled); } return 0; } else { @@ -1921,11 +1922,14 @@ static void tcp_ack(struct tsocket *t, const struct wolfIP_tcp_seg *tcp) /* Update rtt */ if (tcp_process_ts(t, seg, fresh_desc->len) < 0) { /* No timestamp option, use coarse RTT estimation */ - int rtt = t->S->last_tick - fresh_desc->time_sent; - if (t->sock.tcp.rtt == 0) { - t->sock.tcp.rtt = rtt; - } else { - t->sock.tcp.rtt = (7 * (t->sock.tcp.rtt << 3)) + (rtt << 3); + if (t->S->last_tick >= fresh_desc->time_sent) { + uint32_t rtt = (uint32_t)(t->S->last_tick - fresh_desc->time_sent); + if (t->sock.tcp.rtt == 0) { + t->sock.tcp.rtt = rtt; + } else { + uint64_t rtt_scaled = (uint64_t)t->sock.tcp.rtt << 3; + t->sock.tcp.rtt = (uint32_t)(7 * rtt_scaled + ((uint64_t)rtt << 3)); + } } } /* Update cwnd only if we were cwnd-limited. */ From c1fe5b1c4c21dbd3accad2979f2dc17b6f5efd83 Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Tue, 10 Feb 2026 15:52:49 +0100 Subject: [PATCH 8/9] use tcp_seq_inc to handle wrapping when adding seq + seg_len --- src/wolfip.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wolfip.c b/src/wolfip.c index cd71e62..86c7d2b 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1560,6 +1560,14 @@ static void tcp_send_syn(struct tsocket *t, uint8_t flags) fifo_push(&t->sock.tcp.txbuf, tcp, sizeof(struct wolfIP_tcp_seg) + opt_len); } +/* Increment a TCP sequence number (wraps at 2^32) */ +static inline uint32_t tcp_seq_inc(uint32_t seq, uint32_t n) +{ + if (n > UINT32_MAX - seq) + return n - (UINT32_MAX - seq) - 1; + return seq + n; +} + /* Add a segment to the rx buffer for the application to consume */ static void tcp_recv(struct tsocket *t, struct wolfIP_tcp_seg *seg) { @@ -1575,7 +1583,7 @@ static void tcp_recv(struct tsocket *t, struct wolfIP_tcp_seg *seg) /* Buffer full, dropped. This will send a duplicate ack. */ } else { /* Advance ack counter */ - t->sock.tcp.ack = seq + seg_len; + t->sock.tcp.ack = tcp_seq_inc(seq, seg_len); timer_binheap_cancel(&t->S->timers, t->sock.tcp.tmr_rto); t->sock.tcp.tmr_rto = NO_TIMER; t->events |= CB_EVENT_READABLE; @@ -1836,14 +1844,6 @@ static int tcp_process_ts(struct tsocket *t, const struct wolfIP_tcp_seg *tcp, return -1; } -/* Increment a TCP sequence number (wraps at 2^32) */ -static inline uint32_t tcp_seq_inc(uint32_t seq, uint32_t n) -{ - if (n > UINT32_MAX - seq) - return n - (UINT32_MAX - seq) - 1; - return seq + n; -} - #define SEQ_DIFF(a,b) ((a - b) > 0x7FFFFFFF) ? (b - a) : (a - b) /* Return true if a <= b From 652a899a9e643a62b97bc3b7a5f329d785529c9c Mon Sep 17 00:00:00 2001 From: Reda Chouk Date: Wed, 11 Feb 2026 13:11:12 +0100 Subject: [PATCH 9/9] add ipcounter_next, updated call site to reference it --- src/wolfip.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/wolfip.c b/src/wolfip.c index 86c7d2b..18cd706 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -956,6 +956,13 @@ static inline struct ipconf *wolfIP_primary_ipconf(struct wolfIP *s) return wolfIP_ipconf_at(s, WOLFIP_PRIMARY_IF_IDX); } +static inline uint16_t ipcounter_next(struct wolfIP *s) +{ + uint16_t id = s->ipcounter; + s->ipcounter = (uint16_t)(id + 1); + return ee16(id); +} + static inline int ip_is_local_conf(const struct ipconf *conf, ip4 addr) { if (!conf) @@ -1142,8 +1149,7 @@ static void wolfIP_send_ttl_exceeded(struct wolfIP *s, unsigned int if_idx, stru icmp.ip.ver_ihl = 0x45; icmp.ip.ttl = 64; icmp.ip.proto = WI_IPPROTO_ICMP; - icmp.ip.id = ee16(s->ipcounter); - s->ipcounter = (uint16_t)(s->ipcounter + 1); + icmp.ip.id = ipcounter_next(s); icmp.ip.len = ee16(IP_HEADER_LEN + ICMP_TTL_EXCEEDED_SIZE); icmp.ip.src = ee32(wolfIP_ipconf_at(s, if_idx)->ip); icmp.ip.dst = orig->src; @@ -3117,8 +3123,7 @@ static void icmp_input(struct wolfIP *s, unsigned int if_idx, struct wolfIP_ip_p tmp = ip->src; ip->src = ip->dst; ip->dst = tmp; - ip->id = ee16(s->ipcounter); - s->ipcounter = (uint16_t)(s->ipcounter + 1); + ip->id = ipcounter_next(s); ip->csum = 0; iphdr_set_checksum(ip); eth_output_add_header(s, if_idx, ip->eth.src, &ip->eth, ETH_TYPE_IP);