LCOV - code coverage report
Current view: top level - plugins/tlsopenssl - dtls_bio.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 74 109 67.9 %
Date: 2023-07-05 22:20:52 Functions: 9 9 100.0 %

          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 <openssl/bio.h>
      17             : #include <openssl/err.h>
      18             : 
      19             : #include <vnet/session/session.h>
      20             : #include <vnet/session/application_interface.h>
      21             : 
      22             : static inline session_t *
      23        2042 : bio_session (BIO *bio)
      24             : {
      25        4084 :   return session_get_from_handle (pointer_to_uword (BIO_get_data (bio)));
      26             : }
      27             : 
      28             : static int
      29           4 : bio_dtls_alloc (BIO *bio)
      30             : {
      31           4 :   BIO_set_init (bio, 0);
      32           4 :   BIO_set_data (bio, 0);
      33           4 :   BIO_set_flags (bio, 0);
      34           4 :   BIO_set_shutdown (bio, 0);
      35           4 :   return 1;
      36             : }
      37             : 
      38             : static int
      39           4 : bio_dtls_free (BIO *bio)
      40             : {
      41           4 :   if (!bio)
      42           0 :     return 0;
      43             : 
      44           4 :   if (BIO_get_shutdown (bio))
      45             :     {
      46           0 :       if (BIO_get_init (bio))
      47           0 :         session_close (bio_session (bio));
      48           0 :       BIO_set_init (bio, 0);
      49           0 :       BIO_set_flags (bio, 0);
      50             :     }
      51           4 :   return 1;
      52             : }
      53             : 
      54             : static int
      55        1010 : bio_dtls_read (BIO *b, char *out, int outl)
      56             : {
      57             :   app_session_transport_t at;
      58             :   session_t *s;
      59             :   int rv;
      60             : 
      61        1010 :   if (PREDICT_FALSE (!out))
      62           0 :     return 0;
      63             : 
      64        1010 :   s = bio_session (b);
      65        1010 :   if (!s)
      66             :     {
      67           0 :       clib_warning ("no session");
      68           0 :       errno = EBADFD;
      69           0 :       return -1;
      70             :     }
      71             : 
      72        1010 :   rv = app_recv_dgram_raw (s->rx_fifo, (u8 *) out, outl, &at,
      73             :                            0 /* clear evt */, 0 /* peek */);
      74             : 
      75        1010 :   if (rv < 0)
      76             :     {
      77           0 :       BIO_set_retry_read (b);
      78           0 :       errno = EAGAIN;
      79           0 :       return -1;
      80             :     }
      81             : 
      82        1010 :   if (svm_fifo_is_empty_cons (s->rx_fifo))
      83          96 :     svm_fifo_unset_event (s->rx_fifo);
      84             : 
      85        1010 :   BIO_clear_retry_flags (b);
      86             : 
      87        1010 :   return rv;
      88             : }
      89             : 
      90             : static int
      91        1006 : bio_dtls_write (BIO *b, const char *in, int inl)
      92             : {
      93        1006 :   app_session_transport_t at = { 0 };
      94             :   svm_msg_q_t *mq;
      95             :   session_t *s;
      96             :   int rv;
      97             : 
      98        1006 :   if (PREDICT_FALSE (!in))
      99           0 :     return 0;
     100             : 
     101        1006 :   s = bio_session (b);
     102        1006 :   if (!s)
     103             :     {
     104           0 :       clib_warning ("no session");
     105           0 :       errno = EBADFD;
     106           0 :       return -1;
     107             :     }
     108             : 
     109        1006 :   mq = session_main_get_vpp_event_queue (s->thread_index);
     110        1006 :   rv = app_send_dgram_raw (s->tx_fifo, &at, mq, (u8 *) in, inl,
     111             :                            SESSION_IO_EVT_TX, 1 /* do_evt */, 0 /* noblock */);
     112             : 
     113        1006 :   if (rv <= 0)
     114             :     {
     115           0 :       BIO_set_retry_read (b);
     116           0 :       errno = EAGAIN;
     117           0 :       return -1;
     118             :     }
     119             : 
     120        1006 :   BIO_clear_retry_flags (b);
     121             : 
     122        1006 :   return rv;
     123             : }
     124             : 
     125             : static int
     126          24 : dtls_dgram_overhead (BIO *b)
     127             : {
     128          24 :   session_t *s = bio_session (b);
     129          24 :   if (session_type_is_ip4 (s->session_type))
     130             :     /* 20B ip 8B udp */
     131          24 :     return 28;
     132             :   else
     133             :     /* 40B ip 8B udp */
     134           0 :     return 48;
     135             : }
     136             : 
     137             : static u16
     138           2 : dtls_dgram_mss (BIO *b)
     139             : {
     140           2 :   session_t *s = bio_session (b);
     141             :   transport_send_params_t sp;
     142             : 
     143           2 :   transport_connection_snd_params (session_get_transport (s), &sp);
     144             : 
     145           2 :   return sp.snd_mss;
     146             : }
     147             : 
     148             : long
     149          54 : bio_dtls_ctrl (BIO *b, int cmd, long larg, void *parg)
     150             : {
     151          54 :   long ret = 1;
     152             : 
     153          54 :   switch (cmd)
     154             :     {
     155           0 :     case BIO_C_SET_FD:
     156           0 :       os_panic ();
     157           0 :       break;
     158           0 :     case BIO_C_GET_FD:
     159           0 :       os_panic ();
     160           0 :       break;
     161           0 :     case BIO_CTRL_GET_CLOSE:
     162           0 :       ret = BIO_get_shutdown (b);
     163           0 :       break;
     164           0 :     case BIO_CTRL_SET_CLOSE:
     165           0 :       BIO_set_shutdown (b, (int) larg);
     166           0 :       break;
     167           6 :     case BIO_CTRL_PENDING:
     168             :     case BIO_CTRL_WPENDING:
     169           6 :       ret = 0;
     170           6 :       break;
     171           6 :     case BIO_CTRL_DUP:
     172             :     case BIO_CTRL_FLUSH:
     173           6 :       ret = 1;
     174           6 :       break;
     175           2 :     case BIO_CTRL_DGRAM_QUERY_MTU:
     176           2 :       ret = dtls_dgram_mss (b);
     177           2 :       break;
     178           0 :     case BIO_CTRL_DGRAM_SET_MTU:
     179           0 :       ret = 0;
     180           0 :       break;
     181          12 :     case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
     182          12 :       ret = 0;
     183          12 :       break;
     184          24 :     case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
     185          24 :       ret = dtls_dgram_overhead (b);
     186          24 :       break;
     187           4 :     default:
     188           4 :       ret = 0;
     189           4 :       break;
     190             :     }
     191          54 :   return ret;
     192             : }
     193             : 
     194             : BIO *
     195           4 : BIO_new_dtls (session_handle_t sh)
     196             : {
     197             :   static BIO_METHOD *dtls_bio_method;
     198             :   BIO *b;
     199             : 
     200           4 :   if (!dtls_bio_method)
     201             :     {
     202           1 :       dtls_bio_method = BIO_meth_new (BIO_TYPE_SOCKET, "dtls_bio");
     203           1 :       BIO_meth_set_write (dtls_bio_method, bio_dtls_write);
     204           1 :       BIO_meth_set_read (dtls_bio_method, bio_dtls_read);
     205           1 :       BIO_meth_set_create (dtls_bio_method, bio_dtls_alloc);
     206           1 :       BIO_meth_set_destroy (dtls_bio_method, bio_dtls_free);
     207           1 :       BIO_meth_set_ctrl (dtls_bio_method, bio_dtls_ctrl);
     208             :     }
     209             : 
     210           4 :   b = BIO_new (dtls_bio_method);
     211             : 
     212             :   /* Initialize the BIO */
     213           4 :   BIO_set_data (b, uword_to_pointer (sh, void *));
     214           4 :   BIO_set_init (b, 1);
     215             : 
     216           4 :   return b;
     217             : }
     218             : 
     219             : /*
     220             :  * fd.io coding-style-patch-verification: ON
     221             :  *
     222             :  * Local Variables:
     223             :  * eval: (c-set-style "gnu")
     224             :  * End:
     225             :  */

Generated by: LCOV version 1.14