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