mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 01:38:36 +08:00
net/tcp/tcp_input.c: Correct bad check of urgent data length
Urgent data preceded "normal" data in the TCP payload. If the urgent data is larger than the size of the TCP payload, this indicates that the entire payload is urgent data and that urgent data continues in the next packet. This case was handled correctly for the case where urgent data was present but was not being handled correctly in the case where the urgent data was NOT present.
This commit is contained in:
parent
e4e4cce696
commit
b34096a4fa
1 changed files with 44 additions and 7 deletions
|
@ -794,13 +794,13 @@ found:
|
|||
return;
|
||||
}
|
||||
|
||||
/* Check the URG flag. If this is set, the segment carries urgent
|
||||
#ifdef CONFIG_NET_TCPURGDATA
|
||||
/* Check the URG flag. If this is set, the segment carries urgent
|
||||
* data that we must pass to the application.
|
||||
*/
|
||||
|
||||
if ((tcp->flags & TCP_URG) != 0)
|
||||
{
|
||||
#ifdef CONFIG_NET_TCPURGDATA
|
||||
dev->d_urglen = (tcp->urgp[0] << 8) | tcp->urgp[1];
|
||||
if (dev->d_urglen > dev->d_len)
|
||||
{
|
||||
|
@ -809,6 +809,16 @@ found:
|
|||
dev->d_urglen = dev->d_len;
|
||||
}
|
||||
|
||||
/* The d_len field contains the length of the incoming data.
|
||||
* d_urgdata points to the "urgent" data at the beginning of
|
||||
* the payload; d_appdata field points to the any "normal" data
|
||||
* that may follow the urgent data.
|
||||
*
|
||||
* NOTE: If the urgent data continues in the next packet, then
|
||||
* d_len will be zero and d_appdata will point past the end of
|
||||
* the payload (which is OK).
|
||||
*/
|
||||
|
||||
net_incr32(conn->rcvseq, dev->d_urglen);
|
||||
dev->d_len -= dev->d_urglen;
|
||||
dev->d_urgdata = dev->d_appdata;
|
||||
|
@ -816,14 +826,41 @@ found:
|
|||
}
|
||||
else
|
||||
{
|
||||
/* No urgent data */
|
||||
|
||||
dev->d_urglen = 0;
|
||||
#else /* CONFIG_NET_TCPURGDATA */
|
||||
dev->d_appdata = ((FAR uint8_t *)dev->d_appdata) +
|
||||
((tcp->urgp[0] << 8) | tcp->urgp[1]);
|
||||
dev->d_len -= (tcp->urgp[0] << 8) | tcp->urgp[1];
|
||||
#endif /* CONFIG_NET_TCPURGDATA */
|
||||
}
|
||||
|
||||
#else /* CONFIG_NET_TCPURGDATA */
|
||||
/* Check the URG flag. If this is set, We must gracefully ignore
|
||||
* and discard the urgent data.
|
||||
*/
|
||||
|
||||
if ((tcp->flags & TCP_URG) != 0)
|
||||
{
|
||||
uint16_t urglen = (tcp->urgp[0] << 8) | tcp->urgp[1];
|
||||
if (urglen > dev->d_len)
|
||||
{
|
||||
/* There is more urgent data in the next segment to come. */
|
||||
|
||||
urglen = dev->d_len;
|
||||
}
|
||||
|
||||
/* The d_len field contains the length of the incoming data;
|
||||
* The d_appdata field points to the any "normal" data that
|
||||
* may follow the urgent data.
|
||||
*
|
||||
* NOTE: If the urgent data continues in the next packet, then
|
||||
* d_len will be zero and d_appdata will point past the end of
|
||||
* the payload (which is OK).
|
||||
*/
|
||||
|
||||
net_incr32(conn->rcvseq, urglen);
|
||||
dev->d_len -= urglen;
|
||||
dev->d_appdata += urglen;
|
||||
}
|
||||
#endif /* CONFIG_NET_TCPURGDATA */
|
||||
|
||||
#ifdef CONFIG_NET_TCP_KEEPALIVE
|
||||
/* If the established socket receives an ACK or any kind of data
|
||||
* from the remote peer (whether we accept it or not), then reset
|
||||
|
|
Loading…
Reference in a new issue