Skip to content

Commit df2bf56

Browse files
committed
feat: add rfc-compliant syn with payload handling
1 parent 4599f55 commit df2bf56

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/core/tcp_in.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,17 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
678678
npcb->local_port = pcb->local_port;
679679
npcb->remote_port = tcphdr->src;
680680
npcb->state = SYN_RCVD;
681+
#if SYN_WITH_PAYLOAD_ENABLED
682+
/* RFC Compliance: Account for both SYN flag and any payload in the SYN packet.
683+
* Some implementations send data with SYN (SYN+data), and the ACK number must
684+
* correctly reflect seqno + 1 (for SYN) + payload_length to comply with RFC.
685+
* This ensures proper interoperability and passes robustness testing tools. */
686+
npcb->rcv_nxt = seqno + tcplen;
687+
#else
688+
/* Standard behavior: Only account for SYN flag, ignore any payload.
689+
* This is the traditional lwIP behavior - SYN payload is discarded. */
681690
npcb->rcv_nxt = seqno + 1;
691+
#endif
682692
npcb->rcv_ann_right_edge = npcb->rcv_nxt;
683693
iss = tcp_next_iss(npcb);
684694
npcb->snd_wl2 = iss;
@@ -838,7 +848,9 @@ tcp_process(struct tcp_pcb *pcb)
838848
}
839849

840850
if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
841-
/* Cope with new connection attempt after remote end crashed */
851+
/* Cope with new connection attempt after remote end crashed.
852+
* NOTE: We don't process SYN payload here - this is an unexpected SYN
853+
* on an already established connection, so we just ACK it and continue. */
842854
tcp_ack_now(pcb);
843855
return ERR_OK;
844856
}

src/include/lwip/opt.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,27 @@
13131313
#define TCP_SYNMAXRTX 6
13141314
#endif
13151315

1316+
/**
1317+
* SYN_WITH_PAYLOAD_ENABLED: Handle SYN packets with payload according to RFC standards.
1318+
*
1319+
* RFC Compliance: When enabled (set to 1), lwIP correctly processes SYN packets that
1320+
* contain payload data by setting rcv_nxt to account for both the SYN flag and the
1321+
* payload length. According to TCP RFC specifications, the ACK number should reflect
1322+
* the sequence number incremented by the size of the received payload, even in the
1323+
* rare case of a SYN packet carrying data.
1324+
*
1325+
* By default (disabled), lwIP ignores payload in SYN packets and responds with ACK=1,
1326+
* which may not comply with strict RFC interpretations. Some robustness testing tools
1327+
* and security scanners specifically check for this behavior to validate TCP stack
1328+
* correctness.
1329+
*
1330+
* Enable this for improved RFC compliance and interoperability with testing tools.
1331+
* Default is 0 (disabled for backward compatibility and typical usage).
1332+
*/
1333+
#if !defined SYN_WITH_PAYLOAD_ENABLED || defined __DOXYGEN__
1334+
#define SYN_WITH_PAYLOAD_ENABLED 0
1335+
#endif
1336+
13161337
/**
13171338
* TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
13181339
* Define to 0 if your device is low on memory.

0 commit comments

Comments
 (0)