LCOV - code coverage report
Current view: top level - plugins/hs_apps/vcl - vcl_test_protos.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 120 423 28.4 %
Date: 2023-07-05 22:20:52 Functions: 18 35 51.4 %

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

Generated by: LCOV version 1.14