mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +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);
|
conn = tcp_active(dev, tcp);
|
||||||
if (conn)
|
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
|
* arriving in TCP_SYN_RCVD state after the SYNACK packet was
|
||||||
* lost. To avoid other issues, reset any active connection
|
* lost.
|
||||||
* where a SYN arrives in a state != TCP_SYN_RCVD.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD &&
|
if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD &&
|
||||||
|
|||||||
Reference in New Issue
Block a user