blob: 06322a057f51f3252e53f2837705e4b7c3e110a5 [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Dave Wallacee4d5a652018-06-24 21:21:21 -04002 * Copyright (c) 2017-2018 Cisco and/or its affiliates.
Dave Wallace543852a2017-08-03 02:11:34 -04003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
Dave Wallacee4d5a652018-06-24 21:21:21 -040016#include <unistd.h>
17#include <errno.h>
18#include <stdlib.h>
19#include <ctype.h>
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <stdio.h>
23#include <time.h>
24#include <arpa/inet.h>
25#include <vcl/vcl_test.h>
Florin Coras6d4bb422018-09-04 22:07:27 -070026#include <pthread.h>
Dave Wallace543852a2017-08-03 02:11:34 -040027
Dave Wallacee4d5a652018-06-24 21:21:21 -040028typedef struct
29{
Florin Coras1502fc32018-10-05 00:50:30 -070030 vcl_test_session_t *sessions;
Florin Coras6d4bb422018-09-04 22:07:27 -070031 uint32_t n_sessions;
32 uint32_t wrk_index;
33 fd_set wr_fdset;
34 fd_set rd_fdset;
35 int max_fd_index;
36 pthread_t thread_handle;
Florin Coras1502fc32018-10-05 00:50:30 -070037 vcl_test_cfg_t cfg;
Florin Coras6d4bb422018-09-04 22:07:27 -070038} vcl_test_client_worker_t;
39
40typedef struct
41{
42 vcl_test_client_worker_t *workers;
Dave Wallacee4d5a652018-06-24 21:21:21 -040043 vppcom_endpt_t server_endpt;
Dave Wallacee4d5a652018-06-24 21:21:21 -040044 uint32_t cfg_seq_num;
Florin Coras1502fc32018-10-05 00:50:30 -070045 vcl_test_session_t ctrl_session;
46 vcl_test_session_t *sessions;
Dave Wallacee4d5a652018-06-24 21:21:21 -040047 uint8_t dump_cfg;
Florin Coras1502fc32018-10-05 00:50:30 -070048 vcl_test_t post_test;
Florin Coras6d4bb422018-09-04 22:07:27 -070049 uint32_t proto;
50 uint32_t n_workers;
51 volatile int active_workers;
52 struct sockaddr_storage server_addr;
53} vcl_test_client_main_t;
Dave Wallacee4d5a652018-06-24 21:21:21 -040054
Florin Coras6d4bb422018-09-04 22:07:27 -070055static __thread int __wrk_index = 0;
Dave Wallacee4d5a652018-06-24 21:21:21 -040056
Florin Coras6d4bb422018-09-04 22:07:27 -070057vcl_test_client_main_t vcl_client_main;
58
59#define vtc_min(a, b) (a < b ? a : b)
60#define vtc_max(a, b) (a > b ? a : b)
Dave Wallacee4d5a652018-06-24 21:21:21 -040061
62static int
Florin Coras1502fc32018-10-05 00:50:30 -070063vtc_cfg_sync (vcl_test_session_t * ts)
Dave Wallacee4d5a652018-06-24 21:21:21 -040064{
Florin Coras6d4bb422018-09-04 22:07:27 -070065 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -070066 vcl_test_cfg_t *rx_cfg = (vcl_test_cfg_t *) ts->rxbuf;
Dave Wallacee4d5a652018-06-24 21:21:21 -040067 int rx_bytes, tx_bytes;
68
Florin Coras1502fc32018-10-05 00:50:30 -070069 vt_atomic_add (&ts->cfg.seq_num, 1);
70 if (ts->cfg.verbose)
Dave Wallacee4d5a652018-06-24 21:21:21 -040071 {
Florin Coras1502fc32018-10-05 00:50:30 -070072 vtinf ("(fd %d): Sending config to server.", ts->fd);
73 vcl_test_cfg_dump (&ts->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -040074 }
Florin Coras1502fc32018-10-05 00:50:30 -070075 tx_bytes = vcl_test_write (ts->fd, (uint8_t *) & ts->cfg,
76 sizeof (ts->cfg), NULL, ts->cfg.verbose);
Dave Wallacee4d5a652018-06-24 21:21:21 -040077 if (tx_bytes < 0)
78 {
Florin Coras1502fc32018-10-05 00:50:30 -070079 vtwrn ("(fd %d): write test cfg failed (%d)!", ts->fd, tx_bytes);
Dave Wallacee4d5a652018-06-24 21:21:21 -040080 return tx_bytes;
81 }
82
Florin Coras1502fc32018-10-05 00:50:30 -070083 rx_bytes = vcl_test_read (ts->fd, (uint8_t *) ts->rxbuf,
84 sizeof (vcl_test_cfg_t), NULL);
Dave Wallacee4d5a652018-06-24 21:21:21 -040085 if (rx_bytes < 0)
86 return rx_bytes;
87
Florin Coras1502fc32018-10-05 00:50:30 -070088 if (rx_cfg->magic != VCL_TEST_CFG_CTRL_MAGIC)
Dave Wallacee4d5a652018-06-24 21:21:21 -040089 {
Florin Coras1502fc32018-10-05 00:50:30 -070090 vtwrn ("(fd %d): Bad server reply cfg -- aborting!", ts->fd);
Dave Wallacee4d5a652018-06-24 21:21:21 -040091 return -1;
92 }
Florin Coras1502fc32018-10-05 00:50:30 -070093 if ((rx_bytes != sizeof (vcl_test_cfg_t))
94 || !vcl_test_cfg_verify (rx_cfg, &ts->cfg))
Dave Wallacee4d5a652018-06-24 21:21:21 -040095 {
Florin Coras1502fc32018-10-05 00:50:30 -070096 vtwrn ("(fd %d): Invalid config received from server!", ts->fd);
97 if (rx_bytes != sizeof (vcl_test_cfg_t))
Dave Wallacee4d5a652018-06-24 21:21:21 -040098 {
Florin Coras6d4bb422018-09-04 22:07:27 -070099 vtinf ("\tRx bytes %d != cfg size %lu", rx_bytes,
Florin Coras1502fc32018-10-05 00:50:30 -0700100 sizeof (vcl_test_cfg_t));
Dave Wallacee4d5a652018-06-24 21:21:21 -0400101 }
102 else
103 {
Florin Coras1502fc32018-10-05 00:50:30 -0700104 vcl_test_cfg_dump (rx_cfg, 1 /* is_client */ );
105 vtinf ("(fd %d): Valid config sent to server.", ts->fd);
106 vcl_test_cfg_dump (&ts->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400107 }
108 return -1;
109 }
Florin Coras1502fc32018-10-05 00:50:30 -0700110 if (ts->cfg.verbose)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400111 {
Florin Coras1502fc32018-10-05 00:50:30 -0700112 vtinf ("(fd %d): Got config back from server.", ts->fd);
113 vcl_test_cfg_dump (rx_cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400114 }
Dave Wallacee4d5a652018-06-24 21:21:21 -0400115
116 return 0;
117}
118
Dave Wallacee4d5a652018-06-24 21:21:21 -0400119static int
Florin Coras6d4bb422018-09-04 22:07:27 -0700120vtc_connect_test_sessions (vcl_test_client_worker_t * wrk)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400121{
Florin Coras6d4bb422018-09-04 22:07:27 -0700122 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700123 vcl_test_session_t *ts;
Florin Coras6d4bb422018-09-04 22:07:27 -0700124 uint32_t n_test_sessions;
125 int i, rv;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400126
Florin Coras1502fc32018-10-05 00:50:30 -0700127 n_test_sessions = wrk->cfg.num_test_sessions;
Florin Coras6d4bb422018-09-04 22:07:27 -0700128 if (n_test_sessions < 1)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400129 {
130 errno = EINVAL;
131 return -1;
132 }
133
Florin Coras6d4bb422018-09-04 22:07:27 -0700134 if (wrk->n_sessions >= n_test_sessions)
135 goto done;
136
137 if (wrk->n_sessions)
138 wrk->sessions = realloc (wrk->sessions,
Florin Coras1502fc32018-10-05 00:50:30 -0700139 n_test_sessions * sizeof (vcl_test_session_t));
Florin Coras6d4bb422018-09-04 22:07:27 -0700140 else
Florin Coras1502fc32018-10-05 00:50:30 -0700141 wrk->sessions = calloc (n_test_sessions, sizeof (vcl_test_session_t));
Florin Coras6d4bb422018-09-04 22:07:27 -0700142
143 if (!wrk->sessions)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400144 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700145 vterr ("failed to alloc sessions", -errno);
146 return errno;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400147 }
148
Florin Coras6d4bb422018-09-04 22:07:27 -0700149 for (i = 0; i < n_test_sessions; i++)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400150 {
Florin Coras1502fc32018-10-05 00:50:30 -0700151 ts = &wrk->sessions[i];
152 ts->fd = vppcom_session_create (vcm->proto, 1 /* is_nonblocking */ );
153 if (ts->fd < 0)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400154 {
Florin Coras1502fc32018-10-05 00:50:30 -0700155 vterr ("vppcom_session_create()", ts->fd);
156 return ts->fd;
Florin Coras6d4bb422018-09-04 22:07:27 -0700157 }
158
Florin Coras1502fc32018-10-05 00:50:30 -0700159 rv = vppcom_session_connect (ts->fd, &vcm->server_endpt);
Florin Coras6d4bb422018-09-04 22:07:27 -0700160 if (rv < 0)
161 {
162 vterr ("vppcom_session_connect()", rv);
163 return rv;
164 }
Florin Coras1502fc32018-10-05 00:50:30 -0700165 vtinf ("Test session %d (fd %d) connected.", i, ts->fd);
Florin Coras6d4bb422018-09-04 22:07:27 -0700166 }
167 wrk->n_sessions = n_test_sessions;
168
169done:
170 vtinf ("All test sessions (%d) connected!", n_test_sessions);
171 return 0;
172}
173
174static int
175vtc_worker_test_setup (vcl_test_client_worker_t * wrk)
176{
177 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700178 vcl_test_session_t *ctrl = &vcm->ctrl_session;
179 vcl_test_cfg_t *cfg = &wrk->cfg;
180 vcl_test_session_t *ts;
Florin Coras6d4bb422018-09-04 22:07:27 -0700181 uint32_t sidx;
182 int i, j;
183
184 FD_ZERO (&wrk->wr_fdset);
185 FD_ZERO (&wrk->rd_fdset);
186
Florin Coras1502fc32018-10-05 00:50:30 -0700187 for (i = 0; i < cfg->num_test_sessions; i++)
Florin Coras6d4bb422018-09-04 22:07:27 -0700188 {
Florin Coras1502fc32018-10-05 00:50:30 -0700189 ts = &wrk->sessions[i];
190 ts->cfg = wrk->cfg;
191 vcl_test_session_buf_alloc (ts);
Florin Coras6d4bb422018-09-04 22:07:27 -0700192
193 switch (cfg->test)
194 {
Florin Coras1502fc32018-10-05 00:50:30 -0700195 case VCL_TEST_TYPE_ECHO:
196 memcpy (ts->txbuf, ctrl->txbuf, cfg->total_bytes);
Florin Coras6d4bb422018-09-04 22:07:27 -0700197 break;
Florin Coras1502fc32018-10-05 00:50:30 -0700198 case VCL_TEST_TYPE_UNI:
199 case VCL_TEST_TYPE_BI:
200 for (j = 0; j < ts->txbuf_size; j++)
201 ts->txbuf[j] = j & 0xff;
Florin Coras6d4bb422018-09-04 22:07:27 -0700202 break;
203 }
204
Florin Coras1502fc32018-10-05 00:50:30 -0700205 FD_SET (vppcom_session_index (ts->fd), &wrk->wr_fdset);
206 FD_SET (vppcom_session_index (ts->fd), &wrk->rd_fdset);
207 sidx = vppcom_session_index (ts->fd);
Florin Coras6d4bb422018-09-04 22:07:27 -0700208 wrk->max_fd_index = vtc_max (sidx, wrk->max_fd_index);
209 }
210 wrk->max_fd_index += 1;
211
212 return 0;
213}
214
215static int
216vtc_worker_init (vcl_test_client_worker_t * wrk)
217{
218 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700219 vcl_test_session_t *ctrl = &vcm->ctrl_session;
220 vcl_test_cfg_t *cfg = &wrk->cfg;
221 vcl_test_session_t *ts;
Florin Coras6d4bb422018-09-04 22:07:27 -0700222 uint32_t i, n;
223 int rv, nbytes;
224
225 __wrk_index = wrk->wrk_index;
226
Florin Coras1502fc32018-10-05 00:50:30 -0700227 vtinf ("Initializing worker %u ...", wrk->wrk_index);
Florin Coras6d4bb422018-09-04 22:07:27 -0700228
229 if (wrk->wrk_index)
230 {
231 if (vppcom_worker_register ())
232 {
233 vtwrn ("failed to register worker");
Dave Wallacee4d5a652018-06-24 21:21:21 -0400234 return -1;
235 }
Florin Coras6d4bb422018-09-04 22:07:27 -0700236 vt_atomic_add (&vcm->active_workers, 1);
237 }
238 rv = vtc_connect_test_sessions (wrk);
239 if (rv)
240 {
Florin Coras1502fc32018-10-05 00:50:30 -0700241 vterr ("vtc_connect_test_sessions ()", rv);
Florin Coras6d4bb422018-09-04 22:07:27 -0700242 return rv;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400243 }
244
Florin Coras6d4bb422018-09-04 22:07:27 -0700245 if (vtc_worker_test_setup (wrk))
246 return -1;
247
248 vtinf ("Sending config to server on all sessions ...");
249
Florin Coras1502fc32018-10-05 00:50:30 -0700250 for (n = 0; n < cfg->num_test_sessions; n++)
Florin Coras6d4bb422018-09-04 22:07:27 -0700251 {
Florin Coras1502fc32018-10-05 00:50:30 -0700252 ts = &wrk->sessions[n];
253 if (vtc_cfg_sync (ts))
Florin Coras6d4bb422018-09-04 22:07:27 -0700254 return -1;
Florin Coras1502fc32018-10-05 00:50:30 -0700255 memset (&ts->stats, 0, sizeof (ts->stats));
Florin Coras6d4bb422018-09-04 22:07:27 -0700256 }
257
Dave Wallacee4d5a652018-06-24 21:21:21 -0400258 return 0;
259}
260
Florin Coras21795132018-09-09 09:40:51 -0700261static int stats_lock = 0;
262
263static void
264vtc_accumulate_stats (vcl_test_client_worker_t * wrk,
Florin Coras1502fc32018-10-05 00:50:30 -0700265 vcl_test_session_t * ctrl)
Florin Coras21795132018-09-09 09:40:51 -0700266{
Florin Coras1502fc32018-10-05 00:50:30 -0700267 vcl_test_session_t *ts;
Florin Coras21795132018-09-09 09:40:51 -0700268 static char buf[64];
269 int i, show_rx = 0;
270
271 while (__sync_lock_test_and_set (&stats_lock, 1))
272 ;
273
Florin Coras1502fc32018-10-05 00:50:30 -0700274 if (ctrl->cfg.test == VCL_TEST_TYPE_BI
275 || ctrl->cfg.test == VCL_TEST_TYPE_ECHO)
Florin Coras21795132018-09-09 09:40:51 -0700276 show_rx = 1;
277
Florin Coras1502fc32018-10-05 00:50:30 -0700278 for (i = 0; i < wrk->cfg.num_test_sessions; i++)
Florin Coras21795132018-09-09 09:40:51 -0700279 {
Florin Coras1502fc32018-10-05 00:50:30 -0700280 ts = &wrk->sessions[i];
281 ts->stats.start = ctrl->stats.start;
Florin Coras21795132018-09-09 09:40:51 -0700282
283 if (ctrl->cfg.verbose > 1)
284 {
Florin Coras1502fc32018-10-05 00:50:30 -0700285 sprintf (buf, "CLIENT (fd %d) RESULTS", ts->fd);
286 vcl_test_stats_dump (buf, &ts->stats, show_rx, 1 /* show tx */ ,
287 ctrl->cfg.verbose);
Florin Coras21795132018-09-09 09:40:51 -0700288 }
289
Florin Coras1502fc32018-10-05 00:50:30 -0700290 vcl_test_stats_accumulate (&ctrl->stats, &ts->stats);
291 if (vcl_comp_tspec (&ctrl->stats.stop, &ts->stats.stop) < 0)
292 ctrl->stats.stop = ts->stats.stop;
Florin Coras21795132018-09-09 09:40:51 -0700293 }
294
295 __sync_lock_release (&stats_lock);
296}
297
298static void
299vtc_worker_sessions_exit (vcl_test_client_worker_t * wrk)
300{
301 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700302 vcl_test_session_t *ctrl = &vcm->ctrl_session;
303 vcl_test_session_t *ts;
Florin Coras21795132018-09-09 09:40:51 -0700304 int i, verbose = ctrl->cfg.verbose;
305
Florin Coras1502fc32018-10-05 00:50:30 -0700306 for (i = 0; i < wrk->cfg.num_test_sessions; i++)
Florin Coras21795132018-09-09 09:40:51 -0700307 {
Florin Coras1502fc32018-10-05 00:50:30 -0700308 ts = &wrk->sessions[i];
309 ts->cfg.test = VCL_TEST_TYPE_EXIT;
Florin Coras21795132018-09-09 09:40:51 -0700310
311 if (verbose)
312 {
Florin Coras1502fc32018-10-05 00:50:30 -0700313 vtinf ("(fd %d): Sending exit cfg to server...", ts->fd);
314 vcl_test_cfg_dump (&ts->cfg, 1 /* is_client */ );
Florin Coras21795132018-09-09 09:40:51 -0700315 }
Florin Coras1502fc32018-10-05 00:50:30 -0700316 (void) vcl_test_write (ts->fd, (uint8_t *) & ts->cfg,
317 sizeof (ts->cfg), &ts->stats, verbose);
Florin Coras21795132018-09-09 09:40:51 -0700318 }
Florin Coras2cba8532018-09-11 16:33:36 -0700319 wrk->n_sessions = 0;
Florin Coras21795132018-09-09 09:40:51 -0700320}
321
Florin Coras6d4bb422018-09-04 22:07:27 -0700322static void *
323vtc_worker_loop (void *arg)
324{
325 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700326 vcl_test_session_t *ctrl = &vcm->ctrl_session;
Florin Coras6d4bb422018-09-04 22:07:27 -0700327 vcl_test_client_worker_t *wrk = arg;
Florin Coras2cba8532018-09-11 16:33:36 -0700328 uint32_t n_active_sessions, n_bytes;
Florin Coras6d4bb422018-09-04 22:07:27 -0700329 fd_set _wfdset, *wfdset = &_wfdset;
330 fd_set _rfdset, *rfdset = &_rfdset;
Florin Coras1502fc32018-10-05 00:50:30 -0700331 vcl_test_session_t *ts;
Florin Coras6d4bb422018-09-04 22:07:27 -0700332 int i, rv, check_rx = 0;
333
334 rv = vtc_worker_init (wrk);
335 if (rv)
336 {
337 vterr ("vtc_worker_init()", rv);
338 return 0;
339 }
340
341 vtinf ("Starting test ...");
342
343 if (wrk->wrk_index == 0)
344 clock_gettime (CLOCK_REALTIME, &ctrl->stats.start);
345
Florin Coras1502fc32018-10-05 00:50:30 -0700346 check_rx = wrk->cfg.test != VCL_TEST_TYPE_UNI;
347 n_active_sessions = wrk->cfg.num_test_sessions;
Florin Coras6d4bb422018-09-04 22:07:27 -0700348 while (n_active_sessions)
349 {
350 _wfdset = wrk->wr_fdset;
351 _rfdset = wrk->rd_fdset;
352
David Johnsond9818dd2018-12-14 14:53:41 -0500353 rv = vppcom_select (wrk->max_fd_index, (unsigned long *) rfdset,
354 (unsigned long *) wfdset, NULL, 0);
Florin Coras6d4bb422018-09-04 22:07:27 -0700355 if (rv < 0)
356 {
357 vterr ("vppcom_select()", rv);
358 goto exit;
359 }
360 else if (rv == 0)
361 continue;
362
Florin Coras1502fc32018-10-05 00:50:30 -0700363 for (i = 0; i < wrk->cfg.num_test_sessions; i++)
Florin Coras6d4bb422018-09-04 22:07:27 -0700364 {
Florin Coras1502fc32018-10-05 00:50:30 -0700365 ts = &wrk->sessions[i];
366 if (!((ts->stats.stop.tv_sec == 0) &&
367 (ts->stats.stop.tv_nsec == 0)))
Florin Coras6d4bb422018-09-04 22:07:27 -0700368 continue;
369
Florin Coras1502fc32018-10-05 00:50:30 -0700370 if (FD_ISSET (vppcom_session_index (ts->fd), rfdset)
371 && ts->stats.rx_bytes < ts->cfg.total_bytes)
Florin Coras6d4bb422018-09-04 22:07:27 -0700372 {
Florin Coras1502fc32018-10-05 00:50:30 -0700373 (void) vcl_test_read (ts->fd, (uint8_t *) ts->rxbuf,
374 ts->rxbuf_size, &ts->stats);
Florin Coras6d4bb422018-09-04 22:07:27 -0700375 }
376
Florin Coras1502fc32018-10-05 00:50:30 -0700377 if (FD_ISSET (vppcom_session_index (ts->fd), wfdset)
378 && ts->stats.tx_bytes < ts->cfg.total_bytes)
Florin Coras6d4bb422018-09-04 22:07:27 -0700379 {
Florin Coras1502fc32018-10-05 00:50:30 -0700380 n_bytes = ts->cfg.txbuf_size;
381 if (ts->cfg.test == VCL_TEST_TYPE_ECHO)
Florin Coras2cba8532018-09-11 16:33:36 -0700382 n_bytes = strlen (ctrl->txbuf) + 1;
Florin Coras1502fc32018-10-05 00:50:30 -0700383 rv = vcl_test_write (ts->fd, (uint8_t *) ts->txbuf,
384 n_bytes, &ts->stats, ts->cfg.verbose);
Florin Coras6d4bb422018-09-04 22:07:27 -0700385 if (rv < 0)
386 {
387 vtwrn ("vppcom_test_write (%d) failed -- aborting test",
Florin Coras1502fc32018-10-05 00:50:30 -0700388 ts->fd);
Florin Coras6d4bb422018-09-04 22:07:27 -0700389 goto exit;
390 }
391 }
392
Florin Coras1502fc32018-10-05 00:50:30 -0700393 if ((!check_rx && ts->stats.tx_bytes >= ts->cfg.total_bytes)
394 || (check_rx && ts->stats.rx_bytes >= ts->cfg.total_bytes))
Florin Coras6d4bb422018-09-04 22:07:27 -0700395 {
Florin Coras1502fc32018-10-05 00:50:30 -0700396 clock_gettime (CLOCK_REALTIME, &ts->stats.stop);
Florin Coras6d4bb422018-09-04 22:07:27 -0700397 n_active_sessions--;
398 }
399 }
400 }
401exit:
Florin Coras21795132018-09-09 09:40:51 -0700402 vtinf ("Worker %d done ...", wrk->wrk_index);
Florin Coras1502fc32018-10-05 00:50:30 -0700403 if (wrk->cfg.test != VCL_TEST_TYPE_ECHO)
Florin Coras2cba8532018-09-11 16:33:36 -0700404 vtc_accumulate_stats (wrk, ctrl);
Florin Coras1502fc32018-10-05 00:50:30 -0700405 sleep (VCL_TEST_DELAY_DISCONNECT);
Florin Coras21795132018-09-09 09:40:51 -0700406 vtc_worker_sessions_exit (wrk);
Florin Coras6d4bb422018-09-04 22:07:27 -0700407 if (wrk->wrk_index)
408 vt_atomic_add (&vcm->active_workers, -1);
409 return 0;
410}
411
412static void
Florin Coras1502fc32018-10-05 00:50:30 -0700413vtc_print_stats (vcl_test_session_t * ctrl)
Florin Coras6d4bb422018-09-04 22:07:27 -0700414{
Florin Coras1502fc32018-10-05 00:50:30 -0700415 int is_echo = ctrl->cfg.test == VCL_TEST_TYPE_ECHO;
Florin Coras6d4bb422018-09-04 22:07:27 -0700416 int show_rx = 0;
417 char buf[64];
418
Florin Coras1502fc32018-10-05 00:50:30 -0700419 if (ctrl->cfg.test == VCL_TEST_TYPE_BI
420 || ctrl->cfg.test == VCL_TEST_TYPE_ECHO)
Florin Coras6d4bb422018-09-04 22:07:27 -0700421 show_rx = 1;
422
Florin Coras1502fc32018-10-05 00:50:30 -0700423 vcl_test_stats_dump ("CLIENT RESULTS", &ctrl->stats,
424 show_rx, 1 /* show tx */ ,
425 ctrl->cfg.verbose);
426 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Florin Coras6d4bb422018-09-04 22:07:27 -0700427
428 if (ctrl->cfg.verbose)
429 {
Florin Coras1502fc32018-10-05 00:50:30 -0700430 vtinf (" ctrl session info\n"
431 VCL_TEST_SEPARATOR_STRING
Florin Coras6d4bb422018-09-04 22:07:27 -0700432 " fd: %d (0x%08x)\n"
433 " rxbuf: %p\n"
434 " rxbuf size: %u (0x%08x)\n"
435 " txbuf: %p\n"
436 " txbuf size: %u (0x%08x)\n"
Florin Coras1502fc32018-10-05 00:50:30 -0700437 VCL_TEST_SEPARATOR_STRING,
Florin Coras6d4bb422018-09-04 22:07:27 -0700438 ctrl->fd, (uint32_t) ctrl->fd,
439 ctrl->rxbuf, ctrl->rxbuf_size, ctrl->rxbuf_size,
440 ctrl->txbuf, ctrl->txbuf_size, ctrl->txbuf_size);
441 }
442
443 if (is_echo)
444 sprintf (buf, "Echo");
445 else
446 sprintf (buf, "%s-directional Stream",
Florin Coras1502fc32018-10-05 00:50:30 -0700447 ctrl->cfg.test == VCL_TEST_TYPE_BI ? "Bi" : "Uni");
Florin Coras6d4bb422018-09-04 22:07:27 -0700448}
449
450static void
451vtc_echo_client (vcl_test_client_main_t * vcm)
452{
453 vcl_test_client_worker_t *wrk;
Florin Coras1502fc32018-10-05 00:50:30 -0700454 vcl_test_session_t *ctrl = &vcm->ctrl_session;
455 vcl_test_cfg_t *cfg = &ctrl->cfg;
Florin Coras6d4bb422018-09-04 22:07:27 -0700456
457 cfg->total_bytes = strlen (ctrl->txbuf) + 1;
458 memset (&ctrl->stats, 0, sizeof (ctrl->stats));
459
460 /* Echo works with only one worker */
461 wrk = vcm->workers;
462 wrk->wrk_index = 0;
463 wrk->cfg = *cfg;
464
465 vtc_worker_loop (wrk);
466
Florin Coras2cba8532018-09-11 16:33:36 -0700467 /* Not relevant for echo test
468 clock_gettime (CLOCK_REALTIME, &ctrl->stats.stop);
469 vtc_accumulate_stats (wrk, ctrl);
470 vtc_print_stats (ctrl);
471 */
Florin Coras6d4bb422018-09-04 22:07:27 -0700472}
473
474static void
475vtc_stream_client (vcl_test_client_main_t * vcm)
476{
Florin Coras1502fc32018-10-05 00:50:30 -0700477 vcl_test_session_t *ctrl = &vcm->ctrl_session;
478 vcl_test_cfg_t *cfg = &ctrl->cfg;
Florin Coras6d4bb422018-09-04 22:07:27 -0700479 vcl_test_client_worker_t *wrk;
Florin Coras1502fc32018-10-05 00:50:30 -0700480 vcl_test_session_t *ts;
Florin Coras6d4bb422018-09-04 22:07:27 -0700481 int tx_bytes, rv;
482 uint32_t i, n, sidx, n_conn, n_conn_per_wrk;
483
Florin Coras1502fc32018-10-05 00:50:30 -0700484 vtinf ("%s-directional Stream Test Starting!",
485 ctrl->cfg.test == VCL_TEST_TYPE_BI ? "Bi" : "Uni");
Florin Coras6d4bb422018-09-04 22:07:27 -0700486
487 cfg->total_bytes = cfg->num_writes * cfg->txbuf_size;
488 cfg->ctrl_handle = ~0;
489 if (vtc_cfg_sync (ctrl))
490 {
491 vtwrn ("test cfg sync failed -- aborting!");
492 return;
493 }
Florin Coras1502fc32018-10-05 00:50:30 -0700494 cfg->ctrl_handle = ((vcl_test_cfg_t *) ctrl->rxbuf)->ctrl_handle;
Florin Coras6d4bb422018-09-04 22:07:27 -0700495 memset (&ctrl->stats, 0, sizeof (ctrl->stats));
496
Florin Coras1502fc32018-10-05 00:50:30 -0700497 n_conn = cfg->num_test_sessions;
Florin Coras6d4bb422018-09-04 22:07:27 -0700498 n_conn_per_wrk = n_conn / vcm->n_workers;
499 for (i = 0; i < vcm->n_workers; i++)
500 {
501 wrk = &vcm->workers[i];
502 wrk->wrk_index = i;
503 wrk->cfg = ctrl->cfg;
Florin Coras1502fc32018-10-05 00:50:30 -0700504 wrk->cfg.num_test_sessions = vtc_min (n_conn_per_wrk, n_conn);
505 n_conn -= wrk->cfg.num_test_sessions;
Florin Coras6d4bb422018-09-04 22:07:27 -0700506 }
507
508 for (i = 1; i < vcm->n_workers; i++)
509 {
510 wrk = &vcm->workers[i];
511 pthread_create (&wrk->thread_handle, NULL, vtc_worker_loop,
512 (void *) wrk);
513 }
514 vtc_worker_loop (&vcm->workers[0]);
515
516 while (vcm->active_workers > 0)
517 ;
518
Florin Coras1502fc32018-10-05 00:50:30 -0700519 vtinf ("Sending config on ctrl session (fd %d) for stats...", ctrl->fd);
Florin Coras6d4bb422018-09-04 22:07:27 -0700520 if (vtc_cfg_sync (ctrl))
521 {
522 vtwrn ("test cfg sync failed -- aborting!");
523 return;
524 }
525
Florin Coras6d4bb422018-09-04 22:07:27 -0700526 vtc_print_stats (ctrl);
527
Florin Coras1502fc32018-10-05 00:50:30 -0700528 ctrl->cfg.test = VCL_TEST_TYPE_ECHO;
Florin Coras6d4bb422018-09-04 22:07:27 -0700529 ctrl->cfg.total_bytes = 0;
530 if (vtc_cfg_sync (ctrl))
531 vtwrn ("post-test cfg sync failed!");
532}
533
534static void
Dave Wallacee4d5a652018-06-24 21:21:21 -0400535dump_help (void)
536{
537#define INDENT "\n "
538
539 printf ("CLIENT: Test configuration commands:"
Florin Coras1502fc32018-10-05 00:50:30 -0700540 INDENT VCL_TEST_TOKEN_HELP
Dave Wallacee4d5a652018-06-24 21:21:21 -0400541 "\t\t\tDisplay help."
Florin Coras1502fc32018-10-05 00:50:30 -0700542 INDENT VCL_TEST_TOKEN_EXIT
Dave Wallacee4d5a652018-06-24 21:21:21 -0400543 "\t\t\tExit test client & server."
Florin Coras1502fc32018-10-05 00:50:30 -0700544 INDENT VCL_TEST_TOKEN_SHOW_CFG
Dave Wallacee4d5a652018-06-24 21:21:21 -0400545 "\t\t\tShow the current test cfg."
Florin Coras1502fc32018-10-05 00:50:30 -0700546 INDENT VCL_TEST_TOKEN_RUN_UNI
Dave Wallacee4d5a652018-06-24 21:21:21 -0400547 "\t\t\tRun the Uni-directional test."
Florin Coras1502fc32018-10-05 00:50:30 -0700548 INDENT VCL_TEST_TOKEN_RUN_BI
Dave Wallacee4d5a652018-06-24 21:21:21 -0400549 "\t\t\tRun the Bi-directional test."
Florin Coras1502fc32018-10-05 00:50:30 -0700550 INDENT VCL_TEST_TOKEN_VERBOSE
Dave Wallacee4d5a652018-06-24 21:21:21 -0400551 "\t\t\tToggle verbose setting."
Florin Coras1502fc32018-10-05 00:50:30 -0700552 INDENT VCL_TEST_TOKEN_RXBUF_SIZE
Dave Wallacee4d5a652018-06-24 21:21:21 -0400553 "<rxbuf size>\tRx buffer size (bytes)."
Florin Coras1502fc32018-10-05 00:50:30 -0700554 INDENT VCL_TEST_TOKEN_TXBUF_SIZE
Dave Wallacee4d5a652018-06-24 21:21:21 -0400555 "<txbuf size>\tTx buffer size (bytes)."
Florin Coras1502fc32018-10-05 00:50:30 -0700556 INDENT VCL_TEST_TOKEN_NUM_WRITES
Dave Wallacee4d5a652018-06-24 21:21:21 -0400557 "<# of writes>\tNumber of txbuf writes to server." "\n");
558}
559
560static void
561cfg_txbuf_size_set (void)
562{
Florin Coras6d4bb422018-09-04 22:07:27 -0700563 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700564 vcl_test_session_t *ctrl = &vcm->ctrl_session;
565 char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_TXBUF_SIZE);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400566 uint64_t txbuf_size = strtoull ((const char *) p, NULL, 10);
567
Florin Coras1502fc32018-10-05 00:50:30 -0700568 if (txbuf_size >= VCL_TEST_CFG_BUF_SIZE_MIN)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400569 {
570 ctrl->cfg.txbuf_size = txbuf_size;
571 ctrl->cfg.total_bytes = ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
Florin Coras1502fc32018-10-05 00:50:30 -0700572 vcl_test_buf_alloc (&ctrl->cfg, 0 /* is_rxbuf */ ,
573 (uint8_t **) & ctrl->txbuf, &ctrl->txbuf_size);
574 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400575 }
576 else
Florin Coras1502fc32018-10-05 00:50:30 -0700577 vtwrn ("Invalid txbuf size (%lu) < minimum buf size (%u)!",
578 txbuf_size, VCL_TEST_CFG_BUF_SIZE_MIN);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400579}
580
581static void
582cfg_num_writes_set (void)
583{
Florin Coras6d4bb422018-09-04 22:07:27 -0700584 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700585 vcl_test_session_t *ctrl = &vcm->ctrl_session;
586 char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_NUM_WRITES);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400587 uint32_t num_writes = strtoul ((const char *) p, NULL, 10);
588
589 if (num_writes > 0)
590 {
591 ctrl->cfg.num_writes = num_writes;
592 ctrl->cfg.total_bytes = ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
Florin Coras1502fc32018-10-05 00:50:30 -0700593 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400594 }
595 else
596 {
Florin Coras1502fc32018-10-05 00:50:30 -0700597 vtwrn ("invalid num writes: %u", num_writes);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400598 }
599}
600
601static void
Florin Coras1502fc32018-10-05 00:50:30 -0700602cfg_num_test_sessions_set (void)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400603{
Florin Coras6d4bb422018-09-04 22:07:27 -0700604 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700605 vcl_test_session_t *ctrl = &vcm->ctrl_session;
606 char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_NUM_TEST_SESS);
607 uint32_t num_test_sessions = strtoul ((const char *) p, NULL, 10);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400608
Florin Coras1502fc32018-10-05 00:50:30 -0700609 if ((num_test_sessions > 0) &&
610 (num_test_sessions <= VCL_TEST_CFG_MAX_TEST_SESS))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400611 {
Florin Coras1502fc32018-10-05 00:50:30 -0700612 ctrl->cfg.num_test_sessions = num_test_sessions;
613 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400614 }
615 else
616 {
Florin Coras1502fc32018-10-05 00:50:30 -0700617 vtwrn ("invalid num test sessions: %u, (%d max)",
618 num_test_sessions, VCL_TEST_CFG_MAX_TEST_SESS);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400619 }
620}
621
622static void
623cfg_rxbuf_size_set (void)
624{
Florin Coras6d4bb422018-09-04 22:07:27 -0700625 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700626 vcl_test_session_t *ctrl = &vcm->ctrl_session;
627 char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_RXBUF_SIZE);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400628 uint64_t rxbuf_size = strtoull ((const char *) p, NULL, 10);
629
Florin Coras1502fc32018-10-05 00:50:30 -0700630 if (rxbuf_size >= VCL_TEST_CFG_BUF_SIZE_MIN)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400631 {
632 ctrl->cfg.rxbuf_size = rxbuf_size;
Florin Coras1502fc32018-10-05 00:50:30 -0700633 vcl_test_buf_alloc (&ctrl->cfg, 1 /* is_rxbuf */ ,
634 (uint8_t **) & ctrl->rxbuf, &ctrl->rxbuf_size);
635 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400636 }
637 else
Florin Coras1502fc32018-10-05 00:50:30 -0700638 vtwrn ("Invalid rxbuf size (%lu) < minimum buf size (%u)!",
639 rxbuf_size, VCL_TEST_CFG_BUF_SIZE_MIN);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400640}
641
642static void
643cfg_verbose_toggle (void)
644{
Florin Coras6d4bb422018-09-04 22:07:27 -0700645 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700646 vcl_test_session_t *ctrl = &vcm->ctrl_session;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400647
648 ctrl->cfg.verbose = ctrl->cfg.verbose ? 0 : 1;
Florin Coras1502fc32018-10-05 00:50:30 -0700649 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Dave Wallacee4d5a652018-06-24 21:21:21 -0400650
651}
652
Florin Coras1502fc32018-10-05 00:50:30 -0700653static vcl_test_t
Dave Wallacee4d5a652018-06-24 21:21:21 -0400654parse_input ()
655{
Florin Coras6d4bb422018-09-04 22:07:27 -0700656 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700657 vcl_test_session_t *ctrl = &vcm->ctrl_session;
658 vcl_test_t rv = VCL_TEST_TYPE_NONE;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400659
Florin Coras1502fc32018-10-05 00:50:30 -0700660 if (!strncmp (VCL_TEST_TOKEN_EXIT, ctrl->txbuf,
661 strlen (VCL_TEST_TOKEN_EXIT)))
662 rv = VCL_TEST_TYPE_EXIT;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400663
Florin Coras1502fc32018-10-05 00:50:30 -0700664 else if (!strncmp (VCL_TEST_TOKEN_HELP, ctrl->txbuf,
665 strlen (VCL_TEST_TOKEN_HELP)))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400666 dump_help ();
667
Florin Coras1502fc32018-10-05 00:50:30 -0700668 else if (!strncmp (VCL_TEST_TOKEN_SHOW_CFG, ctrl->txbuf,
669 strlen (VCL_TEST_TOKEN_SHOW_CFG)))
Florin Coras6d4bb422018-09-04 22:07:27 -0700670 vcm->dump_cfg = 1;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400671
Florin Coras1502fc32018-10-05 00:50:30 -0700672 else if (!strncmp (VCL_TEST_TOKEN_VERBOSE, ctrl->txbuf,
673 strlen (VCL_TEST_TOKEN_VERBOSE)))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400674 cfg_verbose_toggle ();
675
Florin Coras1502fc32018-10-05 00:50:30 -0700676 else if (!strncmp (VCL_TEST_TOKEN_TXBUF_SIZE, ctrl->txbuf,
677 strlen (VCL_TEST_TOKEN_TXBUF_SIZE)))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400678 cfg_txbuf_size_set ();
679
Florin Coras1502fc32018-10-05 00:50:30 -0700680 else if (!strncmp (VCL_TEST_TOKEN_NUM_TEST_SESS, ctrl->txbuf,
681 strlen (VCL_TEST_TOKEN_NUM_TEST_SESS)))
682 cfg_num_test_sessions_set ();
Dave Wallacee4d5a652018-06-24 21:21:21 -0400683
Florin Coras1502fc32018-10-05 00:50:30 -0700684 else if (!strncmp (VCL_TEST_TOKEN_NUM_WRITES, ctrl->txbuf,
685 strlen (VCL_TEST_TOKEN_NUM_WRITES)))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400686 cfg_num_writes_set ();
687
Florin Coras1502fc32018-10-05 00:50:30 -0700688 else if (!strncmp (VCL_TEST_TOKEN_RXBUF_SIZE, ctrl->txbuf,
689 strlen (VCL_TEST_TOKEN_RXBUF_SIZE)))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400690 cfg_rxbuf_size_set ();
691
Florin Coras1502fc32018-10-05 00:50:30 -0700692 else if (!strncmp (VCL_TEST_TOKEN_RUN_UNI, ctrl->txbuf,
693 strlen (VCL_TEST_TOKEN_RUN_UNI)))
694 rv = ctrl->cfg.test = VCL_TEST_TYPE_UNI;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400695
Florin Coras1502fc32018-10-05 00:50:30 -0700696 else if (!strncmp (VCL_TEST_TOKEN_RUN_BI, ctrl->txbuf,
697 strlen (VCL_TEST_TOKEN_RUN_BI)))
698 rv = ctrl->cfg.test = VCL_TEST_TYPE_BI;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400699
700 else
Florin Coras1502fc32018-10-05 00:50:30 -0700701 rv = VCL_TEST_TYPE_ECHO;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400702
703 return rv;
704}
705
706void
707print_usage_and_exit (void)
708{
709 fprintf (stderr,
Florin Coras1502fc32018-10-05 00:50:30 -0700710 "vcl_test_client [OPTIONS] <ipaddr> <port>\n"
Dave Wallacee4d5a652018-06-24 21:21:21 -0400711 " OPTIONS\n"
712 " -h Print this message and exit.\n"
713 " -6 Use IPv6\n"
Dave Wallacee4d5a652018-06-24 21:21:21 -0400714 " -c Print test config before test.\n"
715 " -w <dir> Write test results to <dir>.\n"
716 " -X Exit after running test.\n"
Ping Yu34a3a082018-11-30 19:16:17 -0500717 " -D Use UDP transport layer\n"
718 " -S Use TLS transport layer\n"
Dave Wallacee4d5a652018-06-24 21:21:21 -0400719 " -E Run Echo test.\n"
720 " -N <num-writes> Test Cfg: number of writes.\n"
721 " -R <rxbuf-size> Test Cfg: rx buffer size.\n"
722 " -T <txbuf-size> Test Cfg: tx buffer size.\n"
723 " -U Run Uni-directional test.\n"
724 " -B Run Bi-directional test.\n"
725 " -V Verbose mode.\n");
726 exit (1);
727}
728
Florin Coras6d4bb422018-09-04 22:07:27 -0700729static void
730vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400731{
Florin Coras1502fc32018-10-05 00:50:30 -0700732 vcl_test_session_t *ctrl = &vcm->ctrl_session;
Florin Coras6d4bb422018-09-04 22:07:27 -0700733 int c, v;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400734
735 opterr = 0;
Ping Yu34a3a082018-11-30 19:16:17 -0500736 while ((c = getopt (argc, argv, "chn:w:XE:I:N:R:T:UBV6DS")) != -1)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400737 switch (c)
738 {
739 case 'c':
Florin Coras6d4bb422018-09-04 22:07:27 -0700740 vcm->dump_cfg = 1;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400741 break;
742
743 case 's':
Florin Coras1502fc32018-10-05 00:50:30 -0700744 if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions) != 1)
745 if (sscanf (optarg, "%u", &ctrl->cfg.num_test_sessions) != 1)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400746 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700747 vtwrn ("Invalid value for option -%c!", c);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400748 print_usage_and_exit ();
749 }
Florin Coras1502fc32018-10-05 00:50:30 -0700750 if (!ctrl->cfg.num_test_sessions ||
751 (ctrl->cfg.num_test_sessions > FD_SETSIZE))
Dave Wallacee4d5a652018-06-24 21:21:21 -0400752 {
Florin Coras1502fc32018-10-05 00:50:30 -0700753 vtwrn ("Invalid number of sessions (%d) specified for option -%c!"
Florin Coras6d4bb422018-09-04 22:07:27 -0700754 "\n Valid range is 1 - %d",
Florin Coras1502fc32018-10-05 00:50:30 -0700755 ctrl->cfg.num_test_sessions, c, FD_SETSIZE);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400756 print_usage_and_exit ();
757 }
758 break;
759
760 case 'w':
Florin Coras6d4bb422018-09-04 22:07:27 -0700761 if (sscanf (optarg, "%d", &v) != 1)
762 {
763 vtwrn ("Invalid value for option -%c!", c);
764 print_usage_and_exit ();
765 }
766 if (v > 1)
767 vcm->n_workers = v;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400768 break;
769
770 case 'X':
Florin Coras1502fc32018-10-05 00:50:30 -0700771 vcm->post_test = VCL_TEST_TYPE_EXIT;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400772 break;
773
774 case 'E':
775 if (strlen (optarg) > ctrl->txbuf_size)
776 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700777 vtwrn ("Option -%c value larger than txbuf size (%d)!",
778 optopt, ctrl->txbuf_size);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400779 print_usage_and_exit ();
780 }
781 strcpy (ctrl->txbuf, optarg);
Florin Coras1502fc32018-10-05 00:50:30 -0700782 ctrl->cfg.test = VCL_TEST_TYPE_ECHO;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400783 break;
784
785 case 'I':
Florin Coras1502fc32018-10-05 00:50:30 -0700786 if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions) != 1)
787 if (sscanf (optarg, "%d", &ctrl->cfg.num_test_sessions) != 1)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400788 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700789 vtwrn ("Invalid value for option -%c!", c);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400790 print_usage_and_exit ();
791 }
Florin Coras1502fc32018-10-05 00:50:30 -0700792 if (ctrl->cfg.num_test_sessions > VCL_TEST_CFG_MAX_TEST_SESS)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400793 {
Florin Coras1502fc32018-10-05 00:50:30 -0700794 vtwrn ("value greater than max number test sessions (%d)!",
795 VCL_TEST_CFG_MAX_TEST_SESS);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400796 print_usage_and_exit ();
797 }
798 break;
799
800 case 'N':
801 if (sscanf (optarg, "0x%lx", &ctrl->cfg.num_writes) != 1)
802 if (sscanf (optarg, "%ld", &ctrl->cfg.num_writes) != 1)
803 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700804 vtwrn ("Invalid value for option -%c!", c);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400805 print_usage_and_exit ();
806 }
807 ctrl->cfg.total_bytes = ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
808 break;
809
810 case 'R':
811 if (sscanf (optarg, "0x%lx", &ctrl->cfg.rxbuf_size) != 1)
812 if (sscanf (optarg, "%ld", &ctrl->cfg.rxbuf_size) != 1)
813 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700814 vtwrn ("Invalid value for option -%c!", c);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400815 print_usage_and_exit ();
816 }
Florin Coras1502fc32018-10-05 00:50:30 -0700817 if (ctrl->cfg.rxbuf_size >= VCL_TEST_CFG_BUF_SIZE_MIN)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400818 {
819 ctrl->rxbuf_size = ctrl->cfg.rxbuf_size;
Florin Coras1502fc32018-10-05 00:50:30 -0700820 vcl_test_buf_alloc (&ctrl->cfg, 1 /* is_rxbuf */ ,
821 (uint8_t **) & ctrl->rxbuf,
822 &ctrl->rxbuf_size);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400823 }
824 else
825 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700826 vtwrn ("rxbuf size (%lu) less than minumum (%u)",
Florin Coras1502fc32018-10-05 00:50:30 -0700827 ctrl->cfg.rxbuf_size, VCL_TEST_CFG_BUF_SIZE_MIN);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400828 print_usage_and_exit ();
829 }
830
831 break;
832
833 case 'T':
834 if (sscanf (optarg, "0x%lx", &ctrl->cfg.txbuf_size) != 1)
835 if (sscanf (optarg, "%ld", &ctrl->cfg.txbuf_size) != 1)
836 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700837 vtwrn ("Invalid value for option -%c!", c);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400838 print_usage_and_exit ();
839 }
Florin Coras1502fc32018-10-05 00:50:30 -0700840 if (ctrl->cfg.txbuf_size >= VCL_TEST_CFG_BUF_SIZE_MIN)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400841 {
842 ctrl->txbuf_size = ctrl->cfg.txbuf_size;
Florin Coras1502fc32018-10-05 00:50:30 -0700843 vcl_test_buf_alloc (&ctrl->cfg, 0 /* is_rxbuf */ ,
844 (uint8_t **) & ctrl->txbuf,
845 &ctrl->txbuf_size);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400846 ctrl->cfg.total_bytes =
847 ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
848 }
849 else
850 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700851 vtwrn ("txbuf size (%lu) less than minumum (%u)!",
Florin Coras1502fc32018-10-05 00:50:30 -0700852 ctrl->cfg.txbuf_size, VCL_TEST_CFG_BUF_SIZE_MIN);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400853 print_usage_and_exit ();
854 }
855 break;
856
857 case 'U':
Florin Coras1502fc32018-10-05 00:50:30 -0700858 ctrl->cfg.test = VCL_TEST_TYPE_UNI;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400859 break;
860
861 case 'B':
Florin Coras1502fc32018-10-05 00:50:30 -0700862 ctrl->cfg.test = VCL_TEST_TYPE_BI;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400863 break;
864
865 case 'V':
866 ctrl->cfg.verbose = 1;
867 break;
868
869 case '6':
870 ctrl->cfg.address_ip6 = 1;
871 break;
872
873 case 'D':
874 ctrl->cfg.transport_udp = 1;
875 break;
876
Ping Yu34a3a082018-11-30 19:16:17 -0500877 case 'S':
878 ctrl->cfg.transport_tls = 1;
879 break;
880
Dave Wallacee4d5a652018-06-24 21:21:21 -0400881 case '?':
882 switch (optopt)
883 {
884 case 'E':
885 case 'I':
886 case 'N':
887 case 'R':
888 case 'T':
889 case 'w':
Florin Coras6d4bb422018-09-04 22:07:27 -0700890 vtwrn ("Option -%c requires an argument.", optopt);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400891 break;
892
893 default:
894 if (isprint (optopt))
Florin Coras6d4bb422018-09-04 22:07:27 -0700895 vtwrn ("Unknown option `-%c'.", optopt);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400896 else
Florin Coras6d4bb422018-09-04 22:07:27 -0700897 vtwrn ("Unknown option character `\\x%x'.", optopt);
Dave Wallacee4d5a652018-06-24 21:21:21 -0400898 }
899 /* fall thru */
900 case 'h':
901 default:
902 print_usage_and_exit ();
903 }
904
905 if (argc < (optind + 2))
906 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700907 vtwrn ("Insufficient number of arguments!");
Dave Wallacee4d5a652018-06-24 21:21:21 -0400908 print_usage_and_exit ();
909 }
Ping Yu34a3a082018-11-30 19:16:17 -0500910
911 if (ctrl->cfg.transport_udp)
912 {
913 vcm->proto = VPPCOM_PROTO_UDP;
914 }
915 else if (ctrl->cfg.transport_tls)
916 {
917 vcm->proto = VPPCOM_PROTO_TLS;
918 }
919 else
920 {
921 vcm->proto = VPPCOM_PROTO_TCP;
922 }
Dave Wallacee4d5a652018-06-24 21:21:21 -0400923
Florin Coras6d4bb422018-09-04 22:07:27 -0700924 memset (&vcm->server_addr, 0, sizeof (vcm->server_addr));
Dave Wallacee4d5a652018-06-24 21:21:21 -0400925 if (ctrl->cfg.address_ip6)
926 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700927 struct sockaddr_in6 *sddr6 = (struct sockaddr_in6 *) &vcm->server_addr;
928 sddr6->sin6_family = AF_INET6;
929 inet_pton (AF_INET6, argv[optind++], &(sddr6->sin6_addr));
930 sddr6->sin6_port = htons (atoi (argv[optind]));
931
932 vcm->server_endpt.is_ip4 = 0;
933 vcm->server_endpt.ip = (uint8_t *) & sddr6->sin6_addr;
934 vcm->server_endpt.port = (uint16_t) sddr6->sin6_port;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400935 }
936 else
937 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700938 struct sockaddr_in *saddr4 = (struct sockaddr_in *) &vcm->server_addr;
939 saddr4->sin_family = AF_INET;
940 inet_pton (AF_INET, argv[optind++], &(saddr4->sin_addr));
941 saddr4->sin_port = htons (atoi (argv[optind]));
Dave Wallacee4d5a652018-06-24 21:21:21 -0400942
Florin Coras6d4bb422018-09-04 22:07:27 -0700943 vcm->server_endpt.is_ip4 = 1;
944 vcm->server_endpt.ip = (uint8_t *) & saddr4->sin_addr;
945 vcm->server_endpt.port = (uint16_t) saddr4->sin_port;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400946 }
Florin Coras6d4bb422018-09-04 22:07:27 -0700947}
Dave Wallacee4d5a652018-06-24 21:21:21 -0400948
Florin Coras6d4bb422018-09-04 22:07:27 -0700949static void
Florin Coras1502fc32018-10-05 00:50:30 -0700950vtc_read_user_input (vcl_test_session_t * ctrl)
Florin Coras6d4bb422018-09-04 22:07:27 -0700951{
952 printf ("\nType some characters and hit <return>\n"
Florin Coras1502fc32018-10-05 00:50:30 -0700953 "('" VCL_TEST_TOKEN_HELP "' for help): ");
Dave Wallacee4d5a652018-06-24 21:21:21 -0400954
Florin Coras6d4bb422018-09-04 22:07:27 -0700955 if (fgets (ctrl->txbuf, ctrl->txbuf_size, stdin) != NULL)
956 {
957 if (strlen (ctrl->txbuf) == 1)
Dave Wallacee4d5a652018-06-24 21:21:21 -0400958 {
Florin Coras6d4bb422018-09-04 22:07:27 -0700959 printf ("\nNothing to send! Please try again...\n");
960 return;
Dave Wallacee4d5a652018-06-24 21:21:21 -0400961 }
Florin Coras6d4bb422018-09-04 22:07:27 -0700962 ctrl->txbuf[strlen (ctrl->txbuf) - 1] = 0; // chomp the newline.
Dave Wallacee4d5a652018-06-24 21:21:21 -0400963
Florin Coras6d4bb422018-09-04 22:07:27 -0700964 /* Parse input for keywords */
965 ctrl->cfg.test = parse_input ();
Dave Wallacee4d5a652018-06-24 21:21:21 -0400966 }
Florin Coras6d4bb422018-09-04 22:07:27 -0700967}
Dave Wallacee4d5a652018-06-24 21:21:21 -0400968
Florin Coras21795132018-09-09 09:40:51 -0700969static void
970vtc_ctrl_session_exit (void)
971{
972 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700973 vcl_test_session_t *ctrl = &vcm->ctrl_session;
Florin Coras21795132018-09-09 09:40:51 -0700974 int verbose = ctrl->cfg.verbose;
975
Florin Coras1502fc32018-10-05 00:50:30 -0700976 ctrl->cfg.test = VCL_TEST_TYPE_EXIT;
Florin Coras21795132018-09-09 09:40:51 -0700977 if (verbose)
978 {
979 vtinf ("(fd %d): Sending exit cfg to server...", ctrl->fd);
Florin Coras1502fc32018-10-05 00:50:30 -0700980 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Florin Coras21795132018-09-09 09:40:51 -0700981 }
982 (void) vcl_test_write (ctrl->fd, (uint8_t *) & ctrl->cfg,
983 sizeof (ctrl->cfg), &ctrl->stats, verbose);
Florin Coras21795132018-09-09 09:40:51 -0700984 sleep (1);
985}
986
Florin Coras6d4bb422018-09-04 22:07:27 -0700987int
988main (int argc, char **argv)
989{
990 vcl_test_client_main_t *vcm = &vcl_client_main;
Florin Coras1502fc32018-10-05 00:50:30 -0700991 vcl_test_session_t *ctrl = &vcm->ctrl_session;
Florin Coras6d4bb422018-09-04 22:07:27 -0700992 int rv, errno_val;
993
994 vcm->n_workers = 1;
Florin Coras1502fc32018-10-05 00:50:30 -0700995 vcl_test_cfg_init (&ctrl->cfg);
996 vcl_test_session_buf_alloc (ctrl);
Florin Coras6d4bb422018-09-04 22:07:27 -0700997 vtc_process_opts (vcm, argc, argv);
998
999 vcm->workers = calloc (vcm->n_workers, sizeof (vcl_test_client_worker_t));
1000 rv = vppcom_app_create ("vcl_test_client");
1001 if (rv < 0)
1002 vtfail ("vppcom_app_create()", rv);
1003
1004 ctrl->fd = vppcom_session_create (vcm->proto, 0 /* is_nonblocking */ );
1005 if (ctrl->fd < 0)
1006 vtfail ("vppcom_session_create()", ctrl->fd);
1007
Ping Yu34a3a082018-11-30 19:16:17 -05001008 if (vcm->proto == VPPCOM_PROTO_TLS)
1009 {
Florin Coras8a140612019-02-18 22:39:39 -08001010 vtinf ("Adding tls certs ...");
Ping Yu34a3a082018-11-30 19:16:17 -05001011 vppcom_session_tls_add_cert (ctrl->fd, vcl_test_crt_rsa,
1012 vcl_test_crt_rsa_len);
1013 vppcom_session_tls_add_key (ctrl->fd, vcl_test_key_rsa,
1014 vcl_test_key_rsa_len);
1015 }
1016
Florin Coras6d4bb422018-09-04 22:07:27 -07001017 vtinf ("Connecting to server...");
1018 rv = vppcom_session_connect (ctrl->fd, &vcm->server_endpt);
1019 if (rv)
1020 vtfail ("vppcom_session_connect()", rv);
Florin Coras1502fc32018-10-05 00:50:30 -07001021 vtinf ("Control session (fd %d) connected.", ctrl->fd);
Florin Coras6d4bb422018-09-04 22:07:27 -07001022
1023 rv = vtc_cfg_sync (ctrl);
1024 if (rv)
1025 vtfail ("vtc_cfg_sync()", rv);
1026
Florin Coras1502fc32018-10-05 00:50:30 -07001027 ctrl->cfg.ctrl_handle = ((vcl_test_cfg_t *) ctrl->rxbuf)->ctrl_handle;
Florin Coras6d4bb422018-09-04 22:07:27 -07001028 memset (&ctrl->stats, 0, sizeof (ctrl->stats));
Dave Wallacee4d5a652018-06-24 21:21:21 -04001029
Florin Coras1502fc32018-10-05 00:50:30 -07001030 while (ctrl->cfg.test != VCL_TEST_TYPE_EXIT)
Dave Wallacee4d5a652018-06-24 21:21:21 -04001031 {
Florin Coras6d4bb422018-09-04 22:07:27 -07001032 if (vcm->dump_cfg)
Dave Wallacee4d5a652018-06-24 21:21:21 -04001033 {
Florin Coras1502fc32018-10-05 00:50:30 -07001034 vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
Florin Coras6d4bb422018-09-04 22:07:27 -07001035 vcm->dump_cfg = 0;
Dave Wallacee4d5a652018-06-24 21:21:21 -04001036 }
1037
1038 switch (ctrl->cfg.test)
1039 {
Florin Coras1502fc32018-10-05 00:50:30 -07001040 case VCL_TEST_TYPE_ECHO:
Florin Coras6d4bb422018-09-04 22:07:27 -07001041 vtc_echo_client (vcm);
Dave Wallacee4d5a652018-06-24 21:21:21 -04001042 break;
1043
Florin Coras1502fc32018-10-05 00:50:30 -07001044 case VCL_TEST_TYPE_UNI:
1045 case VCL_TEST_TYPE_BI:
Florin Coras6d4bb422018-09-04 22:07:27 -07001046 vtc_stream_client (vcm);
Dave Wallacee4d5a652018-06-24 21:21:21 -04001047 break;
1048
Florin Coras1502fc32018-10-05 00:50:30 -07001049 case VCL_TEST_TYPE_EXIT:
Dave Wallacee4d5a652018-06-24 21:21:21 -04001050 continue;
1051
Florin Coras1502fc32018-10-05 00:50:30 -07001052 case VCL_TEST_TYPE_NONE:
Dave Wallacee4d5a652018-06-24 21:21:21 -04001053 default:
1054 break;
1055 }
Florin Coras6d4bb422018-09-04 22:07:27 -07001056 switch (vcm->post_test)
Dave Wallacee4d5a652018-06-24 21:21:21 -04001057 {
Florin Coras1502fc32018-10-05 00:50:30 -07001058 case VCL_TEST_TYPE_EXIT:
Dave Wallacee4d5a652018-06-24 21:21:21 -04001059 switch (ctrl->cfg.test)
1060 {
Florin Coras1502fc32018-10-05 00:50:30 -07001061 case VCL_TEST_TYPE_EXIT:
1062 case VCL_TEST_TYPE_UNI:
1063 case VCL_TEST_TYPE_BI:
1064 case VCL_TEST_TYPE_ECHO:
1065 ctrl->cfg.test = VCL_TEST_TYPE_EXIT;
Dave Wallacee4d5a652018-06-24 21:21:21 -04001066 continue;
1067
Florin Coras1502fc32018-10-05 00:50:30 -07001068 case VCL_TEST_TYPE_NONE:
Dave Wallacee4d5a652018-06-24 21:21:21 -04001069 default:
1070 break;
1071 }
1072 break;
1073
Florin Coras1502fc32018-10-05 00:50:30 -07001074 case VCL_TEST_TYPE_NONE:
1075 case VCL_TEST_TYPE_ECHO:
1076 case VCL_TEST_TYPE_UNI:
1077 case VCL_TEST_TYPE_BI:
Dave Wallacee4d5a652018-06-24 21:21:21 -04001078 default:
1079 break;
1080 }
1081
1082 memset (ctrl->txbuf, 0, ctrl->txbuf_size);
1083 memset (ctrl->rxbuf, 0, ctrl->rxbuf_size);
1084
Florin Coras6d4bb422018-09-04 22:07:27 -07001085 vtc_read_user_input (ctrl);
Dave Wallacee4d5a652018-06-24 21:21:21 -04001086 }
1087
Florin Coras21795132018-09-09 09:40:51 -07001088 vtc_ctrl_session_exit ();
Dave Wallacee4d5a652018-06-24 21:21:21 -04001089 vppcom_session_close (ctrl->fd);
1090 vppcom_app_destroy ();
Florin Coras6d4bb422018-09-04 22:07:27 -07001091 free (vcm->workers);
Dave Wallacee4d5a652018-06-24 21:21:21 -04001092 return 0;
1093}
Dave Wallace543852a2017-08-03 02:11:34 -04001094
1095/*
1096 * fd.io coding-style-patch-verification: ON
1097 *
1098 * Local Variables:
1099 * eval: (c-set-style "gnu")
1100 * End:
1101 */