@@ -32,10 +32,8 @@ LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL);
32
32
#define TCP_RECEIVER_STACK_SIZE 2048
33
33
34
34
#define SOCK_ID_IPV4_LISTEN 0
35
- #define SOCK_ID_IPV4_DATA 1
36
- #define SOCK_ID_IPV6_LISTEN 2
37
- #define SOCK_ID_IPV6_DATA 3
38
- #define SOCK_ID_MAX 4
35
+ #define SOCK_ID_IPV6_LISTEN 1
36
+ #define SOCK_ID_MAX (CONFIG_NET_ZPERF_MAX_SESSIONS + 2)
39
37
40
38
#define TCP_RECEIVER_BUF_SIZE 1500
41
39
#define POLL_TIMEOUT_MS 100
@@ -100,10 +98,50 @@ static void tcp_received(const struct sockaddr *addr, size_t datalen)
100
98
}
101
99
}
102
100
101
+ static int tcp_bind_listen_connection (struct zsock_pollfd * pollfd ,
102
+ struct sockaddr * address )
103
+ {
104
+ uint16_t port ;
105
+ int ret ;
106
+
107
+ if (address -> sa_family == AF_INET ) {
108
+ port = ntohs (net_sin (address )-> sin_port );
109
+ } else {
110
+ port = ntohs (net_sin6 (address )-> sin6_port );
111
+ }
112
+
113
+ ret = zsock_bind (pollfd -> fd , address , sizeof (* address ));
114
+ if (ret < 0 ) {
115
+ NET_ERR ("Cannot bind IPv%d TCP port %d (%d)" ,
116
+ (address -> sa_family == AF_INET ? 4 : 6 ), port , errno );
117
+ goto out ;
118
+ }
119
+
120
+ ret = zsock_listen (pollfd -> fd , 1 );
121
+ if (ret < 0 ) {
122
+ NET_ERR ("Cannot listen IPv%d TCP (%d)" ,
123
+ (address -> sa_family == AF_INET ? 4 : 6 ), errno );
124
+ goto out ;
125
+ }
126
+
127
+ pollfd -> events = ZSOCK_POLLIN ;
128
+
129
+ out :
130
+ return ret ;
131
+ }
132
+
133
+ static void tcp_session_error_report (void )
134
+ {
135
+ if (tcp_session_cb != NULL ) {
136
+ tcp_session_cb (ZPERF_SESSION_ERROR , NULL , tcp_user_data );
137
+ }
138
+ }
139
+
103
140
static void tcp_server_session (void )
104
141
{
105
142
static uint8_t buf [TCP_RECEIVER_BUF_SIZE ];
106
- struct zsock_pollfd fds [SOCK_ID_MAX ] = { 0 };
143
+ static struct zsock_pollfd fds [SOCK_ID_MAX ];
144
+ static struct sockaddr sock_addr [SOCK_ID_MAX ];
107
145
int ret ;
108
146
109
147
for (int i = 0 ; i < ARRAY_SIZE (fds ); i ++ ) {
@@ -134,7 +172,7 @@ static void tcp_server_session(void)
134
172
const struct in_addr * addr =
135
173
zperf_get_default_if_in4_addr ();
136
174
if (!addr ) {
137
- NET_ERR ("Unable to get IPv4 by default\n " );
175
+ NET_ERR ("Unable to get IPv4 by default" );
138
176
goto error ;
139
177
}
140
178
memcpy (& in4_addr -> sin_addr , addr ,
@@ -146,22 +184,15 @@ static void tcp_server_session(void)
146
184
NET_INFO ("Binding to %s" ,
147
185
net_sprint_ipv4_addr (& in4_addr -> sin_addr ));
148
186
149
- ret = zsock_bind (fds [SOCK_ID_IPV4_LISTEN ].fd ,
150
- (struct sockaddr * )in4_addr ,
151
- sizeof (struct sockaddr_in ));
152
- if (ret < 0 ) {
153
- NET_ERR ("Cannot bind IPv4 TCP port %d (%d)" ,
154
- ntohs (in4_addr -> sin_port ), errno );
155
- goto error ;
156
- }
187
+ memcpy (net_sin (& sock_addr [SOCK_ID_IPV4_LISTEN ]), in4_addr ,
188
+ sizeof (struct sockaddr_in ));
157
189
158
- ret = zsock_listen (fds [SOCK_ID_IPV4_LISTEN ].fd , 1 );
190
+ ret = tcp_bind_listen_connection (
191
+ & fds [SOCK_ID_IPV4_LISTEN ],
192
+ & sock_addr [SOCK_ID_IPV4_LISTEN ]);
159
193
if (ret < 0 ) {
160
- NET_ERR ("Cannot listen IPv4 TCP (%d)" , errno );
161
194
goto error ;
162
195
}
163
-
164
- fds [SOCK_ID_IPV4_LISTEN ].events = ZSOCK_POLLIN ;
165
196
}
166
197
167
198
if (IS_ENABLED (CONFIG_NET_IPV6 )) {
@@ -189,7 +220,7 @@ static void tcp_server_session(void)
189
220
const struct in6_addr * addr =
190
221
zperf_get_default_if_in6_addr ();
191
222
if (!addr ) {
192
- NET_ERR ("Unable to get IPv6 by default\n " );
223
+ NET_ERR ("Unable to get IPv6 by default" );
193
224
goto error ;
194
225
}
195
226
memcpy (& in6_addr -> sin6_addr , addr ,
@@ -201,29 +232,20 @@ static void tcp_server_session(void)
201
232
NET_INFO ("Binding to %s" ,
202
233
net_sprint_ipv6_addr (& in6_addr -> sin6_addr ));
203
234
204
- ret = zsock_bind (fds [SOCK_ID_IPV6_LISTEN ].fd ,
205
- (struct sockaddr * )in6_addr ,
206
- sizeof (struct sockaddr_in6 ));
207
- if (ret < 0 ) {
208
- NET_ERR ("Cannot bind IPv6 TCP port %d (%d)" ,
209
- ntohs (in6_addr -> sin6_port ), errno );
210
- goto error ;
211
- }
235
+ memcpy (net_sin6 (& sock_addr [SOCK_ID_IPV6_LISTEN ]), in6_addr ,
236
+ sizeof (struct sockaddr_in6 ));
212
237
213
- ret = zsock_listen (fds [SOCK_ID_IPV6_LISTEN ].fd , 1 );
238
+ ret = tcp_bind_listen_connection (
239
+ & fds [SOCK_ID_IPV6_LISTEN ],
240
+ & sock_addr [SOCK_ID_IPV6_LISTEN ]);
214
241
if (ret < 0 ) {
215
- NET_ERR ("Cannot listen IPv6 TCP (%d)" , errno );
216
242
goto error ;
217
243
}
218
-
219
- fds [SOCK_ID_IPV6_LISTEN ].events = ZSOCK_POLLIN ;
220
244
}
221
245
222
246
NET_INFO ("Listening on port %d" , tcp_server_port );
223
247
224
248
while (true) {
225
- struct sockaddr addr_ipv4 , addr_ipv6 ;
226
-
227
249
ret = zsock_poll (fds , ARRAY_SIZE (fds ), POLL_TIMEOUT_MS );
228
250
if (ret < 0 ) {
229
251
NET_ERR ("TCP receiver poll error (%d)" , errno );
@@ -239,84 +261,84 @@ static void tcp_server_session(void)
239
261
}
240
262
241
263
for (int i = 0 ; i < ARRAY_SIZE (fds ); i ++ ) {
242
- struct sockaddr * addr = & addr_ipv6 ;
243
- socklen_t addrlen = sizeof (struct sockaddr );
244
-
245
264
if ((fds [i ].revents & ZSOCK_POLLERR ) ||
246
265
(fds [i ].revents & ZSOCK_POLLNVAL )) {
247
266
NET_ERR ("TCP receiver IPv%d socket error" ,
248
- (i <= SOCK_ID_IPV4_DATA ) ? 4 : 6 );
267
+ (sock_addr [i ].sa_family == AF_INET
268
+ ? 4 : 6 ));
249
269
goto error ;
250
270
}
251
271
252
272
if (!(fds [i ].revents & ZSOCK_POLLIN )) {
253
273
continue ;
254
274
}
255
275
256
- switch (i ) {
257
- case SOCK_ID_IPV4_LISTEN :
258
- addr = & addr_ipv4 ;
259
- __fallthrough ;
260
- case SOCK_ID_IPV6_LISTEN :{
261
- int sock = zsock_accept (fds [i ].fd , addr , & addrlen );
276
+ if ((i >= SOCK_ID_IPV4_LISTEN ) && (i <= SOCK_ID_IPV6_LISTEN )) {
277
+ int j = SOCK_ID_IPV6_LISTEN + 1 ;
278
+ struct sockaddr addr_incoming_conn ;
279
+ socklen_t addrlen = sizeof (struct sockaddr );
280
+ int sock = zsock_accept (fds [i ].fd ,
281
+ & addr_incoming_conn ,
282
+ & addrlen );
262
283
263
284
if (sock < 0 ) {
264
285
NET_ERR ("TCP receiver IPv%d accept error" ,
265
- (i <= SOCK_ID_IPV4_DATA ) ? 4 : 6 );
286
+ (sock_addr [i ].sa_family == AF_INET
287
+ ? 4 : 6 ));
266
288
goto error ;
267
289
}
268
290
269
- if (i == SOCK_ID_IPV4_LISTEN &&
270
- fds [SOCK_ID_IPV4_DATA ].fd < 0 ) {
271
- fds [SOCK_ID_IPV4_DATA ].fd = sock ;
272
- fds [SOCK_ID_IPV4_DATA ].events = ZSOCK_POLLIN ;
273
- } else if (i == SOCK_ID_IPV6_LISTEN &&
274
- fds [SOCK_ID_IPV6_DATA ].fd < 0 ) {
275
- fds [SOCK_ID_IPV6_DATA ].fd = sock ;
276
- fds [SOCK_ID_IPV6_DATA ].events = ZSOCK_POLLIN ;
277
- } else {
291
+ for (; j < SOCK_ID_MAX ; j ++ ) {
292
+ if (fds [j ].fd < 0 ) {
293
+ break ;
294
+ }
295
+ }
296
+
297
+ if (j == SOCK_ID_MAX ) {
278
298
/* Too many connections. */
299
+ NET_ERR ("Dropping TCP connection, reached maximum limit." );
279
300
zsock_close (sock );
280
- break ;
301
+ } else {
302
+ fds [j ].fd = sock ;
303
+ fds [j ].events = ZSOCK_POLLIN ;
304
+ memcpy (& sock_addr [j ],
305
+ & addr_incoming_conn ,
306
+ addrlen );
281
307
}
282
-
283
- break ;
284
- }
285
-
286
- case SOCK_ID_IPV4_DATA :
287
- addr = & addr_ipv4 ;
288
- __fallthrough ;
289
- case SOCK_ID_IPV6_DATA :
308
+ } else if ((i > SOCK_ID_IPV6_LISTEN ) && (i < SOCK_ID_MAX )) {
290
309
ret = zsock_recv (fds [i ].fd , buf , sizeof (buf ), 0 );
291
310
if (ret < 0 ) {
292
311
NET_ERR ("recv failed on IPv%d socket (%d)" ,
293
- (i <= SOCK_ID_IPV4_DATA ) ? 4 : 6 ,
312
+ (sock_addr [i ].sa_family == AF_INET
313
+ ? 4 : 6 ),
294
314
errno );
295
- goto error ;
315
+ tcp_session_error_report ();
316
+ /* This will close the zperf session */
317
+ ret = 0 ;
296
318
}
297
319
298
- tcp_received (addr , ret );
320
+ tcp_received (& sock_addr [ i ] , ret );
299
321
300
322
if (ret == 0 ) {
301
323
zsock_close (fds [i ].fd );
302
324
fds [i ].fd = -1 ;
325
+ memset (& sock_addr [i ], 0 ,
326
+ sizeof (struct sockaddr ));
303
327
}
304
-
305
- break ;
328
+ } else {
329
+ goto error ;
306
330
}
307
331
}
308
332
}
309
333
310
334
error :
311
- if (tcp_session_cb != NULL ) {
312
- tcp_session_cb (ZPERF_SESSION_ERROR , NULL ,
313
- tcp_user_data );
314
- }
335
+ tcp_session_error_report ();
315
336
316
337
cleanup :
317
338
for (int i = 0 ; i < ARRAY_SIZE (fds ); i ++ ) {
318
339
if (fds [i ].fd >= 0 ) {
319
340
zsock_close (fds [i ].fd );
341
+ memset (& sock_addr [i ], 0 , sizeof (struct sockaddr ));
320
342
}
321
343
}
322
344
}
0 commit comments