FD.io VPP  v21.06
Vector Packet Processing
dtls_bio.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 <openssl/bio.h>
17 #include <openssl/err.h>
18 
19 #include <vnet/session/session.h>
21 
22 static inline session_t *
23 bio_session (BIO *bio)
24 {
25  return session_get_from_handle (pointer_to_uword (BIO_get_data (bio)));
26 }
27 
28 static int
29 bio_dtls_alloc (BIO *bio)
30 {
31  BIO_set_init (bio, 0);
32  BIO_set_data (bio, 0);
33  BIO_set_flags (bio, 0);
34  BIO_set_shutdown (bio, 0);
35  return 1;
36 }
37 
38 static int
39 bio_dtls_free (BIO *bio)
40 {
41  if (!bio)
42  return 0;
43 
44  if (BIO_get_shutdown (bio))
45  {
46  if (BIO_get_init (bio))
47  session_close (bio_session (bio));
48  BIO_set_init (bio, 0);
49  BIO_set_flags (bio, 0);
50  }
51  return 1;
52 }
53 
54 static int
55 bio_dtls_read (BIO *b, char *out, int outl)
56 {
58  session_t *s;
59  int rv;
60 
61  if (PREDICT_FALSE (!out))
62  return 0;
63 
64  s = bio_session (b);
65  if (!s)
66  {
67  clib_warning ("no session");
68  errno = EBADFD;
69  return -1;
70  }
71 
72  rv = app_recv_dgram_raw (s->rx_fifo, (u8 *) out, outl, &at,
73  0 /* clear evt */, 0 /* peek */);
74 
75  if (rv < 0)
76  {
77  BIO_set_retry_read (b);
78  errno = EAGAIN;
79  return -1;
80  }
81 
84 
85  BIO_clear_retry_flags (b);
86 
87  return rv;
88 }
89 
90 static int
91 bio_dtls_write (BIO *b, const char *in, int inl)
92 {
93  app_session_transport_t at = { 0 };
94  svm_msg_q_t *mq;
95  session_t *s;
96  int rv;
97 
98  if (PREDICT_FALSE (!in))
99  return 0;
100 
101  s = bio_session (b);
102  if (!s)
103  {
104  clib_warning ("no session");
105  errno = EBADFD;
106  return -1;
107  }
108 
110  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  if (rv <= 0)
114  {
115  BIO_set_retry_read (b);
116  errno = EAGAIN;
117  return -1;
118  }
119 
120  BIO_clear_retry_flags (b);
121 
122  return rv;
123 }
124 
125 static int
127 {
128  session_t *s = bio_session (b);
130  /* 20B ip 8B udp */
131  return 28;
132  else
133  /* 40B ip 8B udp */
134  return 48;
135 }
136 
137 static u16
139 {
140  session_t *s = bio_session (b);
142 
144 
145  return sp.snd_mss;
146 }
147 
148 long
149 bio_dtls_ctrl (BIO *b, int cmd, long larg, void *parg)
150 {
151  long ret = 1;
152 
153  switch (cmd)
154  {
155  case BIO_C_SET_FD:
156  os_panic ();
157  break;
158  case BIO_C_GET_FD:
159  os_panic ();
160  break;
161  case BIO_CTRL_GET_CLOSE:
162  ret = BIO_get_shutdown (b);
163  break;
164  case BIO_CTRL_SET_CLOSE:
165  BIO_set_shutdown (b, (int) larg);
166  break;
167  case BIO_CTRL_PENDING:
168  case BIO_CTRL_WPENDING:
169  ret = 0;
170  break;
171  case BIO_CTRL_DUP:
172  case BIO_CTRL_FLUSH:
173  ret = 1;
174  break;
175  case BIO_CTRL_DGRAM_QUERY_MTU:
176  ret = dtls_dgram_mss (b);
177  break;
178  case BIO_CTRL_DGRAM_SET_MTU:
179  ret = 0;
180  break;
181  case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
182  ret = 0;
183  break;
184  case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
185  ret = dtls_dgram_overhead (b);
186  break;
187  default:
188  ret = 0;
189  break;
190  }
191  return ret;
192 }
193 
194 BIO *
196 {
197  static BIO_METHOD *dtls_bio_method;
198  BIO *b;
199 
200  if (!dtls_bio_method)
201  {
202  dtls_bio_method = BIO_meth_new (BIO_TYPE_SOCKET, "dtls_bio");
203  BIO_meth_set_write (dtls_bio_method, bio_dtls_write);
204  BIO_meth_set_read (dtls_bio_method, bio_dtls_read);
205  BIO_meth_set_create (dtls_bio_method, bio_dtls_alloc);
206  BIO_meth_set_destroy (dtls_bio_method, bio_dtls_free);
207  BIO_meth_set_ctrl (dtls_bio_method, bio_dtls_ctrl);
208  }
209 
210  b = BIO_new (dtls_bio_method);
211 
212  /* Initialize the BIO */
213  BIO_set_data (b, uword_to_pointer (sh, void *));
214  BIO_set_init (b, 1);
215 
216  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  */
BIO * BIO_new_dtls(session_handle_t sh)
Definition: dtls_bio.c:195
session_type_t session_type
Type built from transport and network protocol types.
svm_fifo_t * tx_fifo
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
Definition: session.h:716
transport_connection_t * session_get_transport(session_t *s)
Definition: session.c:1745
static u16 dtls_dgram_mss(BIO *b)
Definition: dtls_bio.c:138
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
static int svm_fifo_is_empty_cons(svm_fifo_t *f)
Check if fifo is empty optimized for consumer.
Definition: svm_fifo.h:554
static u32 transport_connection_snd_params(transport_connection_t *tc, transport_send_params_t *sp)
Get send parameters for transport connection.
Definition: transport.h:204
unsigned char u8
Definition: types.h:56
vlib_buffer_t ** b
static int bio_dtls_free(BIO *bio)
Definition: dtls_bio.c:39
int __clib_unused rv
Definition: application.c:491
static int app_recv_dgram_raw(svm_fifo_t *f, u8 *buf, u32 len, app_session_transport_t *at, u8 clear_evt, u8 peek)
static int bio_dtls_write(BIO *b, const char *in, int inl)
Definition: dtls_bio.c:91
static session_t * bio_session(BIO *bio)
Definition: dtls_bio.c:23
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:356
unsigned short u16
Definition: types.h:57
static int bio_dtls_alloc(BIO *bio)
Definition: dtls_bio.c:29
#define PREDICT_FALSE(x)
Definition: clib.h:124
static void svm_fifo_unset_event(svm_fifo_t *f)
Unset fifo event flag.
Definition: svm_fifo.h:803
static int app_send_dgram_raw(svm_fifo_t *f, app_session_transport_t *at, svm_msg_q_t *vpp_evt_q, u8 *data, u32 len, u8 evt_type, u8 do_evt, u8 noblock)
static int bio_dtls_read(BIO *b, char *out, int outl)
Definition: dtls_bio.c:55
void os_panic(void)
#define clib_warning(format, args...)
Definition: error.h:59
#define uword_to_pointer(u, type)
Definition: types.h:136
static int dtls_dgram_overhead(BIO *b)
Definition: dtls_bio.c:126
long bio_dtls_ctrl(BIO *b, int cmd, long larg, void *parg)
Definition: dtls_bio.c:149
static uword pointer_to_uword(const void *p)
Definition: types.h:131
u8 thread_index
Index of the thread that allocated the session.
static u8 session_type_is_ip4(session_type_t st)
u64 session_handle_t
void session_close(session_t *s)
Initialize session closing procedure.
Definition: session.c:1496