aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/hs_apps/vcl/vcl_test_client.c
diff options
context:
space:
mode:
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>2019-05-16 14:38:44 +0200
committerFlorin Coras <florin.coras@gmail.com>2019-07-18 18:19:05 +0000
commit9fd996275c745faec2843cf3a8b1d15d6f8c9dab (patch)
tree01bd59cd9deea4994a33bce8bb4a2a7d7fa5c283 /src/plugins/hs_apps/vcl/vcl_test_client.c
parentcef02be220eff4aa32ec7ff56b1e0a552faa1280 (diff)
vcl: add QUIC support
Type: feature * Adds the concept of a "connectable listener" : a session that can be both connected and accepted on. * vppcom_session_is_connectable_listener (fd) that tells if the fd is a connectable listener * vppcom_session_listener (fd) that gives you the listener's fd that accepted the session (if any) * vppcom_session_n_accepted (fd) that gives the number of sessions a listener accepted. Change-Id: Id89d67d8339fb15a7cf7e00a9c5448175eca04fc Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Diffstat (limited to 'src/plugins/hs_apps/vcl/vcl_test_client.c')
-rw-r--r--src/plugins/hs_apps/vcl/vcl_test_client.c209
1 files changed, 168 insertions, 41 deletions
diff --git a/src/plugins/hs_apps/vcl/vcl_test_client.c b/src/plugins/hs_apps/vcl/vcl_test_client.c
index 1ead146aef5..b9bdd6eed55 100644
--- a/src/plugins/hs_apps/vcl/vcl_test_client.c
+++ b/src/plugins/hs_apps/vcl/vcl_test_client.c
@@ -28,7 +28,9 @@
typedef struct
{
vcl_test_session_t *sessions;
+ vcl_test_session_t *qsessions;
uint32_t n_sessions;
+ uint32_t n_qsessions;
uint32_t wrk_index;
fd_set wr_fdset;
fd_set rd_fdset;
@@ -42,11 +44,12 @@ typedef struct
vcl_test_client_worker_t *workers;
vppcom_endpt_t server_endpt;
uint32_t cfg_seq_num;
+ vcl_test_session_t quic_session;
vcl_test_session_t ctrl_session;
vcl_test_session_t *sessions;
uint8_t dump_cfg;
vcl_test_t post_test;
- uint32_t proto;
+ uint8_t proto;
uint32_t n_workers;
volatile int active_workers;
struct sockaddr_storage server_addr;
@@ -116,6 +119,105 @@ vtc_cfg_sync (vcl_test_session_t * ts)
}
static int
+vtc_quic_connect_test_sessions (vcl_test_client_worker_t * wrk)
+{
+ vcl_test_client_main_t *vcm = &vcl_client_main;
+ vcl_test_session_t *ts, *tq;
+ uint32_t i;
+ int rv;
+
+ if (wrk->cfg.num_test_sessions < 1 || wrk->cfg.num_test_sessions_perq < 1)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (wrk->n_sessions >= wrk->cfg.num_test_sessions)
+ goto done;
+
+ /* Connect Qsessions */
+
+ if (wrk->n_qsessions)
+ wrk->qsessions =
+ realloc (wrk->qsessions,
+ wrk->cfg.num_test_qsessions * sizeof (vcl_test_session_t));
+ else
+ wrk->qsessions =
+ calloc (wrk->cfg.num_test_qsessions, sizeof (vcl_test_session_t));
+
+ if (!wrk->qsessions)
+ {
+ vterr ("failed to alloc Qsessions", -errno);
+ return errno;
+ }
+
+
+ for (i = 0; i < wrk->cfg.num_test_qsessions; i++)
+ {
+ tq = &wrk->qsessions[i];
+ tq->fd = vppcom_session_create (vcm->proto, 1 /* is_nonblocking */ );
+ tq->session_index = i;
+ if (tq->fd < 0)
+ {
+ vterr ("vppcom_session_create()", tq->fd);
+ return tq->fd;
+ }
+
+ rv = vppcom_session_connect (tq->fd, &vcm->server_endpt);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_connect()", rv);
+ return rv;
+ }
+ vtinf ("Test Qsession %d (fd %d) connected.", i, tq->fd);
+ }
+ wrk->n_qsessions = wrk->cfg.num_test_qsessions;
+
+ /* Connect Stream sessions */
+
+ if (wrk->n_sessions)
+ wrk->sessions =
+ realloc (wrk->sessions,
+ wrk->cfg.num_test_sessions * sizeof (vcl_test_session_t));
+ else
+ wrk->sessions =
+ calloc (wrk->cfg.num_test_sessions, sizeof (vcl_test_session_t));
+
+ if (!wrk->sessions)
+ {
+ vterr ("failed to alloc sessions", -errno);
+ return errno;
+ }
+
+ for (i = 0; i < wrk->cfg.num_test_sessions; i++)
+ {
+ tq = &wrk->qsessions[i / wrk->cfg.num_test_sessions_perq];
+ ts = &wrk->sessions[i];
+ ts->fd = vppcom_session_create (vcm->proto, 1 /* is_nonblocking */ );
+ ts->session_index = i;
+ if (ts->fd < 0)
+ {
+ vterr ("vppcom_session_create()", ts->fd);
+ return ts->fd;
+ }
+
+ rv = vppcom_session_stream_connect (ts->fd, tq->fd);
+ if (rv < 0)
+ {
+ vterr ("vppcom_session_stream_connect()", rv);
+ return rv;
+ }
+
+ vtinf ("Test session %d (fd %d) connected.", i, ts->fd);
+ }
+ wrk->n_sessions = wrk->cfg.num_test_sessions;
+
+done:
+ vtinf ("All test sessions (%d) connected!", wrk->cfg.num_test_sessions);
+ return 0;
+}
+
+static int
vtc_connect_test_sessions (vcl_test_client_worker_t * wrk)
{
vcl_test_client_main_t *vcm = &vcl_client_main;
@@ -123,6 +225,9 @@ vtc_connect_test_sessions (vcl_test_client_worker_t * wrk)
uint32_t n_test_sessions;
int i, rv;
+ if (vcm->proto == VPPCOM_PROTO_QUIC)
+ return vtc_quic_connect_test_sessions (wrk);
+
n_test_sessions = wrk->cfg.num_test_sessions;
if (n_test_sessions < 1)
{
@@ -314,6 +419,7 @@ vtc_worker_sessions_exit (vcl_test_client_worker_t * wrk)
(void) vcl_test_write (ts->fd, (uint8_t *) & ts->cfg,
sizeof (ts->cfg), &ts->stats, verbose);
}
+
wrk->n_sessions = 0;
}
@@ -387,7 +493,6 @@ vtc_worker_loop (void *arg)
goto exit;
}
}
-
if ((!check_rx && ts->stats.tx_bytes >= ts->cfg.total_bytes)
|| (check_rx && ts->stats.rx_bytes >= ts->cfg.total_bytes))
{
@@ -710,6 +815,7 @@ print_usage_and_exit (void)
" -c Print test config before test.\n"
" -w <dir> Write test results to <dir>.\n"
" -X Exit after running test.\n"
+ " -p <proto> Use <proto> transport layer\n"
" -D Use UDP transport layer\n"
" -L Use TLS transport layer\n"
" -E Run Echo test.\n"
@@ -718,7 +824,10 @@ print_usage_and_exit (void)
" -T <txbuf-size> Test Cfg: tx buffer size.\n"
" -U Run Uni-directional test.\n"
" -B Run Bi-directional test.\n"
- " -V Verbose mode.\n");
+ " -V Verbose mode.\n"
+ " -I <N> Use N sessions.\n"
+ " -s <N> Use N sessions.\n"
+ " -q <n> QUIC : use N Ssessions on top of n Qsessions\n");
exit (1);
}
@@ -729,13 +838,14 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
int c, v;
opterr = 0;
- while ((c = getopt (argc, argv, "chn:w:XE:I:N:R:T:UBV6DL")) != -1)
+ while ((c = getopt (argc, argv, "chnp:w:XE:I:N:R:T:UBV6DLs:q:")) != -1)
switch (c)
{
case 'c':
vcm->dump_cfg = 1;
break;
+ case 'I': /* deprecated */
case 's':
if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions) != 1)
if (sscanf (optarg, "%u", &ctrl->cfg.num_test_sessions) != 1)
@@ -744,11 +854,30 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
print_usage_and_exit ();
}
if (!ctrl->cfg.num_test_sessions ||
- (ctrl->cfg.num_test_sessions > FD_SETSIZE))
+ (ctrl->cfg.num_test_sessions > VCL_TEST_CFG_MAX_TEST_SESS))
{
vtwrn ("Invalid number of sessions (%d) specified for option -%c!"
"\n Valid range is 1 - %d",
- ctrl->cfg.num_test_sessions, c, FD_SETSIZE);
+ ctrl->cfg.num_test_sessions, c,
+ VCL_TEST_CFG_MAX_TEST_SESS);
+ print_usage_and_exit ();
+ }
+ break;
+
+ case 'q':
+ if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions_perq) != 1)
+ if (sscanf (optarg, "%u", &ctrl->cfg.num_test_sessions_perq) != 1)
+ {
+ vtwrn ("Invalid value for option -%c!", c);
+ print_usage_and_exit ();
+ }
+ if (!ctrl->cfg.num_test_sessions_perq ||
+ (ctrl->cfg.num_test_sessions_perq > VCL_TEST_CFG_MAX_TEST_SESS))
+ {
+ vtwrn ("Invalid number of Stream sessions (%d) per Qsession"
+ "for option -%c!\nValid range is 1 - %d",
+ ctrl->cfg.num_test_sessions_perq, c,
+ VCL_TEST_CFG_MAX_TEST_SESS);
print_usage_and_exit ();
}
break;
@@ -778,21 +907,6 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
ctrl->cfg.test = VCL_TEST_TYPE_ECHO;
break;
- case 'I':
- if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions) != 1)
- if (sscanf (optarg, "%d", &ctrl->cfg.num_test_sessions) != 1)
- {
- vtwrn ("Invalid value for option -%c!", c);
- print_usage_and_exit ();
- }
- if (ctrl->cfg.num_test_sessions > VCL_TEST_CFG_MAX_TEST_SESS)
- {
- vtwrn ("value greater than max number test sessions (%d)!",
- VCL_TEST_CFG_MAX_TEST_SESS);
- print_usage_and_exit ();
- }
- break;
-
case 'N':
if (sscanf (optarg, "0x%lx", &ctrl->cfg.num_writes) != 1)
if (sscanf (optarg, "%ld", &ctrl->cfg.num_writes) != 1)
@@ -866,23 +980,30 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
ctrl->cfg.address_ip6 = 1;
break;
- case 'D':
- ctrl->cfg.transport_udp = 1;
+ case 'p':
+ if (vppcom_unformat_proto (&vcm->proto, optarg))
+ vtwrn ("Invalid vppcom protocol %s, defaulting to TCP", optarg);
break;
- case 'L':
- ctrl->cfg.transport_tls = 1;
+ case 'D': /* deprecated */
+ vcm->proto = VPPCOM_PROTO_UDP;
+ break;
+
+ case 'L': /* deprecated */
+ vcm->proto = VPPCOM_PROTO_TLS;
break;
case '?':
switch (optopt)
{
case 'E':
- case 'I':
+ case 'I': /* deprecated */
case 'N':
case 'R':
case 'T':
case 'w':
+ case 'p':
+ case 'q':
vtwrn ("Option -%c requires an argument.", optopt);
break;
@@ -904,18 +1025,9 @@ vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
print_usage_and_exit ();
}
- if (ctrl->cfg.transport_udp)
- {
- vcm->proto = VPPCOM_PROTO_UDP;
- }
- else if (ctrl->cfg.transport_tls)
- {
- vcm->proto = VPPCOM_PROTO_TLS;
- }
- else
- {
- vcm->proto = VPPCOM_PROTO_TCP;
- }
+ ctrl->cfg.num_test_qsessions = vcm->proto != VPPCOM_PROTO_QUIC ? 0 :
+ (ctrl->cfg.num_test_sessions + ctrl->cfg.num_test_sessions_perq - 1) /
+ ctrl->cfg.num_test_sessions_perq;
memset (&vcm->server_addr, 0, sizeof (vcm->server_addr));
if (ctrl->cfg.address_ip6)
@@ -985,6 +1097,7 @@ main (int argc, char **argv)
{
vcl_test_client_main_t *vcm = &vcl_client_main;
vcl_test_session_t *ctrl = &vcm->ctrl_session;
+ vcl_test_session_t *quic_session = &vcm->quic_session;
int rv;
vcm->n_workers = 1;
@@ -1001,7 +1114,7 @@ main (int argc, char **argv)
if (ctrl->fd < 0)
vtfail ("vppcom_session_create()", ctrl->fd);
- if (vcm->proto == VPPCOM_PROTO_TLS)
+ if (vcm->proto == VPPCOM_PROTO_TLS || vcm->proto == VPPCOM_PROTO_QUIC)
{
vtinf ("Adding tls certs ...");
vppcom_session_tls_add_cert (ctrl->fd, vcl_test_crt_rsa,
@@ -1011,7 +1124,20 @@ main (int argc, char **argv)
}
vtinf ("Connecting to server...");
- rv = vppcom_session_connect (ctrl->fd, &vcm->server_endpt);
+ if (vcm->proto == VPPCOM_PROTO_QUIC)
+ {
+ quic_session->fd = vppcom_session_create (vcm->proto,
+ 0 /* is_nonblocking */ );
+ if (quic_session->fd < 0)
+ vtfail ("vppcom_session_create()", quic_session->fd);
+ rv = vppcom_session_connect (quic_session->fd, &vcm->server_endpt);
+ if (rv)
+ vtfail ("vppcom_session_connect()", rv);
+ vtinf ("Connecting to stream...");
+ rv = vppcom_session_stream_connect (ctrl->fd, quic_session->fd);
+ }
+ else
+ rv = vppcom_session_connect (ctrl->fd, &vcm->server_endpt);
if (rv)
vtfail ("vppcom_session_connect()", rv);
vtinf ("Control session (fd %d) connected.", ctrl->fd);
@@ -1082,7 +1208,8 @@ main (int argc, char **argv)
}
vtc_ctrl_session_exit ();
- vppcom_session_close (ctrl->fd);
+ if (quic_session)
+ vppcom_session_close (quic_session->fd);
vppcom_app_destroy ();
free (vcm->workers);
return 0;