20 #include <sys/types.h> 21 #include <sys/socket.h> 24 #include <arpa/inet.h> 55 struct sockaddr_storage server_addr;
58 static __thread
int __wrk_index = 0;
62 #define vtc_min(a, b) (a < b ? a : b) 63 #define vtc_max(a, b) (a > b ? a : b) 69 int rx_bytes, tx_bytes;
74 vtinf (
"(fd %d): Sending config to server.", ts->
fd);
81 vtwrn (
"(fd %d): write test cfg failed (%d)!", ts->
fd, tx_bytes);
92 vtwrn (
"(fd %d): Bad server reply cfg -- aborting!", ts->
fd);
98 vtwrn (
"(fd %d): Invalid config received from server!", ts->
fd);
101 vtinf (
"\tRx bytes %d != cfg size %lu", rx_bytes,
107 vtinf (
"(fd %d): Valid config sent to server.", ts->
fd);
114 vtinf (
"(fd %d): Got config back from server.", ts->
fd);
150 vterr (
"failed to alloc Qsessions", -errno);
158 tq->
fd = vppcom_session_create (vcm->
proto, 1 );
162 vterr (
"vppcom_session_create()", tq->
fd);
169 vterr (
"vppcom_session_connect()", rv);
172 vtinf (
"Test Qsession %d (fd %d) connected.", i, tq->
fd);
188 vterr (
"failed to alloc sessions", -errno);
196 ts->
fd = vppcom_session_create (vcm->
proto, 1 );
200 vterr (
"vppcom_session_create()", ts->
fd);
204 rv = vppcom_session_stream_connect (ts->
fd, tq->
fd);
207 vterr (
"vppcom_session_stream_connect()", rv);
211 vtinf (
"Test session %d (fd %d) connected.", i, ts->
fd);
225 uint32_t n_test_sessions;
228 if (vcm->
proto == VPPCOM_PROTO_QUIC)
232 if (n_test_sessions < 1)
249 vterr (
"failed to alloc sessions", -errno);
253 for (i = 0; i < n_test_sessions; i++)
256 ts->
fd = vppcom_session_create (vcm->
proto, 1 );
259 vterr (
"vppcom_session_create()", ts->
fd);
266 vterr (
"vppcom_session_connect()", rv);
269 vtinf (
"Test session %d (fd %d) connected.", i, ts->
fd);
274 vtinf (
"All test sessions (%d) connected!", n_test_sessions);
305 ts->
txbuf[j] = j & 0xff;
309 FD_SET (vppcom_session_index (ts->
fd), &wrk->
wr_fdset);
310 FD_SET (vppcom_session_index (ts->
fd), &wrk->
rd_fdset);
311 sidx = vppcom_session_index (ts->
fd);
334 if (vppcom_worker_register ())
336 vtwrn (
"failed to register worker");
344 vterr (
"vtc_connect_test_sessions ()", rv);
351 vtinf (
"Sending config to server on all sessions ...");
374 while (__sync_lock_test_and_set (&
stats_lock, 1))
388 sprintf (buf,
"CLIENT (fd %d) RESULTS", ts->
fd);
416 vtinf (
"(fd %d): Sending exit cfg to server...", ts->
fd);
420 sizeof (ts->
cfg), &ts->
stats, verbose);
432 uint32_t n_active_sessions, n_bytes;
433 fd_set _wfdset, *wfdset = &_wfdset;
434 fd_set _rfdset, *rfdset = &_rfdset;
436 int i, rv, check_rx = 0;
441 vterr (
"vtc_worker_init()", rv);
445 vtinf (
"Starting test ...");
448 clock_gettime (CLOCK_REALTIME, &ctrl->
stats.
start);
452 while (n_active_sessions)
457 rv = vppcom_select (wrk->
max_fd_index, (
unsigned long *) rfdset,
458 (
unsigned long *) wfdset,
NULL, 0);
461 vterr (
"vppcom_select()", rv);
474 if (FD_ISSET (vppcom_session_index (ts->
fd), rfdset)
481 if (FD_ISSET (vppcom_session_index (ts->
fd), wfdset)
486 n_bytes = strlen (ctrl->
txbuf) + 1;
491 vtwrn (
"vppcom_test_write (%d) failed -- aborting test",
499 clock_gettime (CLOCK_REALTIME, &ts->
stats.
stop);
533 vtinf (
" ctrl session info\n" 537 " rxbuf size: %u (0x%08x)\n" 539 " txbuf size: %u (0x%08x)\n" 541 ctrl->
fd, (uint32_t) ctrl->
fd,
547 sprintf (buf,
"Echo");
549 sprintf (buf,
"%s-directional Stream",
561 memset (&ctrl->
stats, 0, sizeof (ctrl->
stats));
583 uint32_t
i, n_conn, n_conn_per_wrk;
585 vtinf (
"%s-directional Stream Test Starting!",
592 vtwrn (
"test cfg sync failed -- aborting!");
596 memset (&ctrl->
stats, 0, sizeof (ctrl->
stats));
599 n_conn_per_wrk = n_conn / vcm->
n_workers;
620 vtinf (
"Sending config on ctrl session (fd %d) for stats...", ctrl->
fd);
623 vtwrn (
"test cfg sync failed -- aborting!");
632 vtwrn (
"post-test cfg sync failed!");
640 printf (
"CLIENT: Test configuration commands:" 642 "\t\t\tDisplay help." 644 "\t\t\tExit test client & server." 646 "\t\t\tShow the current test cfg." 648 "\t\t\tRun the Uni-directional test." 650 "\t\t\tRun the Bi-directional test." 652 "\t\t\tToggle verbose setting." 654 "<rxbuf size>\tRx buffer size (bytes)." 656 "<txbuf size>\tTx buffer size (bytes)." 658 "<# of writes>\tNumber of txbuf writes to server." "\n");
667 uint64_t txbuf_size = strtoull ((
const char *) p,
NULL, 10);
678 vtwrn (
"Invalid txbuf size (%lu) < minimum buf size (%u)!",
688 uint32_t num_writes = strtoul ((
const char *) p,
NULL, 10);
698 vtwrn (
"invalid num writes: %u", num_writes);
708 uint32_t num_test_sessions = strtoul ((
const char *) p,
NULL, 10);
710 if ((num_test_sessions > 0) &&
718 vtwrn (
"invalid num test sessions: %u, (%d max)",
729 uint64_t rxbuf_size = strtoull ((
const char *) p,
NULL, 10);
739 vtwrn (
"Invalid rxbuf size (%lu) < minimum buf size (%u)!",
811 "vcl_test_client [OPTIONS] <ipaddr> <port>\n" 813 " -h Print this message and exit.\n" 815 " -c Print test config before test.\n" 816 " -w <dir> Write test results to <dir>.\n" 817 " -X Exit after running test.\n" 818 " -p <proto> Use <proto> transport layer\n" 819 " -D Use UDP transport layer\n" 820 " -L Use TLS transport layer\n" 821 " -E Run Echo test.\n" 822 " -N <num-writes> Test Cfg: number of writes.\n" 823 " -R <rxbuf-size> Test Cfg: rx buffer size.\n" 824 " -T <txbuf-size> Test Cfg: tx buffer size.\n" 825 " -U Run Uni-directional test.\n" 826 " -B Run Bi-directional test.\n" 827 " -V Verbose mode.\n" 828 " -I <N> Use N sessions.\n" 829 " -s <N> Use N sessions.\n" 830 " -q <n> QUIC : use N Ssessions on top of n Qsessions\n");
841 while ((c = getopt (argc, argv,
"chnp:w:XE:I:N:R:T:UBV6DLs:q:")) != -1)
853 vtwrn (
"Invalid value for option -%c!", c);
859 vtwrn (
"Invalid number of sessions (%d) specified for option -%c!" 860 "\n Valid range is 1 - %d",
871 vtwrn (
"Invalid value for option -%c!", c);
877 vtwrn (
"Invalid number of Stream sessions (%d) per Qsession" 878 "for option -%c!\nValid range is 1 - %d",
886 if (sscanf (optarg,
"%d", &v) != 1)
888 vtwrn (
"Invalid value for option -%c!", c);
902 vtwrn (
"Option -%c value larger than txbuf size (%d)!",
906 strcpy (ctrl->
txbuf, optarg);
914 vtwrn (
"Invalid value for option -%c!", c);
924 vtwrn (
"Invalid value for option -%c!", c);
931 (uint8_t **) & ctrl->
rxbuf,
936 vtwrn (
"rxbuf size (%lu) less than minumum (%u)",
947 vtwrn (
"Invalid value for option -%c!", c);
954 (uint8_t **) & ctrl->
txbuf,
961 vtwrn (
"txbuf size (%lu) less than minumum (%u)!",
984 if (vppcom_unformat_proto (&vcm->
proto, optarg))
985 vtwrn (
"Invalid vppcom protocol %s, defaulting to TCP", optarg);
989 vcm->
proto = VPPCOM_PROTO_UDP;
993 vcm->
proto = VPPCOM_PROTO_TLS;
1007 vtwrn (
"Option -%c requires an argument.", optopt);
1011 if (isprint (optopt))
1012 vtwrn (
"Unknown option `-%c'.", optopt);
1014 vtwrn (
"Unknown option character `\\x%x'.", optopt);
1022 if (argc < (optind + 2))
1024 vtwrn (
"Insufficient number of arguments!");
1035 struct sockaddr_in6 *sddr6 = (
struct sockaddr_in6 *) &vcm->
server_addr;
1036 sddr6->sin6_family = AF_INET6;
1037 inet_pton (AF_INET6, argv[optind++], &(sddr6->sin6_addr));
1038 sddr6->sin6_port = htons (atoi (argv[optind]));
1046 struct sockaddr_in *saddr4 = (
struct sockaddr_in *) &vcm->
server_addr;
1047 saddr4->sin_family = AF_INET;
1048 inet_pton (AF_INET, argv[optind++], &(saddr4->sin_addr));
1049 saddr4->sin_port = htons (atoi (argv[optind]));
1060 printf (
"\nType some characters and hit <return>\n" 1065 if (strlen (ctrl->
txbuf) == 1)
1067 printf (
"\nNothing to send! Please try again...\n");
1087 vtinf (
"(fd %d): Sending exit cfg to server...", ctrl->
fd);
1091 sizeof (ctrl->
cfg), &ctrl->
stats, verbose);
1109 rv = vppcom_app_create (
"vcl_test_client");
1111 vtfail (
"vppcom_app_create()", rv);
1113 ctrl->
fd = vppcom_session_create (vcm->
proto, 0 );
1115 vtfail (
"vppcom_session_create()", ctrl->
fd);
1117 if (vcm->
proto == VPPCOM_PROTO_TLS || vcm->
proto == VPPCOM_PROTO_QUIC)
1119 vtinf (
"Adding tls certs ...");
1126 vtinf (
"Connecting to server...");
1127 if (vcm->
proto == VPPCOM_PROTO_QUIC)
1129 quic_session->
fd = vppcom_session_create (vcm->
proto,
1131 if (quic_session->
fd < 0)
1132 vtfail (
"vppcom_session_create()", quic_session->
fd);
1133 rv = vppcom_session_connect (quic_session->
fd, &vcm->
server_endpt);
1135 vtfail (
"vppcom_session_connect()", rv);
1136 vtinf (
"Connecting to stream...");
1137 rv = vppcom_session_stream_connect (ctrl->
fd, quic_session->
fd);
1142 vtfail (
"vppcom_session_connect()", rv);
1143 vtinf (
"Control session (fd %d) connected.", ctrl->
fd);
1147 vtfail (
"vtc_cfg_sync()", rv);
1150 memset (&ctrl->
stats, 0, sizeof (ctrl->
stats));
1212 vppcom_session_close (quic_session->
fd);
1213 vppcom_app_destroy ();
static void dump_help(void)
#define VCL_TEST_TOKEN_RXBUF_SIZE
uint32_t vcl_test_crt_rsa_len
int main(int argc, char **argv)
static vcl_test_t parse_input()
uint32_t num_test_qsessions
vcl_test_session_t ctrl_session
vcl_test_session_t quic_session
vcl_test_client_main_t vcl_client_main
uint32_t num_test_sessions
#define VCL_TEST_CFG_BUF_SIZE_MIN
#define VCL_TEST_DELAY_DISCONNECT
vcl_test_session_t * sessions
static void vtc_worker_sessions_exit(vcl_test_client_worker_t *wrk)
#define VCL_TEST_TOKEN_NUM_WRITES
#define VCL_TEST_TOKEN_SHOW_CFG
void print_usage_and_exit(void)
struct sockaddr_storage server_addr
volatile int active_workers
static int vtc_worker_test_setup(vcl_test_client_worker_t *wrk)
static void vtc_echo_client(vcl_test_client_main_t *vcm)
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 void * vtc_worker_loop(void *arg)
vppcom_endpt_t server_endpt
static void vtc_stream_client(vcl_test_client_main_t *vcm)
vcl_test_client_worker_t * workers
static int vtc_cfg_sync(vcl_test_session_t *ts)
static void cfg_num_writes_set(void)
#define VCL_TEST_SEPARATOR_STRING
static void vcl_test_session_buf_alloc(vcl_test_session_t *socket)
static void vcl_test_cfg_dump(vcl_test_cfg_t *cfg, uint8_t is_client)
static void cfg_txbuf_size_set(void)
vcl_test_session_t * qsessions
#define VCL_TEST_CFG_CTRL_MAGIC
vcl_test_session_t * sessions
#define VCL_TEST_TOKEN_RUN_BI
static void vcl_test_cfg_init(vcl_test_cfg_t *cfg)
#define VCL_TEST_TOKEN_TXBUF_SIZE
#define VCL_TEST_TOKEN_VERBOSE
static void cfg_rxbuf_size_set(void)
#define vt_atomic_add(_ptr, _val)
static void vtc_print_stats(vcl_test_session_t *ctrl)
uint32_t num_test_sessions_perq
#define VCL_TEST_TOKEN_HELP
#define vtinf(_fmt, _args...)
static void vcl_test_buf_alloc(vcl_test_cfg_t *cfg, uint8_t is_rxbuf, uint8_t **buf, uint32_t *bufsize)
static int vcl_test_read(int fd, uint8_t *buf, uint32_t nbytes, vcl_test_stats_t *stats)
static int vtc_quic_connect_test_sessions(vcl_test_client_worker_t *wrk)
static int vcl_test_write(int fd, uint8_t *buf, uint32_t nbytes, vcl_test_stats_t *stats, uint32_t verbose)
static void vtc_accumulate_stats(vcl_test_client_worker_t *wrk, vcl_test_session_t *ctrl)
uint32_t vcl_test_key_rsa_len
static int vtc_connect_test_sessions(vcl_test_client_worker_t *wrk)
#define VCL_TEST_TOKEN_RUN_UNI
static int vcl_comp_tspec(struct timespec *a, struct timespec *b)
static void vcl_test_stats_accumulate(vcl_test_stats_t *accum, vcl_test_stats_t *incr)
static void vtc_read_user_input(vcl_test_session_t *ctrl)
static int vtc_worker_init(vcl_test_client_worker_t *wrk)
static void cfg_verbose_toggle(void)
#define VCL_TEST_TOKEN_NUM_TEST_SESS
#define VCL_TEST_TOKEN_EXIT
static int vcl_test_cfg_verify(vcl_test_cfg_t *cfg, vcl_test_cfg_t *valid_cfg)
static void cfg_num_test_sessions_set(void)
static void vtc_ctrl_session_exit(void)
static void vtc_process_opts(vcl_test_client_main_t *vcm, int argc, char **argv)
#define VCL_TEST_CFG_MAX_TEST_SESS
#define vtwrn(_fmt, _args...)