• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 68c1fe8794077eab032b542094608338947f3d4f Mon Sep 17 00:00:00 2001
2From: wuchangsheng <wuchangsheng2@huawei.com>
3Date: Thu, 6 Oct 2022 19:27:41 +0800
4Subject: [PATCH] fix tcp new port
5
6---
7 src/core/tcp.c         | 87 +++++++++++++++++++++++++++++-------------
8 src/include/reg_sock.h |  1 +
9 2 files changed, 61 insertions(+), 27 deletions(-)
10
11diff --git a/src/core/tcp.c b/src/core/tcp.c
12index b65ab33..436ef85 100644
13--- a/src/core/tcp.c
14+++ b/src/core/tcp.c
15@@ -202,13 +202,26 @@ PER_THREAD u8_t tcp_active_pcbs_changed;
16 /** Timer counter to handle calling slow-timer from tcp_tmr() */
17 static PER_THREAD u8_t tcp_timer;
18 static PER_THREAD u8_t tcp_timer_ctr;
19+#if USE_LIBOS
20+static u16_t tcp_new_port(struct tcp_pcb *pcb);
21+#else
22 static u16_t tcp_new_port(void);
23+#endif
24
25 static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb);
26 #if LWIP_TCP_PCB_NUM_EXT_ARGS
27 static void tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_args);
28 #endif
29
30+#if USE_LIBOS
31+static u8_t port_state[TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START + 1] = {0};
32+void release_port(u16_t port)
33+{
34+    if (port >= TCP_LOCAL_PORT_RANGE_START && port <= TCP_LOCAL_PORT_RANGE_END) {
35+        port_state[port - TCP_LOCAL_PORT_RANGE_START] = 0;
36+    }
37+}
38+#endif
39 /**
40  * Initialize this module.
41  */
42@@ -237,6 +250,7 @@ tcp_free(struct tcp_pcb *pcb)
43 {
44 #if USE_LIBOS
45   vdev_unreg_done(pcb);
46+  release_port(pcb->local_port);
47 #endif
48   LWIP_ASSERT("tcp_free: LISTEN", pcb->state != LISTEN);
49 #if LWIP_TCP_PCB_NUM_EXT_ARGS
50@@ -746,7 +760,11 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
51 #endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
52
53   if (port == 0) {
54+#if USE_LIBOS
55+    port = tcp_new_port(pcb);
56+#else
57     port = tcp_new_port();
58+#endif
59     if (port == 0) {
60       return ERR_BUF;
61     }
62@@ -1057,33 +1075,43 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
63  *
64  * @return a new (free) local TCP port number
65  */
66+#if USE_LIBOS
67+static u16_t
68+tcp_new_port(struct tcp_pcb *pcb)
69+#else
70 static u16_t
71 tcp_new_port(void)
72+#endif
73 {
74-  u8_t i;
75   u16_t n = 0;
76-  u16_t tmp_port;
77-  struct tcp_pcb *pcb;
78+  u16_t tmp_port = 0;
79
80   pthread_mutex_lock(&g_tcp_port_mutex);
81-again:
82-  tcp_port++;
83-  if (tcp_port == TCP_LOCAL_PORT_RANGE_END) {
84-    tcp_port = TCP_LOCAL_PORT_RANGE_START;
85-  }
86-  /* Check all PCB lists. */
87-  for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
88-    for (pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
89-      if (pcb->local_port == tcp_port) {
90-        n++;
91-        if (n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
92-          return 0;
93+  do {
94+      tcp_port++;
95+      if (tcp_port == TCP_LOCAL_PORT_RANGE_END) {
96+        tcp_port = TCP_LOCAL_PORT_RANGE_START;
97+      }
98+
99+      if (__atomic_load_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], __ATOMIC_ACQUIRE) == 0) {
100+#if USE_LIBOS
101+        if (port_in_stack_queue(pcb->remote_ip.addr, pcb->local_ip.addr, pcb->remote_port, tcp_port)) {
102+            tmp_port = tcp_port;
103+            __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE);
104+            break;
105         }
106-        goto again;
107+#else
108+        __atomic_store_n(&port_state[tcp_port - TCP_LOCAL_PORT_RANGE_START], 1, __ATOMIC_RELEASE);
109+        break;
110+#endif
111       }
112-    }
113-  }
114-  tmp_port = tcp_port;
115+
116+      n++;
117+      if (n > TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START) {
118+        break;
119+      }
120+  } while (tmp_port == 0);
121+
122   pthread_mutex_unlock(&g_tcp_port_mutex);
123
124   return tmp_port;
125@@ -1169,7 +1197,11 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
126
127   old_local_port = pcb->local_port;
128   if (pcb->local_port == 0) {
129+#if USE_LIBOS
130+    pcb->local_port = tcp_new_port(pcb);
131+#else
132     pcb->local_port = tcp_new_port();
133+#endif
134     if (pcb->local_port == 0) {
135       return ERR_BUF;
136     }
137@@ -1196,10 +1228,6 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
138 #endif /* SO_REUSE */
139   }
140
141-#if USE_LIBOS
142-  vdev_reg_done(REG_RING_TCP_CONNECT, pcb);
143-#endif
144-
145   iss = tcp_next_iss(pcb);
146   pcb->rcv_nxt = 0;
147   pcb->snd_nxt = iss;
148@@ -1227,6 +1255,10 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
149   /* Send a SYN together with the MSS option. */
150   ret = tcp_enqueue_flags(pcb, TCP_SYN);
151   if (ret == ERR_OK) {
152+#if USE_LIBOS
153+    vdev_reg_done(REG_RING_TCP_CONNECT, pcb);
154+#endif
155+
156     /* SYN segment was enqueued, changed the pcbs state now */
157     pcb->state = SYN_SENT;
158     if (old_local_port != 0) {
159@@ -2277,10 +2309,6 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
160   LWIP_ASSERT("tcp_pcb_remove: invalid pcb", pcb != NULL);
161   LWIP_ASSERT("tcp_pcb_remove: invalid pcblist", pcblist != NULL);
162
163-#if USE_LIBOS
164-  vdev_unreg_done(pcb);
165-#endif
166-
167   TCP_RMV(pcblist, pcb);
168
169   tcp_pcb_purge(pcb);
170@@ -2301,6 +2329,11 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
171 #endif /* TCP_QUEUE_OOSEQ */
172   }
173
174+#if USE_LIBOS
175+  vdev_unreg_done(pcb);
176+  release_port(pcb->local_port);
177+#endif
178+
179   pcb->state = CLOSED;
180   /* reset the local port to prevent the pcb from being 'bound' */
181   pcb->local_port = 0;
182diff --git a/src/include/reg_sock.h b/src/include/reg_sock.h
183index 76673da..e349e85 100644
184--- a/src/include/reg_sock.h
185+++ b/src/include/reg_sock.h
186@@ -58,5 +58,6 @@ struct reg_ring_msg {
187 };
188
189 extern int vdev_reg_xmit(enum reg_ring_type type, struct gazelle_quintuple *qtuple);
190+extern bool port_in_stack_queue(uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port);
191
192 #endif /* __REG_SOCK_H__ */
193--
1942.27.0
195
196