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 2022/11/11 06:37:03 UTC

[incubator-nuttx] 02/07: net: verify NAT port usage in tcp_selectport

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/incubator-nuttx.git

commit 0a4e01d7123085e901b3f9067833f3094c885c76
Author: Zhe Weng <we...@xiaomi.com>
AuthorDate: Wed Oct 26 14:31:04 2022 +0800

    net: verify NAT port usage in tcp_selectport
    
    Signed-off-by: Zhe Weng <we...@xiaomi.com>
---
 net/nat/ipv4_nat.c       | 30 ++++++++++++++++++++++++++++++
 net/nat/ipv4_nat_entry.c |  1 -
 net/nat/nat.h            | 19 +++++++++++++++++++
 net/tcp/tcp_conn.c       | 15 +++++++++++++--
 4 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/net/nat/ipv4_nat.c b/net/nat/ipv4_nat.c
index f1d44155fc..8b0811e52e 100644
--- a/net/nat/ipv4_nat.c
+++ b/net/nat/ipv4_nat.c
@@ -321,4 +321,34 @@ int ipv4_nat_outbound(FAR struct net_driver_s *dev,
   return OK;
 }
 
+/****************************************************************************
+ * Name: ipv4_nat_port_inuse
+ *
+ * Description:
+ *   Check whether a port is currently used by NAT.
+ *
+ * Input Parameters:
+ *   protocol      - The L4 protocol of the packet.
+ *   ip            - The IP bind with the port (in network byte order).
+ *   port          - The port number to check (in network byte order).
+ *
+ * Returned Value:
+ *   True if the port is already used by NAT, otherwise false.
+ *
+ ****************************************************************************/
+
+bool ipv4_nat_port_inuse(uint8_t protocol, in_addr_t ip, uint16_t port)
+{
+  FAR struct ipv4_nat_entry *entry =
+      ipv4_nat_inbound_entry_find(protocol, port);
+
+  /* Not checking ip is enough for single NAT device, may save external_ip in
+   * entry for multiple device support in future.
+   */
+
+  UNUSED(ip);
+
+  return entry != NULL;
+}
+
 #endif /* CONFIG_NET_NAT && CONFIG_NET_IPv4 */
diff --git a/net/nat/ipv4_nat_entry.c b/net/nat/ipv4_nat_entry.c
index e0f7e92513..4a57549355 100644
--- a/net/nat/ipv4_nat_entry.c
+++ b/net/nat/ipv4_nat_entry.c
@@ -62,7 +62,6 @@ static uint16_t ipv4_nat_select_port(uint8_t protocol, uint16_t local_port)
 {
   /* TODO: Implement this, need to consider local ports and nat ports.
    * TODO: Shall we let the chosen port same as local_port if possible?
-   * TODO: Also need to modify local port number assignment.
    */
 
 # warning Missing logic
diff --git a/net/nat/nat.h b/net/nat/nat.h
index c5b13e5a3e..e5df4db633 100644
--- a/net/nat/nat.h
+++ b/net/nat/nat.h
@@ -27,6 +27,7 @@
 
 #include <nuttx/config.h>
 
+#include <stdbool.h>
 #include <stdint.h>
 
 #include <netinet/in.h>
@@ -156,6 +157,24 @@ int ipv4_nat_inbound(FAR struct net_driver_s *dev,
 int ipv4_nat_outbound(FAR struct net_driver_s *dev,
                       FAR struct ipv4_hdr_s *ipv4);
 
+/****************************************************************************
+ * Name: ipv4_nat_port_inuse
+ *
+ * Description:
+ *   Check whether a port is currently used by NAT.
+ *
+ * Input Parameters:
+ *   protocol      - The L4 protocol of the packet.
+ *   ip            - The IP bind with the port (in network byte order).
+ *   port          - The port number to check (in network byte order).
+ *
+ * Returned Value:
+ *   True if the port is already used by NAT, otherwise false.
+ *
+ ****************************************************************************/
+
+bool ipv4_nat_port_inuse(uint8_t protocol, in_addr_t ip, uint16_t port);
+
 /****************************************************************************
  * Name: ipv4_nat_inbound_entry_find
  *
diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c
index 28c23998b9..a4719cec59 100644
--- a/net/tcp/tcp_conn.c
+++ b/net/tcp/tcp_conn.c
@@ -68,6 +68,7 @@
 #include "tcp/tcp.h"
 #include "arp/arp.h"
 #include "icmpv6/icmpv6.h"
+#include "nat/nat.h"
 
 /****************************************************************************
  * Private Data
@@ -244,7 +245,12 @@ static int tcp_selectport(uint8_t domain,
 
           portno = HTONS(g_last_tcp_port);
         }
-      while (tcp_listener(domain, ipaddr, portno));
+      while (tcp_listener(domain, ipaddr, portno)
+#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4)
+             || (domain == PF_INET &&
+                 ipv4_nat_port_inuse(IP_PROTO_TCP, ipaddr->ipv4, portno))
+#endif
+      );
     }
   else
     {
@@ -252,7 +258,12 @@ static int tcp_selectport(uint8_t domain,
        * connection is using this local port.
        */
 
-      if (tcp_listener(domain, ipaddr, portno))
+      if (tcp_listener(domain, ipaddr, portno)
+#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4)
+          || (domain == PF_INET &&
+              ipv4_nat_port_inuse(IP_PROTO_TCP, ipaddr->ipv4, portno))
+#endif
+      )
         {
           /* It is in use... return EADDRINUSE */