18 #include <sys/types.h> 19 #include <sys/socket.h> 27 #include <sys/ioctl.h> 28 #include <sys/epoll.h> 31 #define SOCK_SERVER_MAX_TEST_CONN 10 32 #define SOCK_SERVER_MAX_EPOLL_EVENTS 10 56 struct epoll_event listen_ev;
60 struct epoll_event af_unix_listen_ev;
61 struct sockaddr_un serveraddr;
69 struct timeval timeout;
88 memset (conn, 0,
sizeof (*conn));
100 int errno_val = errno;
101 perror (
"ERROR in conn_pool_expand()");
102 fprintf (stderr,
"SERVER: ERROR: Memory allocation " 103 "failed (errno = %d)!\n", errno_val);
142 printf (
"\nSERVER (fd %d): Replying to cfg message!\n", conn->
fd);
154 int client_fd = conn->
fd;
160 clock_gettime (CLOCK_REALTIME, &conn->
stats.
stop);
174 snprintf (buf,
sizeof (buf),
"SERVER (fd %d) RESULTS",
190 printf (
" sock server main\n" 193 " buf size: %u (0x%08x)\n" 199 printf (
"\nSERVER (fd %d): %s-directional Stream Test Complete!\n" 206 "SERVER (fd %d): %s-directional Stream Test!\n" 207 " Sending client the test cfg to start streaming data...\n",
216 memset (&conn->
stats, 0, sizeof (conn->
stats));
217 clock_gettime (CLOCK_REALTIME, &conn->
stats.
start);
225 int client_fd = conn->
fd;
234 clock_gettime (CLOCK_REALTIME, &conn->
stats.
stop);
242 int af_unix_client_fd;
250 (
struct sockaddr *) NULL, NULL, NULL);
253 (
struct sockaddr *) NULL, NULL);
255 if (af_unix_client_fd < 0)
258 perror (
"ERROR in af_unix_accept()");
259 fprintf (stderr,
"SERVER: ERROR: accept failed " 260 "(errno = %d)!\n", errno_val);
264 printf (
"SERVER: Got an AF_UNIX connection -- fd = %d (0x%08x)!\n",
265 af_unix_client_fd, af_unix_client_fd);
267 memset (buffer, 0,
sizeof (buffer));
269 rv = read (af_unix_client_fd, buffer, nbytes);
273 perror (
"ERROR in af_unix_echo(): read() failed");
274 fprintf (stderr,
"SERVER: ERROR: read(af_unix_client_fd %d (0x%x), " 275 "nbytes %lu) failed (errno = %d)!\n", af_unix_client_fd,
276 af_unix_client_fd, nbytes, errno_val);
280 buffer[
sizeof (buffer) - 1] = 0;
281 printf (
"SERVER (AF_UNIX): RX (%d bytes) - '%s'\n", rv, buffer);
285 rv = write (af_unix_client_fd, buffer, nbytes);
289 perror (
"ERROR in af_unix_echo(): write() failed");
291 "SERVER: ERROR: write(af_unix_client_fd %d (0x%x), " 292 "\"%s\", nbytes %ld) failed (errno = %d)!\n",
293 af_unix_client_fd, af_unix_client_fd, buffer, nbytes,
297 printf (
"SERVER (AF_UNIX): TX (%d bytes) - '%s'\n", rv, buffer);
301 close (af_unix_client_fd);
317 fprintf (stderr,
"\nSERVER: ERROR: No free connections!\n");
322 client_fd = accept4 (ssm->
listen_fd, (
struct sockaddr *) NULL, NULL, NULL);
324 client_fd = accept (ssm->
listen_fd, (
struct sockaddr *) NULL, NULL);
330 perror (
"ERROR in new_client()");
331 fprintf (stderr,
"SERVER: ERROR: accept failed " 332 "(errno = %d)!\n", errno_val);
336 printf (
"SERVER: Got a connection -- fd = %d (0x%08x)!\n",
337 client_fd, client_fd);
339 conn->
fd = client_fd;
341 struct epoll_event ev;
346 rv = epoll_ctl (ssm->
epfd, EPOLL_CTL_ADD, client_fd, &ev);
352 perror (
"ERROR in new_client()");
353 fprintf (stderr,
"SERVER: ERROR: epoll_ctl failed (errno = %d)!\n",
373 perror (
"ERROR in main(): socket(AF_UNIX) failed");
375 "SERVER: ERROR: socket(AF_UNIX, SOCK_STREAM, 0) failed " 376 "(errno = %d)!\n", errno_val);
382 strncpy (ssm->
serveraddr.sun_path, SOCK_TEST_AF_UNIX_FILENAME,
390 perror (
"ERROR in main(): bind(SOCK_TEST_AF_UNIX_FILENAME) failed");
391 fprintf (stderr,
"SERVER: ERROR: bind() fd %d, \"%s\": " 393 SOCK_TEST_AF_UNIX_FILENAME, errno_val);
395 unlink ((
const char *) SOCK_TEST_AF_UNIX_FILENAME);
403 perror (
"ERROR in main(): listen(AF_UNIX) failed");
404 fprintf (stderr,
"SERVER: ERROR: listen() fd %d, \"%s\": " 406 SOCK_TEST_AF_UNIX_FILENAME, errno_val);
408 unlink ((
const char *) SOCK_TEST_AF_UNIX_FILENAME);
419 perror (
"ERROR in main(): mixed epoll_ctl(EPOLL_CTL_ADD)");
420 fprintf (stderr,
"SERVER: ERROR: mixed epoll_ctl(epfd %d (0x%x), " 421 "EPOLL_CTL_ADD, af_unix_listen_fd %d (0x%x), EPOLLIN) failed " 422 "(errno = %d)!\n", ssm->
epfd, ssm->
epfd,
425 unlink ((
const char *) SOCK_TEST_AF_UNIX_FILENAME);
436 "sock_test_server [OPTIONS] <port>\n" 438 " -h Print this message and exit.\n" 440 " -u Use UDP transport layer\n");
448 int client_fd, rv, main_rv = 0;
449 int tx_bytes, rx_bytes, nbytes;
453 uint64_t xtra_bytes = 0;
454 struct sockaddr_storage servaddr;
458 uint32_t servaddr_size;
461 while ((c = getopt (argc, argv,
"6D")) != -1)
476 if (isprint (optopt))
477 fprintf (stderr,
"SERVER: ERROR: Unknown " 478 "option `-%c'.\n", optopt);
480 fprintf (stderr,
"SERVER: ERROR: Unknown " 481 "option character `\\x%x'.\n", optopt);
489 if (argc < (optind + 1))
491 fprintf (stderr,
"SERVER: ERROR: Insufficient number of arguments!\n");
495 if (sscanf (argv[optind],
"%d", &v) == 1)
499 fprintf (stderr,
"SERVER: ERROR: Invalid port (%s)!\n", argv[optind]);
512 perror (
"ERROR in main()");
513 fprintf (stderr,
"SERVER: ERROR: socket() failed " 514 "(errno = %d)!\n", errno_val);
518 memset (&servaddr, 0,
sizeof (servaddr));
522 struct sockaddr_in6 *server_addr = (
struct sockaddr_in6 *) &servaddr;
523 servaddr_size =
sizeof (*server_addr);
524 server_addr->sin6_family = AF_INET6;
525 server_addr->sin6_addr = in6addr_any;
526 server_addr->sin6_port = htons (port);
530 struct sockaddr_in *server_addr = (
struct sockaddr_in *) &servaddr;
531 servaddr_size =
sizeof (*server_addr);
532 server_addr->sin_family = AF_INET;
533 server_addr->sin_addr.s_addr = htonl (INADDR_ANY);
534 server_addr->sin_port = htons (port);
537 rv = bind (ssm->
listen_fd, (
struct sockaddr *) &servaddr, servaddr_size);
541 perror (
"ERROR bind returned");
542 fprintf (stderr,
"SERVER: ERROR: bind failed (errno = %d)!\n",
546 if (fcntl (ssm->
listen_fd, F_SETFL, O_NONBLOCK) < 0)
549 perror (
"ERROR fcntl returned");
550 fprintf (stderr,
"SERVER: ERROR: fcntl failed (errno = %d)!\n",
558 perror (
"ERROR in main()");
559 fprintf (stderr,
"SERVER: ERROR: listen failed " 560 "(errno = %d)!\n", errno_val);
564 ssm->
epfd = epoll_create (1);
568 perror (
"ERROR in main()");
569 fprintf (stderr,
"SERVER: ERROR: epoll_create failed (errno = %d)!\n",
581 perror (
"ERROR in main()");
582 fprintf (stderr,
"SERVER: ERROR: epoll_ctl failed " 583 "(errno = %d)!\n", errno_val);
587 printf (
"\nSERVER: Waiting for a client to connect on port %d...\n", port);
596 perror (
"epoll_wait()");
597 fprintf (stderr,
"\nSERVER: ERROR: epoll_wait() " 598 "failed -- aborting!\n");
604 fprintf (stderr,
"\nSERVER: epoll_wait() timeout!\n");
607 for (i = 0; i < num_ev; i++)
610 if (ssm->
wait_events[i].events & (EPOLLHUP | EPOLLRDHUP))
626 client_fd = conn->
fd;
640 printf (
"SERVER (fd %d): Received a cfg message!\n",
645 if (rx_bytes !=
sizeof (*rx_cfg))
647 printf (
"SERVER (fd %d): Invalid cfg message " 648 "size (%d)!\n Should be %lu bytes.\n",
649 client_fd, rx_bytes,
sizeof (*rx_cfg));
654 printf (
"SERVER (fd %d): Replying to " 655 "cfg message!\n", client_fd);
659 sizeof (conn->
cfg), NULL,
664 switch (rx_cfg->
test)
682 printf (
"SERVER: Have a great day, " 683 "connection %d!\n", client_fd);
686 printf (
"SERVER: Closed client fd %d\n", client_fd);
690 printf (
"SERVER: All client connections " 691 "closed.\n\nSERVER: " 692 "May the force be with you!\n\n");
699 "SERVER: ERROR: Unknown test type!\n");
710 if (ioctl (conn->
fd, FIONREAD))
715 else if (isascii (conn->
buf[0]))
718 ((
char *) conn->
buf)[rx_bytes <
721 printf (
"SERVER (fd %d): RX (%d bytes) - '%s'\n",
722 conn->
fd, rx_bytes, conn->
buf);
727 if (errno == ECONNRESET)
729 printf (
"\nSERVER: Connection reset by remote peer.\n" 730 " Y'all have a great day now!\n\n");
737 if (isascii (conn->
buf[0]))
742 ((
char *) conn->
buf)[rx_bytes <
746 fprintf (stderr,
"SERVER: ERROR: " 747 "FIFO not drained in previous test!\n" 748 " extra chunks %u (0x%x)\n" 749 " extra bytes %lu (0x%lx)\n",
750 xtra, xtra, xtra_bytes, xtra_bytes);
756 printf (
"SERVER (fd %d): Echoing back\n", client_fd);
758 nbytes = strlen ((
const char *) conn->
buf) + 1;
761 nbytes, &conn->
stats,
764 printf (
"SERVER (fd %d): TX (%d bytes) - '%s'\n",
765 conn->
fd, tx_bytes, conn->
buf);
771 xtra_bytes += rx_bytes;
static void new_client(void)
static int sock_test_read(int fd, uint8_t *buf, uint32_t nbytes, vcl_test_stats_t *stats)
static void conn_pool_expand(size_t expand_size)
#define SOCK_TEST_AF_UNIX_ACCEPT_DATA
Optimized string handling code, including c11-compliant "safe C library" variants.
static void sync_config_and_reply(sock_server_conn_t *conn, vcl_test_cfg_t *rx_cfg)
static void conn_pool_free(sock_server_conn_t *conn)
struct sockaddr_un serveraddr
#define VCL_TEST_SERVER_PORT
#define SOCK_TEST_BANNER_STRING
#define SOCK_TEST_AF_UNIX_FILENAME
static void vcl_test_stats_dump(char *header, vcl_test_stats_t *stats, uint8_t show_rx, uint8_t show_tx, uint8_t verbose)
static int sock_test_write(int fd, uint8_t *buf, uint32_t nbytes, vcl_test_stats_t *stats, uint32_t verbose)
#define SOCK_SERVER_MAX_TEST_CONN
#define VCL_TEST_SEPARATOR_STRING
static void vcl_test_cfg_dump(vcl_test_cfg_t *cfg, uint8_t is_client)
struct epoll_event listen_ev
static void stream_test_server_start_stop(sock_server_conn_t *conn, vcl_test_cfg_t *rx_cfg)
#define VCL_TEST_CFG_CTRL_MAGIC
struct epoll_event af_unix_listen_ev
sock_server_main_t sock_server_main
sll srl srl sll sra u16x4 i
static void vcl_test_cfg_init(vcl_test_cfg_t *cfg)
static void vcl_test_buf_alloc(vcl_test_cfg_t *cfg, uint8_t is_rxbuf, uint8_t **buf, uint32_t *bufsize)
#define SOCK_TEST_MIXED_EPOLL_DATA
static sock_server_conn_t * conn_pool_alloc(void)
void print_usage_and_exit(void)
static void af_unix_echo(void)
int main(int argc, char **argv)
#define SOCK_SERVER_MAX_EPOLL_EVENTS
static void vcl_test_stats_accumulate(vcl_test_stats_t *accum, vcl_test_stats_t *incr)
struct epoll_event wait_events[SOCK_SERVER_MAX_EPOLL_EVENTS]
sock_server_conn_t * conn_pool
static int socket_server_echo_af_unix_init(sock_server_main_t *ssm)
static void stream_test_server(sock_server_conn_t *conn, int rx_bytes)