You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2020/12/09 05:01:27 UTC

[incubator-nuttx] 01/02: net/tcp/tcp_input.c: Correct bad check of urgent data length

This is an automated email from the ASF dual-hosted git repository.

btashton pushed a commit to branch releases/10.0
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 2fd1d8c8f1cc8803694b57fdf4ded4767960e528
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Sun Nov 29 23:16:12 2020 -0800

    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.
---
 net/tcp/tcp_input.c | 49 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c
index 09fee45..14f3a8e 100644
--- a/net/tcp/tcp_input.c
+++ b/net/tcp/tcp_input.c
@@ -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,13 +826,40 @@ 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 */
+        /* 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