|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
9 #define MAX_QUEUE 12000
10 #define PTLS_MAX_PLAINTEXT_RECORD_SIZE 16384
13 #ifdef PTLS_OPENSSL_HAVE_X25519
16 #ifdef PTLS_OPENSSL_HAVE_SECP256R1
17 &ptls_openssl_secp256r1,
19 #ifdef PTLS_OPENSSL_HAVE_SECP384R1
20 &ptls_openssl_secp384r1,
22 #ifdef PTLS_OPENSSL_HAVE_SECP521R1
23 &ptls_openssl_secp521r1
39 (*ctx)->ctx.c_thread_index = thread_id;
42 (*ctx)->ptls_ctx_idx =
ctx - pm->
ctx_pool[thread_id];
51 ptls_free (ptls_ctx->
tls);
96 return ptls_handshake_is_complete (ptls_ctx->
tls);
103 u32 enq_max, enq_now;
117 enq_now =
clib_min (enq_now, buf_left);
128 ptls_context_t *ptls_ctx;
133 if (!ckpair || !ckpair->
cert || !ckpair->
key)
135 TLS_DBG (1,
"tls cert and/or key not configured %d",
136 lctx->parent_app_wrk_index);
142 ptls_ctx =
malloc (
sizeof (ptls_context_t));
145 memset (ptls_ctx, 0,
sizeof (ptls_context_t));
146 ptls_ctx->update_open_count = NULL;
156 ptls_ctx->random_bytes = ptls_openssl_random_bytes;
158 ptls_ctx->get_time = &ptls_get_time;
160 lctx->tls_ssl_ctx = ptls_lctx_idx;
171 ptls_lctx_index = lctx->tls_ssl_ctx;
183 ctx->no_app_session = 1;
224 int rv = PTLS_ERROR_IN_PROGRESS, write = 0,
i = 0, read = 0,
len;
227 const int n_segs = 2, max_len = 16384;
228 ptls_t *tls = ptls_ctx->
tls;
232 ptls_buffer_init (
buf,
"", 0);
238 while (read <
len &&
i < n_segs)
241 rv = ptls_handshake (tls,
buf, fs[
i].
data, &deq_now, NULL);
246 if (!(
rv == 0 ||
rv == PTLS_ERROR_IN_PROGRESS))
255 if (deq_now < fs[
i].
len)
257 fs[
i].
data += deq_now;
258 fs[
i].
len -= deq_now;
267 ptls_buffer_dispose (
buf);
280 if (fs[idx].
len <= to_copy)
284 to_copy -= fs[idx].
len;
294 fs[idx].
len -= to_copy;
295 fs[idx].
data += to_copy;
311 int ret,
i = 0, read = 0, tcp_len, n_fs_app;
312 const int n_segs = 4, max_len = 1 << 16;
332 wrote += to_copy -
left;
341 while (ai < n_fs_app && read < tcp_len)
344 min_buf_len = deq_now + (16 << 10);
345 is_nocopy = app_fs[ai].
len < min_buf_len ? 0 : 1;
348 ptls_buffer_init (
buf, app_fs[ai].
data, app_fs[ai].
len);
349 ret = ptls_receive (ptls_ctx->
tls,
buf, tcp_fs[
i].
data, &deq_now);
350 assert (ret == 0 || ret == PTLS_ERROR_IN_PROGRESS);
353 if (
buf->off == app_fs[ai].
len)
359 app_fs[ai].
len -=
buf->off;
367 ret = ptls_receive (ptls_ctx->
tls,
buf, tcp_fs[
i].
data, &deq_now);
368 assert (ret == 0 || ret == PTLS_ERROR_IN_PROGRESS);
385 if (deq_now < tcp_fs[
i].
len)
387 tcp_fs[
i].
data += deq_now;
388 tcp_fs[
i].
len -= deq_now;
425 if (ptls_is_server (ptls_ctx->
tls))
444 tcp_rx_fifo = tcp_session->
rx_fifo;
448 if (wrote && app_session->
session_state >= SESSION_STATE_READY)
459 u32 dst_space,
u8 *is_nocopy)
461 int record_overhead = ptls_get_record_overhead (ptls_ctx->
tls);
463 u32 deq_len, total_overhead;
465 if (dst_chunk >=
clib_min (8192, src_chunk + record_overhead))
468 deq_len =
clib_min (src_chunk, dst_chunk);
470 total_overhead = num_records * record_overhead;
471 if (deq_len + total_overhead > dst_chunk)
472 deq_len = dst_chunk - total_overhead;
476 deq_len =
clib_min (src_chunk, dst_space);
478 total_overhead = num_records * record_overhead;
479 if (deq_len + total_overhead > dst_space)
480 deq_len = dst_space - total_overhead;
491 int read = 0,
rv,
i = 0,
len, n_tcp_segs = 4, deq_len;
492 const int n_app_segs = 2, min_chunk = 2048;
495 ptls_buffer_t _buf, *
buf = &_buf;
497 u8 is_nocopy, *app_buf;
501 app_tx_fifo = app_session->
tx_fifo;
512 while ((
left =
len - read) &&
ti < n_tcp_segs)
516 if (wrote &&
left < min_chunk)
520 if (app_fs[
i].
len < min_chunk && min_chunk <
left)
522 app_buf_len = app_fs[
i].
len + app_fs[
i + 1].
len;
528 app_fs[
i + 1].
data, app_buf_len - app_fs[
i].
len);
529 first_chunk_len = app_fs[
i].
len;
534 app_buf = app_fs[
i].
data;
535 app_buf_len = app_fs[
i].
len;
540 max_enq = tcp_fs[
ti].
len;
541 max_enq +=
ti < (n_tcp_segs - 1) ? tcp_fs[
ti + 1].
len : 0;
544 max_enq, &is_nocopy);
548 rv = ptls_send (ptls_ctx->
tls,
buf, app_buf, deq_len);
562 rv = ptls_send (ptls_ctx->
tls,
buf, app_buf, deq_len);
572 ASSERT (deq_len >= first_chunk_len);
574 if (deq_len == app_buf_len)
580 app_fs[
i].
len -= deq_len - first_chunk_len;
581 app_fs[
i].
data += deq_len - first_chunk_len;
607 u32 deq_max, deq_now, enq_max, enq_buf, wrote = 0;
612 tcp_tx_fifo = tcp_session->
tx_fifo;
619 deq_max =
clib_min (deq_max, enq_max);
633 if (enq_max < wrote + enq_buf)
641 app_session->
flags |= SESSION_F_CUSTOM_TX;
650 u32 ptls_lctx_idx =
ctx->tls_ssl_ctx;
655 if (ptls_ctx->
tls == NULL)
657 TLS_DBG (1,
"Failed to initialize ptls_ssl structure");
673 ptls_handshake_properties_t hsprop = { { { { NULL } } } };
676 ptls_buffer_t hs_buf;
678 ptls_ctx->
tls = ptls_new (client_ptls_ctx, 0);
679 if (ptls_ctx->
tls == NULL)
681 TLS_DBG (1,
"Failed to initialize ptls_ssl structure");
688 ptls_buffer_init (&hs_buf,
"", 0);
689 if (ptls_handshake (ptls_ctx->
tls, &hs_buf, NULL, NULL, &hsprop) !=
690 PTLS_ERROR_IN_PROGRESS)
692 TLS_DBG (1,
"Failed to initialize tls connection");
697 ptls_buffer_dispose (&hs_buf);
714 memset (*client_ptls_ctx, 0,
sizeof (ptls_context_t));
716 (*client_ptls_ctx)->update_open_count = NULL;
718 (*client_ptls_ctx)->random_bytes = ptls_openssl_random_bytes;
720 (*client_ptls_ctx)->get_time = &ptls_get_time;
772 .version = VPP_BUILD_VER,
773 .description =
"Transport Layer Security (TLS) Engine, Picotls Based",
int picotls_init_client_ptls_ctx(ptls_context_t **client_ptls_ctx)
static u8 svm_fifo_set_event(svm_fifo_t *f)
Set fifo event flag.
int svm_fifo_segments(svm_fifo_t *f, u32 offset, svm_fifo_seg_t *fs, u32 n_segs, u32 max_bytes)
Get pointers to fifo chunks data in svm_fifo_seg_t array.
static int picotls_try_handshake_write(picotls_ctx_t *ptls_ctx, session_t *tls_session, ptls_buffer_t *buf)
static u32 svm_fifo_size(svm_fifo_t *f)
int session_dequeue_notify(session_t *s)
static void picotls_listen_ctx_free(picotls_listen_ctx_t *lctx)
int tls_notify_app_connected(tls_ctx_t *ctx, session_error_t err)
ptls_context_t * ptls_ctx
static int picotls_ctx_init_server(tls_ctx_t *ctx)
void session_transport_closing_notify(transport_connection_t *tc)
Notification from transport that connection is being closed.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static int picotls_do_handshake(picotls_ctx_t *ptls_ctx, session_t *tcp_session)
static int picotls_app_close(tls_ctx_t *ctx)
static u8 svm_fifo_needs_deq_ntf(svm_fifo_t *f, u32 n_last_deq)
Check if fifo needs dequeue notification.
int load_bio_certificate_chain(ptls_context_t *ctx, const char *cert_data)
int svm_fifo_provision_chunks(svm_fifo_t *f, svm_fifo_seg_t *fs, u32 n_segs, u32 len)
Provision and return chunks for number of bytes requested.
int tls_notify_app_accept(tls_ctx_t *ctx)
void tls_notify_app_enqueue(tls_ctx_t *ctx, session_t *app_session)
#define SESSION_INVALID_INDEX
u8 thread_index
Index of the thread that allocated the session.
ptls_context_t * client_ptls_ctx
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
void session_transport_closed_notify(transport_connection_t *tc)
Notification from transport that it is closed.
static u8 picotls_handshake_is_over(tls_ctx_t *ctx)
int load_bio_private_key(ptls_context_t *ctx, const char *pk_data)
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
void session_free(session_t *s)
#define pool_put_index(p, i)
Free pool element with given index.
picotls_main_t picotls_main
tls_ctx_t * picotls_ctx_get_w_thread(u32 ctx_index, u8 thread_index)
ptls_cipher_suite_t * ptls_vpp_crypto_cipher_suites[]
void tls_disconnect_transport(tls_ctx_t *ctx)
ptls_buffer_t read_buffer
struct _svm_fifo svm_fifo_t
static int picotls_ctx_read(tls_ctx_t *ctx, session_t *tcp_session)
static u32 ptls_tcp_to_app_write(picotls_ctx_t *ptls_ctx, svm_fifo_t *app_rx_fifo, svm_fifo_t *tcp_rx_fifo)
@ TRANSPORT_SND_F_DESCHED
@ SVM_FIFO_WANT_DEQ_NOTIF
Notify on dequeue.
#define TLS_DBG(_lvl, _fmt, _args...)
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
int tls_add_vpp_q_builtin_rx_evt(session_t *s)
tls_ctx_t * picotls_ctx_get(u32 ctx_index)
static void svm_fifo_clear_deq_ntf(svm_fifo_t *f)
Clear the want notification flag and set has notification.
void svm_fifo_enqueue_nocopy(svm_fifo_t *f, u32 len)
Advance tail.
clib_rwlock_t crypto_keys_rw_lock
static int picotls_transport_close(tls_ctx_t *ctx)
static_always_inline uword vlib_get_thread_index(void)
picotls_listen_ctx_t * picotls_lctx_get(u32 lctx_index)
int svm_fifo_dequeue_drop(svm_fifo_t *f, u32 len)
Dequeue and drop bytes from fifo.
int svm_fifo_enqueue(svm_fifo_t *f, u32 len, const u8 *src)
Enqueue data to fifo.
u32 svm_fifo_max_write_chunk(svm_fifo_t *f)
Max contiguous chunk of data that can be written.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static session_t * session_get_from_handle(session_handle_t handle)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
static u32 picotls_ctx_alloc(void)
static u32 picotls_listen_ctx_alloc(void)
static session_t * session_get(u32 si, u32 thread_index)
static void clib_rwlock_init(clib_rwlock_t *p)
static int picotls_ctx_init_client(tls_ctx_t *ctx)
static clib_error_t * tls_picotls_init(vlib_main_t *vm)
static u32 ptls_compute_deq_len(picotls_ctx_t *ptls_ctx, u32 dst_chunk, u32 src_chunk, u32 dst_space, u8 *is_nocopy)
static int picotls_start_listen(tls_ctx_t *lctx)
static ptls_key_exchange_algorithm_t * default_key_exchange[]
static int picotls_ctx_write(tls_ctx_t *ctx, session_t *app_session, transport_send_params_t *sp)
#define vec_free(V)
Free vector's memory (no header).
static void picotls_handle_handshake_failure(tls_ctx_t *ctx)
#define TLSP_MIN_ENQ_SPACE
static u32 svm_fifo_max_enqueue_prod(svm_fifo_t *f)
Maximum number of bytes that can be enqueued into fifo.
#define VLIB_INIT_FUNCTION(x)
#define SESSION_INVALID_HANDLE
int tls_add_vpp_q_tx_evt(session_t *s)
picotls_ctx_t *** ctx_pool
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
picotls_listen_ctx_t * lctx_pool
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
#define clib_error(format, args...)
transport_snd_flags_t flags
void * malloc(size_t size)
app_cert_key_pair_t * app_cert_key_pair_get_if_valid(u32 index)
static int picotls_stop_listen(tls_ctx_t *lctx)
const static tls_engine_vft_t picotls_engine
static int ptls_copy_buf_to_fs(ptls_buffer_t *buf, u32 to_copy, svm_fifo_seg_t *fs, u32 *fs_idx, u32 max_fs)
void tls_register_engine(const tls_engine_vft_t *vft, crypto_engine_type_t type)
static vlib_thread_main_t * vlib_get_thread_main()
static u32 svm_fifo_max_dequeue_cons(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for consumer.
static void svm_fifo_add_want_deq_ntf(svm_fifo_t *f, u8 ntf_type)
Set specific want notification flag.
int session_send_io_evt_to_thread(svm_fifo_t *f, session_evt_type_t evt_type)
volatile u8 session_state
State in session layer state machine.
static void picotls_ctx_free(tls_ctx_t *ctx)
static void * clib_mem_alloc(uword size)
static void picotls_confirm_app_close(tls_ctx_t *ctx)
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Fifo max bytes to dequeue.
static u32 ptls_app_to_tcp_write(picotls_ctx_t *ptls_ctx, session_t *app_session, svm_fifo_t *tcp_tx_fifo, u32 max_len)
#define PTLS_MAX_PLAINTEXT_RECORD_SIZE
static void transport_connection_deschedule(transport_connection_t *tc)