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, 0 );
162 vterr (
"vppcom_session_create()", tq->
fd);
170 vterr (
"vppcom_session_connect()", rv);
174 flen =
sizeof (
flags);
175 vppcom_session_attr (tq->
fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
176 vtinf (
"Test Qsession %d (fd %d) connected.", i, tq->
fd);
192 vterr (
"failed to alloc sessions", -errno);
200 ts->
fd = vppcom_session_create (vcm->
proto, 1 );
204 vterr (
"vppcom_session_create()", ts->
fd);
208 rv = vppcom_session_stream_connect (ts->
fd, tq->
fd);
211 vterr (
"vppcom_session_stream_connect()", rv);
215 vtinf (
"Test session %d (fd %d) connected.", i, ts->
fd);
229 uint32_t n_test_sessions;
230 uint32_t
flags, flen;
233 if (vcm->
proto == VPPCOM_PROTO_QUIC)
237 if (n_test_sessions < 1)
254 vterr (
"failed to alloc sessions", -errno);
258 for (i = 0; i < n_test_sessions; i++)
261 ts->
fd = vppcom_session_create (vcm->
proto, 0 );
264 vterr (
"vppcom_session_create()", ts->
fd);
272 vterr (
"vppcom_session_connect()", rv);
276 flen =
sizeof (
flags);
277 vppcom_session_attr (ts->
fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
278 vtinf (
"Test session %d (fd %d) connected.", i, ts->
fd);
283 vtinf (
"All test sessions (%d) connected!", n_test_sessions);
314 ts->
txbuf[j] = j & 0xff;
318 FD_SET (vppcom_session_index (ts->
fd), &wrk->
wr_fdset);
319 FD_SET (vppcom_session_index (ts->
fd), &wrk->
rd_fdset);
320 sidx = vppcom_session_index (ts->
fd);
343 if (vppcom_worker_register ())
345 vtwrn (
"failed to register worker");
353 vterr (
"vtc_connect_test_sessions ()", rv);
360 vtinf (
"Sending config to server on all sessions ...");
383 while (__sync_lock_test_and_set (&
stats_lock, 1))
397 snprintf (buf,
sizeof (buf),
"CLIENT (fd %d) RESULTS", ts->
fd);
425 vtinf (
"(fd %d): Sending exit cfg to server...", ts->
fd);
429 sizeof (ts->
cfg), &ts->
stats, verbose);
441 uint32_t n_active_sessions, n_bytes;
442 fd_set _wfdset, *wfdset = &_wfdset;
443 fd_set _rfdset, *rfdset = &_rfdset;
445 int i, rv, check_rx = 0;
450 vterr (
"vtc_worker_init()", rv);
454 vtinf (
"Starting test ...");
457 clock_gettime (CLOCK_REALTIME, &ctrl->
stats.
start);
461 while (n_active_sessions)
466 rv = vppcom_select (wrk->
max_fd_index, (
unsigned long *) rfdset,
467 (
unsigned long *) wfdset, NULL, 0);
470 vterr (
"vppcom_select()", rv);
483 if (FD_ISSET (vppcom_session_index (ts->
fd), rfdset)
490 if (FD_ISSET (vppcom_session_index (ts->
fd), wfdset)
495 n_bytes = strlen (ctrl->
txbuf) + 1;
500 vtwrn (
"vppcom_test_write (%d) failed -- aborting test",
508 clock_gettime (CLOCK_REALTIME, &ts->
stats.
stop);
542 vtinf (
" ctrl session info\n" 546 " rxbuf size: %u (0x%08x)\n" 548 " txbuf size: %u (0x%08x)\n" 550 ctrl->
fd, (uint32_t) ctrl->
fd,
556 snprintf (buf,
sizeof (buf),
"Echo");
558 snprintf (buf,
sizeof (buf),
"%s-directional Stream",
570 memset (&ctrl->
stats, 0, sizeof (ctrl->
stats));
592 uint32_t
i, n_conn, n_conn_per_wrk;
594 vtinf (
"%s-directional Stream Test Starting!",
601 vtwrn (
"test cfg sync failed -- aborting!");
605 memset (&ctrl->
stats, 0, sizeof (ctrl->
stats));
608 n_conn_per_wrk = n_conn / vcm->
n_workers;
629 vtinf (
"Sending config on ctrl session (fd %d) for stats...", ctrl->
fd);
632 vtwrn (
"test cfg sync failed -- aborting!");
641 vtwrn (
"post-test cfg sync failed!");
650 uint64_t txbuf_size = strtoull ((
const char *) p, NULL, 10);
661 vtwrn (
"Invalid txbuf size (%lu) < minimum buf size (%u)!",
671 uint32_t num_writes = strtoul ((
const char *) p, NULL, 10);
681 vtwrn (
"invalid num writes: %u", num_writes);
691 uint32_t num_test_sessions = strtoul ((
const char *) p, NULL, 10);
693 if ((num_test_sessions > 0) &&
701 vtwrn (
"invalid num test sessions: %u, (%d max)",
712 uint64_t rxbuf_size = strtoull ((
const char *) p, NULL, 10);
722 vtwrn (
"Invalid rxbuf size (%lu) < minimum buf size (%u)!",
794 "vcl_test_client [OPTIONS] <ipaddr> <port>\n" 796 " -h Print this message and exit.\n" 798 " -c Print test config before test.\n" 799 " -w <dir> Write test results to <dir>.\n" 800 " -X Exit after running test.\n" 801 " -p <proto> Use <proto> transport layer\n" 802 " -D Use UDP transport layer\n" 803 " -L Use TLS transport layer\n" 804 " -E Run Echo test.\n" 805 " -N <num-writes> Test Cfg: number of writes.\n" 806 " -R <rxbuf-size> Test Cfg: rx buffer size.\n" 807 " -T <txbuf-size> Test Cfg: tx buffer size.\n" 808 " -U Run Uni-directional test.\n" 809 " -B Run Bi-directional test.\n" 810 " -V Verbose mode.\n" 811 " -I <N> Use N sessions.\n" 812 " -s <N> Use N sessions.\n" 813 " -q <n> QUIC : use N Ssessions on top of n Qsessions\n");
824 while ((c = getopt (argc, argv,
"chnp:w:XE:I:N:R:T:UBV6DLs:q:")) != -1)
836 vtwrn (
"Invalid value for option -%c!", c);
842 vtwrn (
"Invalid number of sessions (%d) specified for option -%c!" 843 "\n Valid range is 1 - %d",
854 vtwrn (
"Invalid value for option -%c!", c);
860 vtwrn (
"Invalid number of Stream sessions (%d) per Qsession" 861 "for option -%c!\nValid range is 1 - %d",
869 if (sscanf (optarg,
"%d", &v) != 1)
871 vtwrn (
"Invalid value for option -%c!", c);
885 vtwrn (
"Option -%c value larger than txbuf size (%d)!",
897 vtwrn (
"Invalid value for option -%c!", c);
907 vtwrn (
"Invalid value for option -%c!", c);
914 (uint8_t **) & ctrl->
rxbuf,
919 vtwrn (
"rxbuf size (%lu) less than minumum (%u)",
930 vtwrn (
"Invalid value for option -%c!", c);
937 (uint8_t **) & ctrl->
txbuf,
944 vtwrn (
"txbuf size (%lu) less than minumum (%u)!",
967 if (vppcom_unformat_proto (&vcm->
proto, optarg))
968 vtwrn (
"Invalid vppcom protocol %s, defaulting to TCP", optarg);
972 vcm->
proto = VPPCOM_PROTO_UDP;
976 vcm->
proto = VPPCOM_PROTO_TLS;
990 vtwrn (
"Option -%c requires an argument.", optopt);
994 if (isprint (optopt))
995 vtwrn (
"Unknown option `-%c'.", optopt);
997 vtwrn (
"Unknown option character `\\x%x'.", optopt);
1005 if (argc < (optind + 2))
1007 vtwrn (
"Insufficient number of arguments!");
1018 struct sockaddr_in6 *sddr6 = (
struct sockaddr_in6 *) &vcm->
server_addr;
1019 sddr6->sin6_family = AF_INET6;
1020 inet_pton (AF_INET6, argv[optind++], &(sddr6->sin6_addr));
1021 sddr6->sin6_port = htons (atoi (argv[optind]));
1029 struct sockaddr_in *saddr4 = (
struct sockaddr_in *) &vcm->
server_addr;
1030 saddr4->sin_family = AF_INET;
1031 inet_pton (AF_INET, argv[optind++], &(saddr4->sin_addr));
1032 saddr4->sin_port = htons (atoi (argv[optind]));
1043 printf (
"\nType some characters and hit <return>\n" 1048 if (strlen (ctrl->
txbuf) == 1)
1050 printf (
"\nNothing to send! Please try again...\n");
1070 vtinf (
"(fd %d): Sending exit cfg to server...", ctrl->
fd);
1074 sizeof (ctrl->
cfg), &ctrl->
stats, verbose);
1092 rv = vppcom_app_create (
"vcl_test_client");
1094 vtfail (
"vppcom_app_create()", rv);
1096 ctrl->
fd = vppcom_session_create (vcm->
proto, 0 );
1098 vtfail (
"vppcom_session_create()", ctrl->
fd);
1100 if (vcm->
proto == VPPCOM_PROTO_TLS || vcm->
proto == VPPCOM_PROTO_QUIC)
1102 vtinf (
"Adding tls certs ...");
1109 vtinf (
"Connecting to server...");
1110 if (vcm->
proto == VPPCOM_PROTO_QUIC)
1112 quic_session->
fd = vppcom_session_create (vcm->
proto,
1114 if (quic_session->
fd < 0)
1115 vtfail (
"vppcom_session_create()", quic_session->
fd);
1116 rv = vppcom_session_connect (quic_session->
fd, &vcm->
server_endpt);
1118 vtfail (
"vppcom_session_connect()", rv);
1119 vtinf (
"Connecting to stream...");
1120 rv = vppcom_session_stream_connect (ctrl->
fd, quic_session->
fd);
1125 vtfail (
"vppcom_session_connect()", rv);
1126 vtinf (
"Control session (fd %d) connected.", ctrl->
fd);
1130 vtfail (
"vtc_cfg_sync()", rv);
1133 memset (&ctrl->
stats, 0, sizeof (ctrl->
stats));
1195 vppcom_session_close (quic_session->
fd);
1196 vppcom_app_destroy ();
#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
static void dump_help(void)
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
sll srl srl sll sra u16x4 i
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...)