You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/18 08:24:18 UTC
[nuttx] 03/04: net/tcp: parse tcp options in common function
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit c581cc5f9b8c3bbd622895f3eff4e6a7f1342774
Author: chao an <an...@xiaomi.com>
AuthorDate: Mon Jan 9 19:44:23 2023 +0800
net/tcp: parse tcp options in common function
Signed-off-by: chao an <an...@xiaomi.com>
---
net/tcp/tcp_input.c | 212 ++++++++++++++++++++++++----------------------------
1 file changed, 96 insertions(+), 116 deletions(-)
diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c
index 552f6b1d37..b4b7b05292 100644
--- a/net/tcp/tcp_input.c
+++ b/net/tcp/tcp_input.c
@@ -564,6 +564,100 @@ clear:
}
#endif /* CONFIG_NET_TCP_OUT_OF_ORDER */
+/****************************************************************************
+ * Name: tcp_parse_option
+ *
+ * Description:
+ * Parse incoming TCP options
+ *
+ * Input Parameters:
+ * dev - The device driver structure containing the received TCP packet.
+ * conn - The TCP connection of interest
+ * iplen - Length of the IP header (IPv4_HDRLEN or IPv6_HDRLEN).
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * The network is locked.
+ *
+ ****************************************************************************/
+
+static void tcp_parse_option(FAR struct net_driver_s *dev,
+ FAR struct tcp_conn_s *conn,
+ unsigned int iplen)
+{
+ FAR struct tcp_hdr_s *tcp;
+ unsigned int tcpiplen;
+ uint16_t tmp16;
+ uint8_t opt;
+ int i;
+
+ tcp = IPBUF(iplen);
+
+ if ((tcp->tcpoffset & 0xf0) <= 0x50)
+ {
+ return;
+ }
+
+ tcpiplen = iplen + TCP_HDRLEN;
+
+ for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ; )
+ {
+ opt = IPDATA(tcpiplen + i);
+ if (opt == TCP_OPT_END)
+ {
+ /* End of options. */
+
+ break;
+ }
+ else if (opt == TCP_OPT_NOOP)
+ {
+ /* NOP option. */
+
+ ++i;
+ continue;
+ }
+ else if (opt == TCP_OPT_MSS &&
+ IPDATA(tcpiplen + 1 + i) == TCP_OPT_MSS_LEN)
+ {
+ uint16_t tcp_mss = TCP_MSS(dev, iplen);
+
+ /* An MSS option with the right option length. */
+
+ tmp16 = ((uint16_t)IPDATA(tcpiplen + 2 + i) << 8) |
+ (uint16_t)IPDATA(tcpiplen + 3 + i);
+ conn->mss = tmp16 > tcp_mss ? tcp_mss : tmp16;
+ }
+#ifdef CONFIG_NET_TCP_WINDOW_SCALE
+ else if (opt == TCP_OPT_WS &&
+ IPDATA(tcpiplen + 1 + i) == TCP_OPT_WS_LEN)
+ {
+ conn->snd_scale = IPDATA(tcpiplen + 2 + i);
+ conn->rcv_scale = CONFIG_NET_TCP_WINDOW_SCALE_FACTOR;
+ conn->flags |= TCP_WSCALE;
+ }
+#endif
+ else
+ {
+ /* All other options have a length field, so that we
+ * easily can skip past them.
+ */
+
+ if (IPDATA(tcpiplen + 1 + i) == 0)
+ {
+ /* If the length field is zero, the options are
+ * malformed and we don't process them further.
+ */
+
+ break;
+ }
+ }
+
+ i += IPDATA(tcpiplen + 1 + i);
+ }
+}
+
/****************************************************************************
* Name: tcp_input
*
@@ -593,9 +687,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
uint16_t tmp16;
uint16_t flags;
uint16_t result;
- uint8_t opt;
int len;
- int i;
#ifdef CONFIG_NET_STATISTICS
/* Bump up the count of TCP packets received */
@@ -748,63 +840,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
/* Parse the TCP MSS option, if present. */
- if ((tcp->tcpoffset & 0xf0) > 0x50)
- {
- for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ; )
- {
- opt = IPDATA(tcpiplen + i);
- if (opt == TCP_OPT_END)
- {
- /* End of options. */
-
- break;
- }
- else if (opt == TCP_OPT_NOOP)
- {
- /* NOP option. */
-
- ++i;
- continue;
- }
- else if (opt == TCP_OPT_MSS &&
- IPDATA(tcpiplen + 1 + i) == TCP_OPT_MSS_LEN)
- {
- uint16_t tcp_mss = TCP_MSS(dev, iplen);
-
- /* An MSS option with the right option length. */
-
- tmp16 = ((uint16_t)IPDATA(tcpiplen + 2 + i) << 8) |
- (uint16_t)IPDATA(tcpiplen + 3 + i);
- conn->mss = tmp16 > tcp_mss ? tcp_mss : tmp16;
- }
-#ifdef CONFIG_NET_TCP_WINDOW_SCALE
- else if (opt == TCP_OPT_WS &&
- IPDATA(tcpiplen + 1 + i) == TCP_OPT_WS_LEN)
- {
- conn->snd_scale = IPDATA(tcpiplen + 2 + i);
- conn->rcv_scale = CONFIG_NET_TCP_WINDOW_SCALE_FACTOR;
- conn->flags |= TCP_WSCALE;
- }
-#endif
- else
- {
- /* All other options have a length field, so that we
- * easily can skip past them.
- */
-
- if (IPDATA(tcpiplen + 1 + i) == 0)
- {
- /* If the length field is zero, the options are
- * malformed and we don't process them further.
- */
-
- break;
- }
- }
-
- i += IPDATA(tcpiplen + 1 + i);
- }
- }
+ tcp_parse_option(dev, conn, iplen);
/* Our response will be a SYNACK. */
@@ -1245,63 +1281,7 @@ found:
{
/* Parse the TCP MSS option, if present. */
- if ((tcp->tcpoffset & 0xf0) > 0x50)
- {
- for (i = 0; i < ((tcp->tcpoffset >> 4) - 5) << 2 ; )
- {
- opt = IPDATA(tcpiplen + i);
- if (opt == TCP_OPT_END)
- {
- /* End of options. */
-
- break;
- }
- else if (opt == TCP_OPT_NOOP)
- {
- /* NOP option. */
-
- ++i;
- continue;
- }
- else if (opt == TCP_OPT_MSS &&
- IPDATA(tcpiplen + 1 + i) == TCP_OPT_MSS_LEN)
- {
- uint16_t tcp_mss = TCP_MSS(dev, iplen);
-
- /* An MSS option with the right option length. */
-
- tmp16 = (IPDATA(tcpiplen + 2 + i) << 8) |
- IPDATA(tcpiplen + 3 + i);
- conn->mss = tmp16 > tcp_mss ? tcp_mss : tmp16;
- }
-#ifdef CONFIG_NET_TCP_WINDOW_SCALE
- else if (opt == TCP_OPT_WS &&
- IPDATA(tcpiplen + 1 + i) == TCP_OPT_WS_LEN)
- {
- conn->snd_scale = IPDATA(tcpiplen + 2 + i);
- conn->rcv_scale = CONFIG_NET_TCP_WINDOW_SCALE_FACTOR;
- conn->flags |= TCP_WSCALE;
- }
-#endif
- else
- {
- /* All other options have a length field, so that we
- * easily can skip past them.
- */
-
- if (IPDATA(tcpiplen + 1 + i) == 0)
- {
- /* If the length field is zero, the options are
- * malformed and we don't process them further.
- */
-
- break;
- }
- }
-
- i += IPDATA(tcpiplen + 1 + i);
- }
- }
+ tcp_parse_option(dev, conn, iplen);
conn->tcpstateflags = TCP_ESTABLISHED;
memcpy(conn->rcvseq, tcp->seqno, 4);