mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 21:34:07 +08:00
net/tcp: support OTW SEQ number check except SYN-SEND state
According rfc793 p69, from state SYN-RECEIVED to state TIME-WAIT, if the incoming segment is not acceptable, an acknowledgment should be sent in reply (unless the RST bit is set): <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK> Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
This commit is contained in:
+42
-3
@@ -744,10 +744,49 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
|
||||
conn = tcp_active(dev, tcp);
|
||||
if (conn)
|
||||
{
|
||||
/* We found an active connection.. Check for the subsequent SYN
|
||||
/* RFC793, 1) page 37 Reset Processing: "In all states except
|
||||
* SYN-SENT, all reset (RST) segments are validated by checking
|
||||
* their SEQ-fields."
|
||||
* 2) page 69 In all states except SYN-SENT: "If an incoming
|
||||
* segment is not acceptable, an acknowledgment should be sent
|
||||
* in reply (unless the RST bit is set, if so drop the segment
|
||||
* and return)".
|
||||
*/
|
||||
|
||||
if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_SENT &&
|
||||
((conn->tcpstateflags & TCP_STATE_MASK) >= TCP_SYN_RCVD &&
|
||||
(conn->tcpstateflags & TCP_STATE_MASK) <= TCP_LAST_ACK))
|
||||
{
|
||||
uint32_t seq;
|
||||
uint32_t rcvseq;
|
||||
uint32_t endseq;
|
||||
|
||||
seq = tcp_getsequence(tcp->seqno);
|
||||
rcvseq = tcp_getsequence(conn->rcvseq);
|
||||
endseq = seq + dev->d_len - iplen - ((tcp->tcpoffset >> 4) << 2);
|
||||
if ((tcp->flags & (TCP_SYN | TCP_FIN)) != 0)
|
||||
{
|
||||
endseq += 1;
|
||||
}
|
||||
|
||||
if (TCP_SEQ_LT(endseq, rcvseq) || TCP_SEQ_GT(seq, conn->rcv_adv))
|
||||
{
|
||||
if ((tcp->flags & TCP_RST) == 0)
|
||||
{
|
||||
tcp_send(dev, conn, TCP_ACK, tcpiplen);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC793,p71 In all states except SYN-SENT: "If the SYN is in the
|
||||
* window it is an error, send a reset", except the subsequent SYN
|
||||
* arriving in TCP_SYN_RCVD state after the SYNACK packet was
|
||||
* lost. To avoid other issues, reset any active connection
|
||||
* where a SYN arrives in a state != TCP_SYN_RCVD.
|
||||
* lost.
|
||||
*/
|
||||
|
||||
if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD &&
|
||||
|
||||
Reference in New Issue
Block a user