ReactOS 0.4.16-dev-814-g656a5dc
sockets_stresstest.c
Go to the documentation of this file.
1
20 /*
21 * Copyright (c) 2017 Simon Goldschmidt
22 * All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without modification,
25 * are permitted provided that the following conditions are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright notice,
28 * this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright notice,
30 * this list of conditions and the following disclaimer in the documentation
31 * and/or other materials provided with the distribution.
32 * 3. The name of the author may not be used to endorse or promote products
33 * derived from this software without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
38 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
43 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
44 * OF SUCH DAMAGE.
45 *
46 * This file is part of the lwIP TCP/IP stack.
47 *
48 * Author: Simon Goldschmidt <goldsimon@gmx.de>
49 *
50 */
51
52#include "lwip/opt.h"
53#include "sockets_stresstest.h"
54
55#include "lwip/sockets.h"
56#include "lwip/sys.h"
57
58#include "lwip/mem.h"
59
60#include <stdio.h>
61#include <string.h>
62
63#if LWIP_SOCKET && LWIP_IPV4 /* this uses IPv4 loopback sockets, currently */
64
65#ifndef TEST_SOCKETS_STRESS
66#define TEST_SOCKETS_STRESS LWIP_DBG_OFF
67#endif
68
69#define TEST_TIME_SECONDS 10
70#define TEST_TXRX_BUFSIZE (TCP_MSS * 2)
71#define TEST_MAX_RXWAIT_MS 50
72#define TEST_MAX_CONNECTIONS 50
73
74#define TEST_SOCK_READABLE 0x01
75#define TEST_SOCK_WRITABLE 0x02
76#define TEST_SOCK_ERR 0x04
77
78#define TEST_MODE_SELECT 0x01
79#define TEST_MODE_POLL 0x02
80#define TEST_MODE_NONBLOCKING 0x04
81#define TEST_MODE_WAIT 0x08
82#define TEST_MODE_RECVTIMEO 0x10
83#define TEST_MODE_SLEEP 0x20
84
85static int sockets_stresstest_numthreads;
86
87struct test_settings {
89 int start_client;
90 int loop_cnt;
91};
92
93struct sockets_stresstest_fullduplex {
94 int s;
95 volatile int closed;
96};
97
98static void
99fill_test_data(void *buf, size_t buf_len_bytes)
100{
101 u8_t *p = (u8_t*)buf;
102 u16_t i, chk;
103
104 LWIP_ASSERT("buffer too short", buf_len_bytes >= 4);
105 LWIP_ASSERT("buffer too big", buf_len_bytes <= 0xFFFF);
106 /* store the total number of bytes */
107 p[0] = (u8_t)(buf_len_bytes >> 8);
108 p[1] = (u8_t)buf_len_bytes;
109
110 /* fill buffer with random */
111 chk = 0;
112 for (i = 4; i < buf_len_bytes; i++) {
113 u8_t rnd = (u8_t)LWIP_RAND();
114 p[i] = rnd;
115 chk += rnd;
116 }
117 /* store checksum */
118 p[2] = (u8_t)(chk >> 8);
119 p[3] = (u8_t)chk;
120}
121
122static size_t
123check_test_data(const void *buf, size_t buf_len_bytes)
124{
125 u8_t *p = (u8_t*)buf;
126 u16_t i, chk, chk_rx, len_rx;
127
128 LWIP_ASSERT("buffer too short", buf_len_bytes >= 4);
129 len_rx = (((u16_t)p[0]) << 8) | p[1];
130 LWIP_ASSERT("len too short", len_rx >= 4);
131 if (len_rx > buf_len_bytes) {
132 /* not all data received in this segment */
133 LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("check-\n"));
134 return buf_len_bytes;
135 }
136 chk_rx = (((u16_t)p[2]) << 8) | p[3];
137 /* calculate received checksum */
138 chk = 0;
139 for (i = 4; i < len_rx; i++) {
140 chk += p[i];
141 }
142 LWIP_ASSERT("invalid checksum", chk == chk_rx);
143 if (len_rx < buf_len_bytes) {
144 size_t data_left = buf_len_bytes - len_rx;
145 memmove(p, &p[len_rx], data_left);
146 return data_left;
147 }
148 /* if we come here, we received exactly one chunk
149 -> next offset is 0 */
150 return 0;
151}
152
153static size_t
154recv_and_check_data_return_offset(int s, char *rxbuf, size_t rxbufsize, size_t rxoff, int *closed, const char *dbg)
155{
156 ssize_t ret;
157
158 ret = lwip_read(s, &rxbuf[rxoff], rxbufsize - rxoff);
159 if (ret == 0) {
160 *closed = 1;
161 return rxoff;
162 }
163 *closed = 0;
164 LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("%s %d rx %d\n", dbg, s, (int)ret));
165 if (ret == -1) {
166 /* TODO: for this to work, 'errno' has to support multithreading... */
167 int err = errno;
168 if (err == ENOTCONN) {
169 *closed = 1;
170 return 0;
171 }
172 LWIP_ASSERT("err == 0", err == 0);
173 }
174 LWIP_ASSERT("ret > 0", ret > 0);
175 return check_test_data(rxbuf, rxoff + ret);
176}
177
178#if LWIP_SOCKET_SELECT
179static int
180sockets_stresstest_wait_readable_select(int s, int timeout_ms)
181{
182 int ret;
183 struct timeval tv;
184 fd_set fs_r;
185 fd_set fs_w;
186 fd_set fs_e;
187
188 FD_ZERO(&fs_r);
189 FD_ZERO(&fs_w);
190 FD_ZERO(&fs_e);
191
192 FD_SET(s, &fs_r);
193 FD_SET(s, &fs_e);
194
195 tv.tv_sec = timeout_ms / 1000;
196 tv.tv_usec = (timeout_ms - (tv.tv_sec * 1000)) * 1000;
197 ret = lwip_select(s + 1, &fs_r, &fs_w, &fs_e, &tv);
198 LWIP_ASSERT("select error", ret >= 0);
199 if (ret) {
200 /* convert poll flags to our flags */
201 ret = 0;
202 if (FD_ISSET(s, &fs_r)) {
203 ret |= TEST_SOCK_READABLE;
204 }
205 if (FD_ISSET(s, &fs_w)) {
206 ret |= TEST_SOCK_WRITABLE;
207 }
208 if (FD_ISSET(s, &fs_e)) {
209 ret |= TEST_SOCK_ERR;
210 }
211 return ret;
212 }
213 return 0;
214}
215#endif
216
217#if LWIP_SOCKET_POLL
218static int
219sockets_stresstest_wait_readable_poll(int s, int timeout_ms)
220{
221 int ret;
222 struct pollfd pfd;
223
224 pfd.fd = s;
225 pfd.revents = 0;
226 pfd.events = POLLIN | POLLERR;
227
228 ret = lwip_poll(&pfd, 1, timeout_ms);
229 if (ret) {
230 /* convert poll flags to our flags */
231 ret = 0;
232 if (pfd.revents & POLLIN) {
233 ret |= TEST_SOCK_READABLE;
234 }
235 if (pfd.revents & POLLOUT) {
236 ret |= TEST_SOCK_WRITABLE;
237 }
238 if (pfd.revents & POLLERR) {
239 ret |= TEST_SOCK_ERR;
240 }
241 return ret;
242 }
243 return 0;
244}
245#endif
246
247#if LWIP_SO_RCVTIMEO
248static int
249sockets_stresstest_wait_readable_recvtimeo(int s, int timeout_ms)
250{
251 int ret;
252 char buf;
253#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
254 int opt_on = timeout_ms;
255 int opt_off = 0;
256#else
257 struct timeval opt_on, opt_off;
258 opt_on.tv_sec = timeout_ms / 1000;
259 opt_on.tv_usec = (timeout_ms - (opt_on.tv_sec * 1000)) * 1000;
260 opt_off.tv_sec = 0;
261 opt_off.tv_usec = 0;
262#endif
263
264 /* enable receive timeout */
265 ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt_on, sizeof(opt_on));
266 LWIP_ASSERT("setsockopt error", ret == 0);
267
268 /* peek for one byte with timeout */
269 ret = lwip_recv(s, &buf, 1, MSG_PEEK);
270
271 /* disable receive timeout */
272 ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt_off, sizeof(opt_off));
273 LWIP_ASSERT("setsockopt error", ret == 0);
274
275 if (ret == 1) {
276 return TEST_SOCK_READABLE;
277 }
278 if (ret == 0) {
279 return 0;
280 }
281 if (ret == -1) {
282 return TEST_SOCK_ERR;
283 }
284 LWIP_ASSERT("invalid return value", 0);
285 return TEST_SOCK_ERR;
286}
287#endif
288
289static int
290sockets_stresstest_wait_readable_wait_peek(int s, int timeout_ms)
291{
292 int ret;
293 char buf;
294
295 LWIP_UNUSED_ARG(timeout_ms); /* cannot time out here */
296
297 /* peek for one byte */
298 ret = lwip_recv(s, &buf, 1, MSG_PEEK);
299
300 if (ret == 1) {
301 return TEST_SOCK_READABLE;
302 }
303 if (ret == 0) {
304 return 0;
305 }
306 if (ret == -1) {
307 return TEST_SOCK_ERR;
308 }
309 LWIP_ASSERT("invalid return value", 0);
310 return TEST_SOCK_ERR;
311}
312
313static int
314sockets_stresstest_wait_readable_nonblock(int s, int timeout_ms)
315{
316 int ret;
317 char buf;
318 u32_t wait_until = sys_now() + timeout_ms;
319
320 while(sys_now() < wait_until) {
321 /* peek for one byte */
322 ret = lwip_recv(s, &buf, 1, MSG_PEEK | MSG_DONTWAIT);
323
324 if (ret == 1) {
325 return TEST_SOCK_READABLE;
326 }
327 if (ret == -1) {
328 /* TODO: for this to work, 'errno' has to support multithreading... */
329 int err = errno;
330 if (err != EWOULDBLOCK) {
331 return TEST_SOCK_ERR;
332 }
333 }
334 /* TODO: sleep? */
335 }
336 return 0;
337}
338
339static int sockets_stresstest_rand_mode(int allow_wait, int allow_rx)
340{
341 u32_t random_value = LWIP_RAND();
342#if LWIP_SOCKET_SELECT
343 if (random_value & TEST_MODE_SELECT) {
344 return TEST_MODE_SELECT;
345 }
346#endif
347#if LWIP_SOCKET_POLL
348 if (random_value & TEST_MODE_POLL) {
349 return TEST_MODE_POLL;
350 }
351#endif
352 if (!allow_rx) {
353 return TEST_MODE_SLEEP;
354 }
355#if LWIP_SO_RCVTIMEO
356 if (random_value & TEST_MODE_RECVTIMEO) {
357 return TEST_MODE_RECVTIMEO;
358 }
359#endif
360 if (allow_wait) {
361 if (random_value & TEST_MODE_RECVTIMEO) {
362 return TEST_MODE_RECVTIMEO;
363 }
364 }
365 return TEST_MODE_NONBLOCKING;
366}
367
368static int
369sockets_stresstest_wait_readable(int mode, int s, int timeout_ms)
370{
371 switch(mode)
372 {
373#if LWIP_SOCKET_SELECT
374 case TEST_MODE_SELECT:
375 return sockets_stresstest_wait_readable_select(s, timeout_ms);
376#endif
377#if LWIP_SOCKET_POLL
378 case TEST_MODE_POLL:
379 return sockets_stresstest_wait_readable_poll(s, timeout_ms);
380#endif
381#if LWIP_SO_RCVTIMEO
382 case TEST_MODE_RECVTIMEO:
383 return sockets_stresstest_wait_readable_recvtimeo(s, timeout_ms);
384#endif
385 case TEST_MODE_WAIT:
386 return sockets_stresstest_wait_readable_wait_peek(s, timeout_ms);
387 case TEST_MODE_NONBLOCKING:
388 return sockets_stresstest_wait_readable_nonblock(s, timeout_ms);
389 case TEST_MODE_SLEEP:
390 {
391 sys_msleep(timeout_ms);
392 return 1;
393 }
394 default:
395 LWIP_ASSERT("invalid mode", 0);
396 break;
397 }
398 return 0;
399}
400
401#if LWIP_NETCONN_FULLDUPLEX
402static void
403sockets_stresstest_conn_client_r(void *arg)
404{
405 struct sockets_stresstest_fullduplex *fd = (struct sockets_stresstest_fullduplex *)arg;
406 int s = fd->s;
407 size_t rxoff = 0;
408 char rxbuf[TEST_TXRX_BUFSIZE];
409
410 while (1) {
411 int closed;
412 if (fd->closed) {
413 break;
414 }
415 rxoff = recv_and_check_data_return_offset(s, rxbuf, sizeof(rxbuf), rxoff, &closed, "cli");
416 if (fd->closed) {
417 break;
418 }
419 if (closed) {
420 lwip_close(s);
421 break;
422 }
423 }
424
425 SYS_ARCH_DEC(sockets_stresstest_numthreads, 1);
426 LWIP_ASSERT("", sockets_stresstest_numthreads >= 0);
427}
428#endif
429
430static void
431sockets_stresstest_conn_client(void *arg)
432{
433 struct sockaddr_storage addr;
434 struct sockaddr_in *addr_in;
435 int s, ret;
436 char txbuf[TEST_TXRX_BUFSIZE];
437 char rxbuf[TEST_TXRX_BUFSIZE];
438 size_t rxoff = 0;
439 u32_t max_time = sys_now() + (TEST_TIME_SECONDS * 1000);
440 int do_rx = 1;
441 struct sockets_stresstest_fullduplex *data = NULL;
442
443 memcpy(&addr, arg, sizeof(addr));
444 LWIP_ASSERT("", addr.ss_family == AF_INET);
445 addr_in = (struct sockaddr_in *)&addr;
446 addr_in->sin_addr.s_addr = inet_addr("127.0.0.1");
447
448 /* sleep a random time between 1 and 2 seconds */
449 sys_msleep(1000 + (LWIP_RAND() % 1000));
450
451 /* connect to the server */
452 s = lwip_socket(addr.ss_family, SOCK_STREAM, 0);
453 LWIP_ASSERT("s >= 0", s >= 0);
454
455#if LWIP_NETCONN_FULLDUPLEX
456 if (LWIP_RAND() & 1) {
458 data = (struct sockets_stresstest_fullduplex*)mem_malloc(sizeof(struct sockets_stresstest_fullduplex));
459 LWIP_ASSERT("data != NULL", data != 0);
460 SYS_ARCH_INC(sockets_stresstest_numthreads, 1);
461 data->s = s;
462 data->closed = 0;
463 t = sys_thread_new("sockets_stresstest_conn_client_r", sockets_stresstest_conn_client_r, data, 0, 0);
464 LWIP_ASSERT("thread != NULL", t != 0);
465 do_rx = 0;
466 }
467#endif
468
469 /* @todo: nonblocking connect? */
470 ret = lwip_connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage));
471 LWIP_ASSERT("ret == 0", ret == 0);
472
473 while (sys_now() < max_time) {
474 int closed;
475 int mode = sockets_stresstest_rand_mode(0, do_rx);
476 int timeout_ms = LWIP_RAND() % TEST_MAX_RXWAIT_MS;
477 ret = sockets_stresstest_wait_readable(mode, s, timeout_ms);
478 if (ret) {
479 if (do_rx) {
480 /* read some */
481 LWIP_ASSERT("readable", ret == TEST_SOCK_READABLE);
482 rxoff = recv_and_check_data_return_offset(s, rxbuf, sizeof(rxbuf), rxoff, &closed, "cli");
483 LWIP_ASSERT("client got closed", !closed);
484 }
485 } else {
486 /* timeout, send some */
487 size_t send_len = (LWIP_RAND() % (sizeof(txbuf) - 4)) + 4;
488 fill_test_data(txbuf, send_len);
489 LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("cli %d tx %d\n", s, (int)send_len));
490 ret = lwip_write(s, txbuf, send_len);
491 if (ret == -1) {
492 /* TODO: for this to work, 'errno' has to support multithreading... */
493 int err = errno;
494 LWIP_ASSERT("err == 0", err == 0);
495 }
496 LWIP_ASSERT("ret == send_len", ret == (int)send_len);
497 }
498 }
499 if (data) {
500 data->closed = 1;
501 }
502 ret = lwip_close(s);
503 LWIP_ASSERT("ret == 0", ret == 0);
504
505 SYS_ARCH_DEC(sockets_stresstest_numthreads, 1);
506 LWIP_ASSERT("", sockets_stresstest_numthreads >= 0);
507}
508
509static void
510sockets_stresstest_conn_server(void *arg)
511{
512 int s, ret;
513 char txbuf[TEST_TXRX_BUFSIZE];
514 char rxbuf[TEST_TXRX_BUFSIZE];
515 size_t rxoff = 0;
516
517 s = (int)arg;
518
519 while (1) {
520 int closed;
521 int mode = sockets_stresstest_rand_mode(1, 1);
522 int timeout_ms = LWIP_RAND() % TEST_MAX_RXWAIT_MS;
523 ret = sockets_stresstest_wait_readable(mode, s, timeout_ms);
524 if (ret) {
525 if (ret & TEST_SOCK_ERR) {
526 /* closed? */
527 break;
528 }
529 /* read some */
530 LWIP_ASSERT("readable", ret == TEST_SOCK_READABLE);
531 rxoff = recv_and_check_data_return_offset(s, rxbuf, sizeof(rxbuf), rxoff, &closed, "srv");
532 if (closed) {
533 break;
534 }
535 } else {
536 /* timeout, send some */
537 size_t send_len = (LWIP_RAND() % (sizeof(txbuf) - 4)) + 4;
538 fill_test_data(txbuf, send_len);
539 LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_TRACE, ("srv %d tx %d\n", s, (int)send_len));
540 ret = lwip_write(s, txbuf, send_len);
541 if (ret == -1) {
542 /* TODO: for this to work, 'errno' has to support multithreading... */
543 int err = errno;
544 if (err == ECONNRESET) {
545 break;
546 }
547 if (err == ENOTCONN) {
548 break;
549 }
550 LWIP_ASSERT("unknown error", 0);
551 }
552 LWIP_ASSERT("ret == send_len", ret == (int)send_len);
553 }
554 }
555 ret = lwip_close(s);
556 LWIP_ASSERT("ret == 0", ret == 0);
557
558 SYS_ARCH_DEC(sockets_stresstest_numthreads, 1);
559 LWIP_ASSERT("", sockets_stresstest_numthreads >= 0);
560}
561
562static int
563sockets_stresstest_start_clients(const struct sockaddr_storage *remote_addr)
564{
565 /* limit the number of connections */
566 const int max_connections = LWIP_MIN(TEST_MAX_CONNECTIONS, MEMP_NUM_TCP_PCB/3);
567 int i;
568
569 for (i = 0; i < max_connections; i++) {
571 SYS_ARCH_INC(sockets_stresstest_numthreads, 1);
572 t = sys_thread_new("sockets_stresstest_conn_client", sockets_stresstest_conn_client, (void*)remote_addr, 0, 0);
573 LWIP_ASSERT("thread != NULL", t != 0);
574 }
575 return max_connections;
576}
577
578static void
579sockets_stresstest_listener(void *arg)
580{
581 int slisten;
582 int ret;
583 struct sockaddr_storage addr;
584 socklen_t addr_len;
585 struct test_settings *settings = (struct test_settings *)arg;
586 int num_clients, num_servers = 0;
587
588 slisten = lwip_socket(AF_INET, SOCK_STREAM, 0);
589 LWIP_ASSERT("slisten >= 0", slisten >= 0);
590
591 memcpy(&addr, &settings->addr, sizeof(struct sockaddr_storage));
592 ret = lwip_bind(slisten, (struct sockaddr *)&addr, sizeof(addr));
593 LWIP_ASSERT("ret == 0", ret == 0);
594
595 ret = lwip_listen(slisten, 0);
596 LWIP_ASSERT("ret == 0", ret == 0);
597
598 addr_len = sizeof(addr);
599 ret = lwip_getsockname(slisten, (struct sockaddr *)&addr, &addr_len);
600 LWIP_ASSERT("ret == 0", ret == 0);
601
602 num_clients = sockets_stresstest_start_clients(&addr);
603
604 while (num_servers < num_clients) {
605 struct sockaddr_storage aclient;
606 socklen_t aclient_len = sizeof(aclient);
607 int sclient = lwip_accept(slisten, (struct sockaddr *)&aclient, &aclient_len);
608#if 1
609 /* using server threads */
610 {
612 SYS_ARCH_INC(sockets_stresstest_numthreads, 1);
613 num_servers++;
614 t = sys_thread_new("sockets_stresstest_conn_server", sockets_stresstest_conn_server, (void*)sclient, 0, 0);
615 LWIP_ASSERT("thread != NULL", t != 0);
616 }
617#else
618 /* using server select */
619#endif
620 }
621 LWIP_DEBUGF(TEST_SOCKETS_STRESS | LWIP_DBG_STATE, ("sockets_stresstest_listener: all %d connections established\n", num_clients));
622
623 /* accepted all clients */
624 while (sockets_stresstest_numthreads > 0) {
625 sys_msleep(1);
626 }
627
628 ret = lwip_close(slisten);
629 LWIP_ASSERT("ret == 0", ret == 0);
630
631 LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener: done\n"));
632}
633
634static void
635sockets_stresstest_listener_loop(void *arg)
636{
637 int i;
638 struct test_settings *settings = (struct test_settings *)arg;
639
640 if (settings->loop_cnt) {
641 for (i = 0; i < settings->loop_cnt; i++) {
642 LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener_loop: iteration %d\n", i));
643 sockets_stresstest_listener(arg);
644 sys_msleep(2);
645 }
646 LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener_loop: done\n"));
647 } else {
648 for (i = 0; ; i++) {
649 LWIP_DEBUGF(TEST_SOCKETS_STRESS |LWIP_DBG_STATE, ("sockets_stresstest_listener_loop: iteration %d\n", i));
650 sockets_stresstest_listener(arg);
651 sys_msleep(2);
652 }
653 }
654}
655
656void
658{
660 struct test_settings *settings = (struct test_settings *)mem_malloc(sizeof(struct test_settings));
661
662 LWIP_ASSERT("OOM", settings != NULL);
663 memset(settings, 0, sizeof(struct test_settings));
664#if LWIP_IPV4 && LWIP_IPV6
665 LWIP_ASSERT("invalid addr_family", (addr_family == AF_INET) || (addr_family == AF_INET6));
666#endif
667 settings->addr.ss_family = (sa_family_t)addr_family;
668 LWIP_UNUSED_ARG(addr_family);
669 settings->start_client = 1;
670
671 t = sys_thread_new("sockets_stresstest_listener_loop", sockets_stresstest_listener_loop, settings, 0, 0);
672 LWIP_ASSERT("thread != NULL", t != 0);
673}
674
675void
676sockets_stresstest_init_server(int addr_family, u16_t server_port)
677{
679 struct test_settings *settings = (struct test_settings *)mem_malloc(sizeof(struct test_settings));
680
681 LWIP_ASSERT("OOM", settings != NULL);
682 memset(settings, 0, sizeof(struct test_settings));
683#if LWIP_IPV4 && LWIP_IPV6
684 LWIP_ASSERT("invalid addr_family", (addr_family == AF_INET) || (addr_family == AF_INET6));
685 settings->addr.ss_family = (sa_family_t)addr_family;
686#endif
687 LWIP_UNUSED_ARG(addr_family);
688 ((struct sockaddr_in *)(&settings->addr))->sin_port = server_port;
689
690 t = sys_thread_new("sockets_stresstest_listener", sockets_stresstest_listener, settings, 0, 0);
691 LWIP_ASSERT("thread != NULL", t != 0);
692}
693
694void
695sockets_stresstest_init_client(const char *remote_ip, u16_t remote_port)
696{
697#if LWIP_IPV4
698 ip4_addr_t ip4;
699#endif
700#if LWIP_IPV6
701 ip6_addr_t ip6;
702#endif
703 struct sockaddr_storage *addr = (struct sockaddr_storage *)mem_malloc(sizeof(struct sockaddr_storage));
704
705 LWIP_ASSERT("OOM", addr != NULL);
706 memset(addr, 0, sizeof(struct test_settings));
707#if LWIP_IPV4
708 if (ip4addr_aton(remote_ip, &ip4)) {
709 addr->ss_family = AF_INET;
710 ((struct sockaddr_in *)addr)->sin_addr.s_addr = ip4_addr_get_u32(&ip4);
711 }
712#endif
713#if LWIP_IPV4 && LWIP_IPV6
714 else
715#endif
716#if LWIP_IPV6
717 if (ip6addr_aton(remote_ip, &ip6)) {
718 addr->ss_family = AF_INET6;
719 /* todo: copy ipv6 address */
720 }
721#endif
722 ((struct sockaddr_in *)addr)->sin_port = remote_port;
723 sockets_stresstest_start_clients(addr);
724}
725
726#endif /* LWIP_SOCKET && LWIP_IPV4 */
struct mke2fs_defaults settings[]
ULONG WSAAPI inet_addr(IN CONST CHAR FAR *cp)
Definition: addrconv.c:71
#define LWIP_MIN(x, y)
Definition: def.h:66
#define NULL
Definition: types.h:112
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define EWOULDBLOCK
Definition: errno.h:42
#define ECONNRESET
Definition: errno.h:115
#define ENOTCONN
Definition: errno.h:118
#define POLLIN
Definition: linux.h:1853
#define POLLOUT
Definition: linux.h:1855
#define POLLERR
Definition: linux.h:1856
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
void * mem_malloc(mem_size_t size_in)
Definition: mem.c:831
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
#define LWIP_DBG_STATE
Definition: debug.h:85
#define LWIP_DBG_TRACE
Definition: debug.h:83
#define MEMP_NUM_TCP_PCB
Definition: opt.h:429
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:275
void sys_msleep(u32_t ms)
Definition: sys.c:135
u32_t sys_now(void)
Definition: sys_arch.c:23
u32_t sys_thread_t
Definition: sys_arch.h:20
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
int socklen_t
Definition: tcp.c:35
#define err(...)
int ssize_t
Definition: rosdhcp.h:48
#define errno
Definition: errno.h:18
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
void sockets_stresstest_init_client(const char *remote_ip, u16_t remote_port)
void sockets_stresstest_init_loopback(int addr_family)
void sockets_stresstest_init_server(int addr_family, u16_t server_port)
static PIXELFORMATDESCRIPTOR pfd
Definition: ssstars.c:67
Definition: winsock.h:66
Definition: linux.h:1867
struct in_addr sin_addr
Definition: winsock.h:512
u_short sin_port
Definition: winsock.h:511
unsigned long tv_sec
Definition: linux.h:1738
#define SYS_ARCH_DEC(var, val)
Definition: sys.h:535
#define SYS_ARCH_INC(var, val)
Definition: sys.h:526
int ret
#define FD_ISSET(fd, set)
Definition: winsock.h:100
#define FD_ZERO(set)
Definition: winsock.h:96
#define MSG_PEEK
Definition: winsock.h:222
#define SOL_SOCKET
Definition: winsock.h:398
#define AF_INET6
Definition: winsock.h:369
#define FD_SET(fd, set)
Definition: winsock.h:89
#define SO_RCVTIMEO
Definition: winsock.h:193