FD.io VPP  v21.06-1-gbb7418cf9
Vector Packet Processing
vcl_test_protos.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Cisco and/or its affiliates.
3  * 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 
16 #include <hs_apps/vcl/vcl_test.h>
17 
18 static int
19 vt_tcp_connect (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
20 {
21  uint32_t flags, flen;
22  int rv;
23 
24  ts->fd = vppcom_session_create (VPPCOM_PROTO_TCP, 0 /* is_nonblocking */);
25  if (ts->fd < 0)
26  {
27  vterr ("vppcom_session_create()", ts->fd);
28  return ts->fd;
29  }
30 
31  /* Connect is blocking */
32  rv = vppcom_session_connect (ts->fd, endpt);
33  if (rv < 0)
34  {
35  vterr ("vppcom_session_connect()", rv);
36  return rv;
37  }
38 
39  ts->read = vcl_test_read;
40  ts->write = vcl_test_write;
41  flags = O_NONBLOCK;
42  flen = sizeof (flags);
43  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
44  vtinf ("Test session %d (fd %d) connected.", ts->session_index, ts->fd);
45 
46  return 0;
47 }
48 
49 static int
50 vt_tcp_listen (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
51 {
52  int rv;
53 
54  ts->fd = vppcom_session_create (VPPCOM_PROTO_TCP, 1 /* is_nonblocking */);
55  if (ts->fd < 0)
56  {
57  vterr ("vppcom_session_create()", ts->fd);
58  return ts->fd;
59  }
60 
61  rv = vppcom_session_bind (ts->fd, endpt);
62  if (rv < 0)
63  {
64  vterr ("vppcom_session_bind()", rv);
65  return rv;
66  }
67 
68  rv = vppcom_session_listen (ts->fd, 10);
69  if (rv < 0)
70  {
71  vterr ("vppcom_session_listen()", rv);
72  return rv;
73  }
74 
75  return 0;
76 }
77 
78 static int
79 vt_tcp_accept (int listen_fd, vcl_test_session_t *ts)
80 {
81  int client_fd;
82 
83  client_fd = vppcom_session_accept (listen_fd, &ts->endpt, 0);
84  if (client_fd < 0)
85  {
86  vterr ("vppcom_session_accept()", client_fd);
87  return client_fd;
88  }
89  ts->fd = client_fd;
90  ts->is_open = 1;
91  ts->read = vcl_test_read;
92  ts->write = vcl_test_write;
93 
94  return 0;
95 }
96 
97 static const vcl_test_proto_vft_t vcl_test_tcp = {
99  .listen = vt_tcp_listen,
100  .accept = vt_tcp_accept,
101 };
102 
103 VCL_TEST_REGISTER_PROTO (VPPCOM_PROTO_TCP, vcl_test_tcp);
104 
105 static int
106 vt_udp_connect (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
107 {
108  uint32_t flags, flen;
109  int rv;
110 
111  ts->fd = vppcom_session_create (VPPCOM_PROTO_UDP, 0 /* is_nonblocking */);
112  if (ts->fd < 0)
113  {
114  vterr ("vppcom_session_create()", ts->fd);
115  return ts->fd;
116  }
117 
118  /* Connect is blocking */
119  rv = vppcom_session_connect (ts->fd, endpt);
120  if (rv < 0)
121  {
122  vterr ("vppcom_session_connect()", rv);
123  return rv;
124  }
125 
126  ts->read = vcl_test_read;
127  ts->write = vcl_test_write;
128  flags = O_NONBLOCK;
129  flen = sizeof (flags);
130  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
131  vtinf ("Test session %d (fd %d) connected.", ts->session_index, ts->fd);
132 
133  return 0;
134 }
135 
136 static int
137 vt_udp_listen (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
138 {
139  int rv;
140 
141  ts->fd = vppcom_session_create (VPPCOM_PROTO_UDP, 1 /* is_nonblocking */);
142  if (ts->fd < 0)
143  {
144  vterr ("vppcom_session_create()", ts->fd);
145  return ts->fd;
146  }
147 
148  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CONNECTED, 0, 0);
149 
150  /* Listen is implicit */
151  rv = vppcom_session_bind (ts->fd, endpt);
152  if (rv < 0)
153  {
154  vterr ("vppcom_session_bind()", rv);
155  return rv;
156  }
157 
158  return 0;
159 }
160 
161 static int
162 vt_udp_accept (int listen_fd, vcl_test_session_t *ts)
163 {
164  int client_fd;
165 
166  client_fd = vppcom_session_accept (listen_fd, &ts->endpt, 0);
167  if (client_fd < 0)
168  {
169  vterr ("vppcom_session_accept()", client_fd);
170  return client_fd;
171  }
172  ts->fd = client_fd;
173  ts->is_open = 1;
174  ts->read = vcl_test_read;
175  ts->write = vcl_test_write;
176 
177  return 0;
178 }
179 
180 static const vcl_test_proto_vft_t vcl_test_udp = {
181  .open = vt_udp_connect,
182  .listen = vt_udp_listen,
183  .accept = vt_udp_accept,
184 };
185 
186 VCL_TEST_REGISTER_PROTO (VPPCOM_PROTO_UDP, vcl_test_udp);
187 
188 /*
189  * TLS server cert and keys to be used for testing only
190  */
191 static char vcl_test_crt_rsa[] =
192  "-----BEGIN CERTIFICATE-----\r\n"
193  "MIID5zCCAs+gAwIBAgIJALeMYCEHrTtJMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD\r\n"
194  "VQQGEwJVUzELMAkGA1UECAwCQ0ExETAPBgNVBAcMCFNhbiBKb3NlMQ4wDAYDVQQK\r\n"
195  "DAVDaXNjbzEOMAwGA1UECwwFZmQuaW8xFjAUBgNVBAMMDXRlc3R0bHMuZmQuaW8x\r\n"
196  "IjAgBgkqhkiG9w0BCQEWE3ZwcC1kZXZAbGlzdHMuZmQuaW8wHhcNMTgwMzA1MjEx\r\n"
197  "NTEyWhcNMjgwMzAyMjExNTEyWjCBiTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB\r\n"
198  "MREwDwYDVQQHDAhTYW4gSm9zZTEOMAwGA1UECgwFQ2lzY28xDjAMBgNVBAsMBWZk\r\n"
199  "LmlvMRYwFAYDVQQDDA10ZXN0dGxzLmZkLmlvMSIwIAYJKoZIhvcNAQkBFhN2cHAt\r\n"
200  "ZGV2QGxpc3RzLmZkLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\r\n"
201  "4C1k8a1DuStgggqT4o09fP9sJ2dC54bxhS/Xk2VEfaIZ222WSo4X/syRVfVy9Yah\r\n"
202  "cpI1zJ/RDxaZSFhgA+nPZBrFMsrULkrdAOpOVj8eDEp9JuWdO2ODSoFnCvLxcYWB\r\n"
203  "Yc5kHryJpEaGJl1sFQSesnzMFty/59ta0stk0Fp8r5NhIjWvSovGzPo6Bhz+VS2c\r\n"
204  "ebIZh4x1t2hHaFcgm0qJoJ6DceReWCW8w+yOVovTolGGq+bpb2Hn7MnRSZ2K2NdL\r\n"
205  "+aLXpkZbS/AODP1FF2vTO1mYL290LO7/51vJmPXNKSDYMy5EvILr5/VqtjsFCwRL\r\n"
206  "Q4jcM/+GeHSAFWx4qIv0BwIDAQABo1AwTjAdBgNVHQ4EFgQUWa1SOB37xmT53tZQ\r\n"
207  "aXuLLhRI7U8wHwYDVR0jBBgwFoAUWa1SOB37xmT53tZQaXuLLhRI7U8wDAYDVR0T\r\n"
208  "BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAoUht13W4ya27NVzQuCMvqPWL3VM4\r\n"
209  "3xbPFk02FaGz/WupPu276zGlzJAZrbuDcQowwwU1Ni1Yygxl96s1c2M5rHDTrOKG\r\n"
210  "rK0hbkSFBo+i6I8u4HiiQ4rYmG0Hv6+sXn3of0HsbtDPGgWZoipPWDljPYEURu3e\r\n"
211  "3HRe/Dtsj9CakBoSDzs8ndWaBR+f4sM9Tk1cjD46Gq2T/qpSPXqKxEUXlzhdCAn4\r\n"
212  "twub17Bq2kykHpppCwPg5M+v30tHG/R2Go15MeFWbEJthFk3TZMjKL7UFs7fH+x2\r\n"
213  "wSonXb++jY+KmCb93C+soABBizE57g/KmiR2IxQ/LMjDik01RSUIaM0lLA==\r\n"
214  "-----END CERTIFICATE-----\r\n";
215 static uint32_t vcl_test_crt_rsa_len = sizeof (vcl_test_crt_rsa);
216 
217 static char vcl_test_key_rsa[] =
218  "-----BEGIN PRIVATE KEY-----\r\n"
219  "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgLWTxrUO5K2CC\r\n"
220  "CpPijT18/2wnZ0LnhvGFL9eTZUR9ohnbbZZKjhf+zJFV9XL1hqFykjXMn9EPFplI\r\n"
221  "WGAD6c9kGsUyytQuSt0A6k5WPx4MSn0m5Z07Y4NKgWcK8vFxhYFhzmQevImkRoYm\r\n"
222  "XWwVBJ6yfMwW3L/n21rSy2TQWnyvk2EiNa9Ki8bM+joGHP5VLZx5shmHjHW3aEdo\r\n"
223  "VyCbSomgnoNx5F5YJbzD7I5Wi9OiUYar5ulvYefsydFJnYrY10v5otemRltL8A4M\r\n"
224  "/UUXa9M7WZgvb3Qs7v/nW8mY9c0pINgzLkS8guvn9Wq2OwULBEtDiNwz/4Z4dIAV\r\n"
225  "bHioi/QHAgMBAAECggEBAMzGipP8+oT166U+NlJXRFifFVN1DvdhG9PWnOxGL+c3\r\n"
226  "ILmBBC08WQzmHshPemBvR6DZkA1H23cV5JTiLWrFtC00CvhXsLRMrE5+uWotI6yE\r\n"
227  "iofybMroHvD6/X5R510UX9hQ6MHu5ShLR5VZ9zXHz5MpTmB/60jG5dLx+jgcwBK8\r\n"
228  "LuGv2YB/WCUwT9QJ3YU2eaingnXtz/MrFbkbltrqlnBdlD+kTtw6Yac9y1XuuQXc\r\n"
229  "BPeulLNDuPolJVWbUvDBZrpt2dXTgz8ws1sv+wCNE0xwQJsqW4Nx3QkpibUL9RUr\r\n"
230  "CVbKlNfa9lopT6nGKlgX69R/uH35yh9AOsfasro6w0ECgYEA82UJ8u/+ORah+0sF\r\n"
231  "Q0FfW5MTdi7OAUHOz16pUsGlaEv0ERrjZxmAkHA/VRwpvDBpx4alCv0Hc39PFLIk\r\n"
232  "nhSsM2BEuBkTAs6/GaoNAiBtQVE/hN7awNRWVmlieS0go3Y3dzaE9IUMyj8sPOFT\r\n"
233  "5JdJ6BM69PHKCkY3dKdnnfpFEuECgYEA68mRpteunF1mdZgXs+WrN+uLlRrQR20F\r\n"
234  "ZyMYiUCH2Dtn26EzA2moy7FipIIrQcX/j+KhYNGM3e7MU4LymIO29E18mn8JODnH\r\n"
235  "sQOXzBTsf8A4yIVMkcuQD3bfb0JiUGYUPOidTp2N7IJA7+6Yc3vQOyb74lnKnJoO\r\n"
236  "gougPT2wS+cCgYAn7muzb6xFsXDhyW0Tm6YJYBfRS9yAWEuVufINobeBZPSl2cN1\r\n"
237  "Jrnw+HlrfTNbrJWuJmjtZJXUXQ6cVp2rUbjutNyRV4vG6iRwEXYQ40EJdkr1gZpi\r\n"
238  "CHQhuShuuPih2MNAy7EEbM+sXrDjTBR3bFqzuHPzu7dp+BshCFX3lRfAAQKBgGQt\r\n"
239  "K5i7IhCFDjb/+3IPLgOAK7mZvsvZ4eXD33TQ2eZgtut1PXtBtNl17/b85uv293Fm\r\n"
240  "VDISVcsk3eLNS8zIiT6afUoWlxAwXEs0v5WRfjl4radkGvgGiJpJYvyeM67877RB\r\n"
241  "EDSKc/X8ESLfOB44iGvZUEMG6zJFscx9DgN25iQZAoGAbyd+JEWwdVH9/K3IH1t2\r\n"
242  "PBkZX17kNWv+iVM1WyFjbe++vfKZCrOJiyiqhDeEqgrP3AuNMlaaduC3VRC3G5oV\r\n"
243  "Mj1tlhDWQ/qhvKdCKNdIVQYDE75nw+FRWV8yYkHAnXYW3tNoweDIwixE0hkPR1bc\r\n"
244  "oEjPLVNtx8SOj/M4rhaPT3I=\r\n"
245  "-----END PRIVATE KEY-----\r\n";
246 static uint32_t vcl_test_key_rsa_len = sizeof (vcl_test_key_rsa);
247 
248 static int
250 {
252  vppcom_cert_key_pair_t ckpair;
253  int ckp_index;
254 
255  vtinf ("Adding tls certs ...");
256 
257  ckpair.cert = vcl_test_crt_rsa;
258  ckpair.key = vcl_test_key_rsa;
259  ckpair.cert_len = vcl_test_crt_rsa_len;
260  ckpair.key_len = vcl_test_key_rsa_len;
261  ckp_index = vppcom_add_cert_key_pair (&ckpair);
262  if (ckp_index < 0)
263  {
264  vterr ("vppcom_add_cert_key_pair()", ckp_index);
265  return ckp_index;
266  }
267 
268  vt->ckpair_index = ckp_index;
269  return 0;
270 }
271 
272 static int
274 {
275  return vt_add_cert_key_pair ();
276 }
277 
278 static int
279 vt_tls_connect (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
280 {
282  uint32_t flags, flen, ckp_len;
283  int rv;
284 
285  ts->fd = vppcom_session_create (VPPCOM_PROTO_TLS, 0 /* is_nonblocking */);
286  if (ts->fd < 0)
287  {
288  vterr ("vppcom_session_create()", ts->fd);
289  return ts->fd;
290  }
291 
292  ckp_len = sizeof (vt->ckpair_index);
293  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR, &vt->ckpair_index,
294  &ckp_len);
295 
296  /* Connect is blocking */
297  rv = vppcom_session_connect (ts->fd, endpt);
298  if (rv < 0)
299  {
300  vterr ("vppcom_session_connect()", rv);
301  return rv;
302  }
303 
304  ts->read = vcl_test_read;
305  ts->write = vcl_test_write;
306  flags = O_NONBLOCK;
307  flen = sizeof (flags);
308  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
309  vtinf ("Test session %d (fd %d) connected.", ts->session_index, ts->fd);
310 
311  return 0;
312 }
313 
314 static int
315 vt_tls_listen (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
316 {
318  uint32_t ckp_len;
319  int rv;
320 
321  ts->fd = vppcom_session_create (VPPCOM_PROTO_TLS, 1 /* is_nonblocking */);
322  if (ts->fd < 0)
323  {
324  vterr ("vppcom_session_create()", ts->fd);
325  return ts->fd;
326  }
327 
328  ckp_len = sizeof (vt->ckpair_index);
329  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR, &vt->ckpair_index,
330  &ckp_len);
331 
332  rv = vppcom_session_bind (ts->fd, endpt);
333  if (rv < 0)
334  {
335  vterr ("vppcom_session_bind()", rv);
336  return rv;
337  }
338 
339  rv = vppcom_session_listen (ts->fd, 10);
340  if (rv < 0)
341  {
342  vterr ("vppcom_session_listen()", rv);
343  return rv;
344  }
345 
346  return 0;
347 }
348 
349 static int
350 vt_tls_accept (int listen_fd, vcl_test_session_t *ts)
351 {
352  int client_fd;
353 
354  client_fd = vppcom_session_accept (listen_fd, &ts->endpt, 0);
355  if (client_fd < 0)
356  {
357  vterr ("vppcom_session_accept()", client_fd);
358  return client_fd;
359  }
360  ts->fd = client_fd;
361  ts->is_open = 1;
362  ts->read = vcl_test_read;
363  ts->write = vcl_test_write;
364 
365  return 0;
366 }
367 
368 static const vcl_test_proto_vft_t vcl_test_tls = {
369  .init = vt_tls_init,
370  .open = vt_tls_connect,
371  .listen = vt_tls_listen,
372  .accept = vt_tls_accept,
373 };
374 
375 VCL_TEST_REGISTER_PROTO (VPPCOM_PROTO_TLS, vcl_test_tls);
376 
377 static int
379 {
380  return vt_add_cert_key_pair ();
381 }
382 
383 static int
384 vt_dtls_connect (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
385 {
387  uint32_t flags, flen, ckp_len;
388  int rv;
389 
390  ts->fd = vppcom_session_create (VPPCOM_PROTO_DTLS, 0 /* is_nonblocking */);
391  if (ts->fd < 0)
392  {
393  vterr ("vppcom_session_create()", ts->fd);
394  return ts->fd;
395  }
396 
397  ckp_len = sizeof (vt->ckpair_index);
398  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR, &vt->ckpair_index,
399  &ckp_len);
400 
401  /* Connect is blocking */
402  rv = vppcom_session_connect (ts->fd, endpt);
403  if (rv < 0)
404  {
405  vterr ("vppcom_session_connect()", rv);
406  return rv;
407  }
408 
409  ts->read = vcl_test_read;
410  ts->write = vcl_test_write;
411  flags = O_NONBLOCK;
412  flen = sizeof (flags);
413  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
414  vtinf ("Test session %d (fd %d) connected.", ts->session_index, ts->fd);
415 
416  return 0;
417 }
418 
419 static int
420 vt_dtls_listen (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
421 {
423  uint32_t ckp_len;
424  int rv;
425 
426  ts->fd = vppcom_session_create (VPPCOM_PROTO_DTLS, 1 /* is_nonblocking */);
427  if (ts->fd < 0)
428  {
429  vterr ("vppcom_session_create()", ts->fd);
430  return ts->fd;
431  }
432 
433  ckp_len = sizeof (vt->ckpair_index);
434  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR, &vt->ckpair_index,
435  &ckp_len);
436 
437  rv = vppcom_session_bind (ts->fd, endpt);
438  if (rv < 0)
439  {
440  vterr ("vppcom_session_bind()", rv);
441  return rv;
442  }
443 
444  rv = vppcom_session_listen (ts->fd, 10);
445  if (rv < 0)
446  {
447  vterr ("vppcom_session_listen()", rv);
448  return rv;
449  }
450 
451  return 0;
452 }
453 
454 static int
455 vt_dtls_accept (int listen_fd, vcl_test_session_t *ts)
456 {
457  int client_fd;
458 
459  client_fd = vppcom_session_accept (listen_fd, &ts->endpt, 0);
460  if (client_fd < 0)
461  {
462  vterr ("vppcom_session_accept()", client_fd);
463  return client_fd;
464  }
465  ts->fd = client_fd;
466  ts->is_open = 1;
467  ts->read = vcl_test_read;
468  ts->write = vcl_test_write;
469 
470  return 0;
471 }
472 
473 static const vcl_test_proto_vft_t vcl_test_dtls = {
474  .init = vt_dtls_init,
475  .open = vt_dtls_connect,
476  .listen = vt_dtls_listen,
477  .accept = vt_dtls_accept,
478 };
479 
480 VCL_TEST_REGISTER_PROTO (VPPCOM_PROTO_DTLS, vcl_test_dtls);
481 
482 static int
484 {
486 
487  if (cfg)
488  vt->cfg = *cfg;
489 
490  return vt_add_cert_key_pair ();
491 }
492 
493 static int
495  vppcom_endpt_t *endpt)
496 {
497  uint32_t size, i, flags, flen, ckp_len;
498  vcl_test_session_t *tq;
499  int rv;
500 
501  /* Test already initialized */
502  if (wrk->n_qsessions == vt->cfg.num_test_qsessions)
503  return 0;
504 
505  /* Make sure pool is large enough */
506  if (!wrk->qsessions)
507  {
508  wrk->qsessions =
510  }
511  else
512  {
513  size = vt->cfg.num_test_qsessions * sizeof (vcl_test_session_t);
514  wrk->qsessions = realloc (wrk->qsessions, size);
515  }
516 
517  if (!wrk->qsessions)
518  {
519  vterr ("failed to alloc Qsessions", -errno);
520  return errno;
521  }
522 
523  for (i = 0; i < vt->cfg.num_test_qsessions; i++)
524  {
525  tq = &wrk->qsessions[i];
526  tq->fd =
527  vppcom_session_create (VPPCOM_PROTO_QUIC, 0 /* is_nonblocking */);
528  tq->session_index = i;
529  if (tq->fd < 0)
530  {
531  vterr ("vppcom_session_create()", tq->fd);
532  return tq->fd;
533  }
534 
535  ckp_len = sizeof (vt->ckpair_index);
536  vppcom_session_attr (tq->fd, VPPCOM_ATTR_SET_CKPAIR, &vt->ckpair_index,
537  &ckp_len);
538 
539  /* Connect is blocking */
540  rv = vppcom_session_connect (tq->fd, endpt);
541  if (rv < 0)
542  {
543  vterr ("vppcom_session_connect()", rv);
544  return rv;
545  }
546  flags = O_NONBLOCK;
547  flen = sizeof (flags);
548  vppcom_session_attr (tq->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
549  vtinf ("Test Qsession %d (fd %d) connected.", i, tq->fd);
550  }
552 
553  return 0;
554 }
555 
556 static int
557 vt_quic_connect (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
558 {
560  uint32_t wrk_index, flags, flen;
561  vcl_test_session_t *tq;
563  int rv;
564 
565  wrk_index = vcl_test_worker_index ();
566  wrk = &vt->wrk[wrk_index];
567 
568  /* Make sure qsessions are initialized */
569  vt_quic_maybe_init_wrk (vt, wrk, endpt);
570 
571  ts->fd = vppcom_session_create (VPPCOM_PROTO_QUIC, 0 /* is_nonblocking */);
572  if (ts->fd < 0)
573  {
574  vterr ("vppcom_session_create()", ts->fd);
575  return ts->fd;
576  }
577 
578  /* Choose qession to use for stream */
579  tq = &wrk->qsessions[ts->session_index / vt->cfg.num_test_sessions_perq];
580 
581  rv = vppcom_session_stream_connect (ts->fd, tq->fd);
582  if (rv < 0)
583  {
584  vterr ("vppcom_session_stream_connect()", rv);
585  return rv;
586  }
587 
588  flags = O_NONBLOCK;
589  flen = sizeof (flags);
590  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
591 
592  ts->read = vcl_test_read;
593  ts->write = vcl_test_write;
594 
595  vtinf ("Test (quic stream) session %d (fd %d) connected.", ts->session_index,
596  ts->fd);
597 
598  return 0;
599 }
600 
601 static int
602 vt_quic_listen (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
603 {
605  uint32_t ckp_len;
606  int rv;
607 
608  ts->fd = vppcom_session_create (VPPCOM_PROTO_QUIC, 1 /* is_nonblocking */);
609  if (ts->fd < 0)
610  {
611  vterr ("vppcom_session_create()", ts->fd);
612  return ts->fd;
613  }
614 
615  ckp_len = sizeof (vt->ckpair_index);
616  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_CKPAIR, &vt->ckpair_index,
617  &ckp_len);
618 
619  rv = vppcom_session_bind (ts->fd, endpt);
620  if (rv < 0)
621  {
622  vterr ("vppcom_session_bind()", rv);
623  return rv;
624  }
625 
626  rv = vppcom_session_listen (ts->fd, 10);
627  if (rv < 0)
628  {
629  vterr ("vppcom_session_listen()", rv);
630  return rv;
631  }
632 
633  return 0;
634 }
635 
636 static int
637 vt_quic_accept (int listen_fd, vcl_test_session_t *ts)
638 {
639  int client_fd;
640 
641  client_fd = vppcom_session_accept (listen_fd, &ts->endpt, 0);
642  if (client_fd < 0)
643  {
644  vterr ("vppcom_session_accept()", client_fd);
645  return client_fd;
646  }
647  ts->fd = client_fd;
648  ts->is_open = 1;
649  ts->read = vcl_test_read;
650  ts->write = vcl_test_write;
651 
652  return 0;
653 }
654 
655 static int
657 {
658  int listener_fd = vppcom_session_listener (ts->fd);
659 
660  if ((vppcom_session_n_accepted (listener_fd) == 0) &
661  vppcom_session_is_connectable_listener (listener_fd))
662  {
663  vtinf ("Connected Listener fd %x has no more sessions", listener_fd);
664  vppcom_session_close (listener_fd);
665  }
666 
667  return 0;
668 }
669 
670 static const vcl_test_proto_vft_t vcl_test_quic = {
671  .init = vt_quic_init,
672  .open = vt_quic_connect,
673  .listen = vt_quic_listen,
674  .accept = vt_quic_accept,
675  .close = vt_quic_close,
676 };
677 
678 VCL_TEST_REGISTER_PROTO (VPPCOM_PROTO_QUIC, vcl_test_quic);
679 
680 static unsigned char test_key[46] = {
681  0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0, 0xd6, 0x4f, 0xa3, 0x2c,
682  0x06, 0xde, 0x41, 0x39, 0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
683  0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73, 0xc3, 0x17, 0xf2, 0xda,
684  0xbe, 0x35, 0x77, 0x93, 0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
685 };
686 
687 typedef struct
688 {
689  unsigned char cc : 4;
690  unsigned char x : 1;
691  unsigned char p : 1;
692  unsigned char version : 2;
693  unsigned char pt : 7;
694  unsigned char m : 1;
695  uint16_t seq;
696  uint32_t ts;
697  uint32_t ssrc;
698 } rtp_hdr_t;
699 
700 typedef struct
701 {
704 } rtp_headers_t;
705 
706 typedef struct transport_endpt_cfg_srtp_policy
707 {
708  uint32_t ssrc_type;
709  uint32_t ssrc_value;
710  uint32_t window_size;
712  uint8_t key_len;
713  uint8_t key[46];
715 
716 typedef struct transport_endpt_cfg_srtp
717 {
720 
721 static void
723 {
724  transport_endpt_cfg_srtp_t *srtp_cfg;
726  uint32_t rx_ssrc, tx_ssrc;
727  uint32_t cfg_size;
728 
729  rx_ssrc = is_connect ? 0xcafebeef : 0xbeefcafe;
730  tx_ssrc = is_connect ? 0xbeefcafe : 0xcafebeef;
731 
732  cfg_size = sizeof (transport_endpt_cfg_srtp_t);
733  srtp_cfg = malloc (cfg_size);
734  memset (srtp_cfg, 0, cfg_size);
735 
736  test_policy = &srtp_cfg->policy[0];
737  test_policy->ssrc_type = 1 /* ssrc_specific */;
738  test_policy->ssrc_value = rx_ssrc;
739  memcpy (test_policy->key, test_key, sizeof (test_key));
740  test_policy->key_len = sizeof (test_key);
741  test_policy->window_size = 128;
742  test_policy->allow_repeat_tx = 1;
743 
744  test_policy = &srtp_cfg->policy[1];
745  test_policy->ssrc_type = 1 /* ssrc_specific */;
746  test_policy->ssrc_value = tx_ssrc;
747  memcpy (test_policy->key, test_key, sizeof (test_key));
748  test_policy->key_len = sizeof (test_key);
749  test_policy->window_size = 128;
750  test_policy->allow_repeat_tx = 1;
751 
752  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_ENDPT_EXT_CFG, srtp_cfg,
753  &cfg_size);
754  free (srtp_cfg);
755 }
756 
757 static void
759 {
760  uint32_t rx_ssrc, tx_ssrc;
761  rtp_headers_t *rtp_hdrs;
762  rtp_hdr_t *hdr;
763 
764  rx_ssrc = is_connect ? 0xcafebeef : 0xbeefcafe;
765  tx_ssrc = is_connect ? 0xbeefcafe : 0xcafebeef;
766 
767  rtp_hdrs = malloc (sizeof (rtp_headers_t));
768  memset (rtp_hdrs, 0, sizeof (*rtp_hdrs));
769  ts->opaque = rtp_hdrs;
770 
771  hdr = &rtp_hdrs->rx_hdr;
772  hdr->version = 2;
773  hdr->p = 0;
774  hdr->x = 0;
775  hdr->cc = 0;
776  hdr->m = 0;
777  hdr->pt = 0x1;
778  hdr->seq = 0;
779  hdr->ts = 0;
780  hdr->ssrc = htonl (rx_ssrc);
781 
782  hdr = &rtp_hdrs->tx_hdr;
783  hdr->version = 2;
784  hdr->p = 0;
785  hdr->x = 0;
786  hdr->cc = 0;
787  hdr->m = 0;
788  hdr->pt = 0x1;
789  hdr->seq = 0;
790  hdr->ts = 0;
791  hdr->ssrc = htonl (tx_ssrc);
792 }
793 
794 static int
795 vt_srtp_write (vcl_test_session_t *ts, void *buf, uint32_t nbytes)
796 {
797  int tx_bytes = 0, nbytes_left = nbytes, rv;
798  vcl_test_stats_t *stats = &ts->stats;
799  rtp_hdr_t *hdr;
800 
801  hdr = &((rtp_headers_t *) ts->opaque)->tx_hdr;
802  hdr->seq = htons (ntohs (hdr->seq) + 1);
803  hdr->ts = htonl (ntohl (hdr->ts) + 1);
804 
805  memcpy (buf, hdr, sizeof (*hdr));
806 
807  do
808  {
809  stats->tx_xacts++;
810  rv = vppcom_session_write (ts->fd, buf, nbytes_left);
811  if (rv < 0)
812  {
813  if ((rv == VPPCOM_EAGAIN || rv == VPPCOM_EWOULDBLOCK))
814  stats->tx_eagain++;
815  break;
816  }
817  tx_bytes += rv;
818  nbytes_left = nbytes_left - rv;
819  buf += rv;
820  stats->tx_incomp++;
821  }
822  while (tx_bytes != nbytes);
823 
824  if (tx_bytes < 0)
825  return 0;
826 
827  stats->tx_bytes += tx_bytes;
828 
829  return (tx_bytes);
830 }
831 
832 static inline int
833 vt_srtp_read (vcl_test_session_t *ts, void *buf, uint32_t nbytes)
834 {
835  vcl_test_stats_t *stats = &ts->stats;
836  rtp_hdr_t *hdr;
837  int rx_bytes;
838 
839  stats->rx_xacts++;
840  rx_bytes = vppcom_session_read (ts->fd, buf, nbytes);
841 
842  if (rx_bytes <= 0)
843  {
844  if (rx_bytes == VPPCOM_EAGAIN || rx_bytes == VPPCOM_EWOULDBLOCK)
845  stats->rx_eagain++;
846  else
847  return -1;
848  }
849 
850  if (rx_bytes < nbytes)
851  stats->rx_incomp++;
852 
853  stats->rx_bytes += rx_bytes;
854 
855  hdr = &((rtp_headers_t *) ts->opaque)->rx_hdr;
856  if (((rtp_hdr_t *) buf)->ssrc != hdr->ssrc)
857  hdr->ssrc = ((rtp_hdr_t *) buf)->ssrc;
858  return (rx_bytes);
859 }
860 
861 static int
862 vt_srtp_connect (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
863 {
864  uint32_t flags, flen;
865  int rv;
866 
867  ts->fd = vppcom_session_create (VPPCOM_PROTO_SRTP, 0 /* is_nonblocking */);
868  if (ts->fd < 0)
869  {
870  vterr ("vppcom_session_create()", ts->fd);
871  return ts->fd;
872  }
873 
874  vt_session_add_srtp_policy (ts, 1 /* is connect */);
875 
876  /* Connect is blocking */
877  rv = vppcom_session_connect (ts->fd, endpt);
878  if (rv < 0)
879  {
880  vterr ("vppcom_session_connect()", rv);
881  return rv;
882  }
883 
884  ts->read = vt_srtp_read;
885  ts->write = vt_srtp_write;
886  flags = O_NONBLOCK;
887  flen = sizeof (flags);
888  vppcom_session_attr (ts->fd, VPPCOM_ATTR_SET_FLAGS, &flags, &flen);
889  vtinf ("Test session %d (fd %d) connected.", ts->session_index, ts->fd);
890 
891  vt_srtp_session_init (ts, 1 /* is connect */);
892 
893  return 0;
894 }
895 
896 static int
897 vt_srtp_listen (vcl_test_session_t *ts, vppcom_endpt_t *endpt)
898 {
899  int rv;
900 
901  ts->fd = vppcom_session_create (VPPCOM_PROTO_SRTP, 1 /* is_nonblocking */);
902  if (ts->fd < 0)
903  {
904  vterr ("vppcom_session_create()", ts->fd);
905  return ts->fd;
906  }
907 
908  vt_session_add_srtp_policy (ts, 0 /* is connect */);
909 
910  rv = vppcom_session_bind (ts->fd, endpt);
911  if (rv < 0)
912  {
913  vterr ("vppcom_session_bind()", rv);
914  return rv;
915  }
916 
917  rv = vppcom_session_listen (ts->fd, 10);
918  if (rv < 0)
919  {
920  vterr ("vppcom_session_listen()", rv);
921  return rv;
922  }
923 
924  return 0;
925 }
926 
927 static int
928 vt_srtp_accept (int listen_fd, vcl_test_session_t *ts)
929 {
930  int client_fd;
931 
932  client_fd = vppcom_session_accept (listen_fd, &ts->endpt, 0);
933  if (client_fd < 0)
934  {
935  vterr ("vppcom_session_accept()", client_fd);
936  return client_fd;
937  }
938  ts->fd = client_fd;
939  ts->is_open = 1;
940  ts->read = vt_srtp_read;
941  ts->write = vt_srtp_write;
942 
943  vt_srtp_session_init (ts, 0 /* is connect */);
944 
945  return 0;
946 }
947 
948 static int
950 {
951  free (ts->opaque);
952  return 0;
953 }
954 
955 static const vcl_test_proto_vft_t vcl_test_srtp = {
957  .listen = vt_srtp_listen,
958  .accept = vt_srtp_accept,
959  .close = vt_srtp_close,
960 };
961 
962 VCL_TEST_REGISTER_PROTO (VPPCOM_PROTO_SRTP, vcl_test_srtp);
963 
964 /*
965  * fd.io coding-style-patch-verification: ON
966  *
967  * Local Variables:
968  * eval: (c-set-style "gnu")
969  * End:
970  */
VCL_TEST_REGISTER_PROTO(VPPCOM_PROTO_TCP, vcl_test_tcp)
static int vt_dtls_listen(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
static void vt_srtp_session_init(vcl_test_session_t *ts, int is_connect)
static int vt_tcp_listen(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
static int vt_tls_listen(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
static int vcl_test_worker_index(void)
Definition: vcl_test.h:150
#define ntohs(x)
Definition: af_xdp.bpf.c:29
transport_endpt_cfg_srtp_policy_t policy[2]
static int vt_srtp_connect(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
session_worker_t * wrk
Definition: application.c:490
uint32_t n_qsessions
Definition: vcl_test.h:167
static char vcl_test_crt_rsa[]
static int vcl_test_write(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
Definition: vcl_test.h:530
vcl_test_main_t vcl_test_main
int(* read)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
Definition: vcl_test.h:131
static int vt_dtls_init(vcl_test_cfg_t *cfg)
uint32_t num_test_qsessions
Definition: vcl_test.h:101
static int vt_udp_connect(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
vcl_test_wrk_t * wrk
Definition: vcl_test.h:176
int(* init)(vcl_test_cfg_t *cfg)
Definition: vcl_test.h:157
int(* open)(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
Definition: vcl_test.h:158
vl_api_ipsec_spd_action_t policy
Definition: ipsec.api:99
u8 key[SRTP_MAX_KEYLEN]
Definition: srtp.h:63
uint16_t seq
struct transport_endpt_cfg_srtp_policy transport_endpt_cfg_srtp_policy_t
static int vt_udp_listen(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
static int vt_srtp_read(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
uint32_t rx_eagain
Definition: vcl_test.h:115
vcl_test_session_t * qsessions
Definition: vcl_test.h:166
static int vt_srtp_write(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
unsigned char cc
static int vt_dtls_accept(int listen_fd, vcl_test_session_t *ts)
static uint32_t vcl_test_key_rsa_len
static int vt_quic_listen(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
static int vt_quic_connect(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
#define vterr(_fn, _rv)
Definition: vcl_test.h:34
int __clib_unused rv
Definition: application.c:491
static int vt_srtp_close(vcl_test_session_t *ts)
vcl_test_stats_t stats
Definition: vcl_test.h:138
uint32_t ssrc
vl_api_ikev2_sa_stats_t stats
uint32_t ckpair_index
Definition: vcl_test.h:174
static int vt_add_cert_key_pair()
u32 size
Definition: vhost_user.h:125
unsigned char m
int(* write)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
Definition: vcl_test.h:132
void * malloc(size_t size)
Definition: mem.c:33
struct vcl_test_session vcl_test_session_t
static int vt_tls_init(vcl_test_cfg_t *cfg)
static int vt_tls_connect(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
unsigned char p
static int vt_quic_init(vcl_test_cfg_t *cfg)
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
vppcom_endpt_t endpt
Definition: vcl_test.h:141
u64 buf
Definition: application.c:493
uint32_t ts
uint32_t num_test_sessions_perq
Definition: vcl_test.h:100
void free(void *p)
Definition: mem.c:42
#define vtinf(_fmt, _args...)
Definition: vcl_test.h:43
static int vt_srtp_accept(int listen_fd, vcl_test_session_t *ts)
static void vt_session_add_srtp_policy(vcl_test_session_t *ts, int is_connect)
static int vt_tls_accept(int listen_fd, vcl_test_session_t *ts)
static int vt_quic_close(vcl_test_session_t *ts)
unsigned char version
uint32_t rx_incomp
Definition: vcl_test.h:116
static int vcl_test_read(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
Definition: vcl_test.h:462
unsigned char pt
static int vt_tcp_connect(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
void * realloc(void *p, size_t size)
Definition: mem.c:67
uint64_t tx_bytes
Definition: vcl_test.h:118
uint64_t tx_xacts
Definition: vcl_test.h:117
static int vt_quic_maybe_init_wrk(vcl_test_main_t *vt, vcl_test_wrk_t *wrk, vppcom_endpt_t *endpt)
static int vt_tcp_accept(int listen_fd, vcl_test_session_t *ts)
uint32_t tx_eagain
Definition: vcl_test.h:119
static int vt_udp_accept(int listen_fd, vcl_test_session_t *ts)
static int vt_quic_accept(int listen_fd, vcl_test_session_t *ts)
unsigned char x
static char vcl_test_key_rsa[]
uint8_t is_open
Definition: vcl_test.h:128
void * calloc(size_t nmemb, size_t size)
Definition: mem.c:54
static int vt_dtls_connect(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
rtp_hdr_t tx_hdr
rtp_hdr_t rx_hdr
static unsigned char test_key[46]
static int vt_srtp_listen(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
uint32_t tx_incomp
Definition: vcl_test.h:120
static uint32_t vcl_test_crt_rsa_len
vcl_test_cfg_t cfg
Definition: vcl_test.h:175
uint64_t rx_bytes
Definition: vcl_test.h:114
struct transport_endpt_cfg_srtp transport_endpt_cfg_srtp_t
uint64_t rx_xacts
Definition: vcl_test.h:113