Skip to content
Open
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
17 changes: 17 additions & 0 deletions src/core/tcp_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,17 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
npcb->local_port = pcb->local_port;
npcb->remote_port = tcphdr->src;
npcb->state = SYN_RCVD;
#if SYN_WITH_PAYLOAD_ENABLED
/* RFC Compliance: Account for both SYN flag and any payload in the SYN packet.
* Some implementations send data with SYN (SYN+data), and the ACK number must
* correctly reflect seqno + 1 (for SYN) + payload_length to comply with RFC.
* This ensures proper interoperability and passes robustness testing tools. */
npcb->rcv_nxt = seqno + tcplen;
#else
/* Standard behavior: Only account for SYN flag, ignore any payload.
* This is the traditional lwIP behavior - SYN payload is discarded. */
npcb->rcv_nxt = seqno + 1;
#endif
npcb->rcv_ann_right_edge = npcb->rcv_nxt;
iss = tcp_next_iss(npcb);
npcb->snd_wl2 = iss;
Expand Down Expand Up @@ -838,6 +848,13 @@ tcp_process(struct tcp_pcb *pcb)
}

if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
#if SYN_WITH_PAYLOAD_ENABLED
/* RFC Compliance: Handle SYN with payload in unexpected states.
* Update rcv_nxt to account for SYN flag and any payload to maintain
* correct sequence tracking and generate proper ACK numbers.
* Note: Sequence nb could be the same becuase we don't intend a new seq nb */
pcb->rcv_nxt += tcplen;
#endif
/* Cope with new connection attempt after remote end crashed */
tcp_ack_now(pcb);
return ERR_OK;
Expand Down
21 changes: 21 additions & 0 deletions src/include/lwip/opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,27 @@
#define TCP_SYNMAXRTX 6
#endif

/**
* SYN_WITH_PAYLOAD_ENABLED: Handle SYN packets with payload according to RFC standards.
*
* RFC Compliance: When enabled (set to 1), lwIP correctly processes SYN packets that
* contain payload data by setting rcv_nxt to account for both the SYN flag and the
* payload length. According to TCP RFC specifications, the ACK number should reflect
* the sequence number incremented by the size of the received payload, even in the
* rare case of a SYN packet carrying data.
*
* By default (disabled), lwIP ignores payload in SYN packets and responds with ACK=1,
* which may not comply with strict RFC interpretations. Some robustness testing tools
* and security scanners specifically check for this behavior to validate TCP stack
* correctness.
*
* Enable this for improved RFC compliance and interoperability with testing tools.
* Default is 0 (disabled for backward compatibility and typical usage).
*/
#if !defined SYN_WITH_PAYLOAD_ENABLED || defined __DOXYGEN__
#define SYN_WITH_PAYLOAD_ENABLED 0
#endif

/**
* TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
* Define to 0 if your device is low on memory.
Expand Down