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 */