- int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND;
- char line[256];
- ptls_base64_decode_state_t state;
-
- /* Get the label on a line by itself */
- while (BIO_gets (bio, line, 256))
- {
- if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
- {
- ret = 0;
- ptls_base64_decode_init (&state);
- break;
- }
- }
- /* Get the data in the buffer */
- while (ret == 0 && BIO_gets (bio, line, 256))
- {
- if (ptls_compare_separator_line (line, "END", label) == 0)
- {
- if (state.status == PTLS_BASE64_DECODE_DONE
- || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
- && state.nbc == 0))
- {
- ret = 0;
- }
- else
- {
- ret = PTLS_ERROR_INCORRECT_BASE64;
- }
- break;
- }
- else
- {
- ret = ptls_base64_decode (line, &state, buf);
- }
- }
-
- return ret;
-}
-
-static int
-ptls_load_bio_pem_objects (BIO * bio, const char *label, ptls_iovec_t * list,
- size_t list_max, size_t * nb_objects)
-{
- int ret = 0;
- size_t count = 0;
-
- *nb_objects = 0;
-
- if (ret == 0)
- {
- while (count < list_max)
- {
- ptls_buffer_t buf;
-
- ptls_buffer_init (&buf, "", 0);
-
- ret = ptls_get_bio_pem_object (bio, label, &buf);
-
- if (ret == 0)
- {
- if (buf.off > 0 && buf.is_allocated)
- {
- list[count].base = buf.base;
- list[count].len = buf.off;
- count++;
- }
- else
- {
- ptls_buffer_dispose (&buf);
- }
- }
- else
- {
- ptls_buffer_dispose (&buf);
- break;
- }
- }
- }
-
- if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
- {
- ret = 0;
- }
-
- *nb_objects = count;
-
- return ret;
-}
-
-#define PTLS_MAX_CERTS_IN_CONTEXT 16
-
-static int
-ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
-{
- int ret = 0;
-
- ctx->certificates.list =
- (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
- sizeof (ptls_iovec_t));
-
- if (ctx->certificates.list == NULL)
- {
- ret = PTLS_ERROR_NO_MEMORY;
- }
- else
- {
- ret =
- ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
- PTLS_MAX_CERTS_IN_CONTEXT,
- &ctx->certificates.count);
- }
-
- return ret;
-}
-
-static inline void
-load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
-{
- BIO *cert_bio;
- cert_bio = BIO_new_mem_buf (cert_data, -1);
- if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
- {
- BIO_free (cert_bio);
- fprintf (stderr, "failed to load certificate:%s\n", strerror (errno));
- exit (1);
- }
- BIO_free (cert_bio);
-}
-
-static inline void
-load_bio_private_key (ptls_context_t * ctx, const char *pk_data)
-{
- static ptls_openssl_sign_certificate_t sc;
- EVP_PKEY *pkey;
- BIO *key_bio;
-
- key_bio = BIO_new_mem_buf (pk_data, -1);
- pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
- BIO_free (key_bio);
-
- if (pkey == NULL)
- {
- fprintf (stderr, "failed to read private key from app configuration\n");
- exit (1);
- }
-
- ptls_openssl_init_sign_certificate (&sc, pkey);
- EVP_PKEY_free (pkey);
-
- ctx->sign_certificate = &sc.super;
-}
-
-static inline void
-quic_make_connection_key (clib_bihash_kv_16_8_t * kv,
- const quicly_cid_plaintext_t * id)
-{
- kv->key[0] = ((u64) id->master_id) << 32 | (u64) id->thread_id;
- kv->key[1] = id->node_id;
-}
-
-static void
-quic_connection_closed (u32 ctx_index, u32 thread_index)
-{
- /* TODO : free fifos */
- QUIC_DBG (2, "QUIC connection closed");
- tw_timer_wheel_1t_3w_1024sl_ov_t *tw;
- clib_bihash_kv_16_8_t kv;
- quicly_conn_t *conn;
- quic_ctx_t *ctx;
-
- ctx = quic_ctx_get (ctx_index, thread_index);
-
- ASSERT (!ctx->c_quic_ctx_id.is_stream);
- /* TODO if connection is not established, just delete the session? */
-
- /* Stop the timer */
- if (ctx->timer_handle != QUIC_TIMER_HANDLE_INVALID)
- {
- tw = &quic_main.wrk_ctx[thread_index].timer_wheel;
- tw_timer_stop_1t_3w_1024sl_ov (tw, ctx->timer_handle);
- }
-
- /* Delete the connection from the connection map */
- conn = ctx->c_quic_ctx_id.conn;
- quic_make_connection_key (&kv, quicly_get_master_id (conn));
- QUIC_DBG (2, "Deleting conn with id %lu %lu", kv.key[0], kv.key[1]);
- clib_bihash_add_del_16_8 (&quic_main.connection_hash, &kv, 0 /* is_add */ );
-
- quic_disconnect_transport (ctx);
- session_transport_delete_notify (&ctx->connection);
- /* Do not try to send anything anymore */
- quicly_free (ctx->c_quic_ctx_id.conn);
- ctx->c_quic_ctx_id.conn = NULL;
- quic_ctx_free (ctx);
-}
-
-static void
-allocate_quicly_ctx (application_t * app, u8 is_client)
-{
- struct
- {
- quicly_context_t _;
- char cid_key[17];
- } *ctx_data;
- quicly_context_t *quicly_ctx;
- ptls_iovec_t key_vec;
- QUIC_DBG (2, "Called allocate_quicly_ctx");
-
- if (app->quicly_ctx)
- {
- QUIC_DBG (1, "Trying to reallocate quicly_ctx");
- return;
- }
-
- ctx_data = malloc (sizeof (*ctx_data));
- quicly_ctx = &ctx_data->_;
- app->quicly_ctx = (u64 *) quicly_ctx;
- memcpy (quicly_ctx, &quicly_spec_context, sizeof (quicly_context_t));
-
- quicly_ctx->max_packet_size = QUIC_MAX_PACKET_SIZE;
- quicly_ctx->tls = &quic_tlsctx;
- quicly_ctx->stream_open = &on_stream_open;
- quicly_ctx->closed_by_peer = &on_closed_by_peer;
- quicly_ctx->now = &quicly_vpp_now_cb;
-
- quicly_amend_ptls_context (quicly_ctx->tls);
-
- quicly_ctx->event_log.mask = 0; /* logs */
- quicly_ctx->event_log.cb = quicly_new_default_event_logger (stderr);
-
- quicly_ctx->transport_params.max_data = QUIC_INT_MAX;
- quicly_ctx->transport_params.max_streams_uni = QUIC_INT_MAX;
- quicly_ctx->transport_params.max_streams_bidi = QUIC_INT_MAX;
- quicly_ctx->transport_params.max_stream_data.bidi_local = (QUIC_FIFO_SIZE - 1); /* max_enq is SIZE - 1 */
- quicly_ctx->transport_params.max_stream_data.bidi_remote = (QUIC_FIFO_SIZE - 1); /* max_enq is SIZE - 1 */
- quicly_ctx->transport_params.max_stream_data.uni = QUIC_INT_MAX;
-
- quicly_ctx->tls->random_bytes (ctx_data->cid_key, 16);
- ctx_data->cid_key[16] = 0;
- key_vec = ptls_iovec_init (ctx_data->cid_key, strlen (ctx_data->cid_key));
- quicly_ctx->cid_encryptor =
- quicly_new_default_cid_encryptor (&ptls_openssl_bfecb,
- &ptls_openssl_sha256, key_vec);
- if (!is_client && app->tls_key != NULL && app->tls_cert != NULL)
- {
- load_bio_private_key (quicly_ctx->tls, (char *) app->tls_key);
- load_bio_certificate_chain (quicly_ctx->tls, (char *) app->tls_cert);
- }
-}
-
-
-/*****************************************************************************
- * BEGIN TIMERS HANDLING
- *****************************************************************************/
-
-static int64_t
-quic_get_thread_time (u8 thread_index)
-{
- return quic_main.wrk_ctx[thread_index].time_now;
-}
-
-static int64_t
-quic_get_time (quicly_now_t * self)
-{
- u8 thread_index = vlib_get_thread_index ();
- return quic_get_thread_time (thread_index);
-}
-
-static u32
-quic_set_time_now (u32 thread_index)
-{
- vlib_main_t *vlib_main = vlib_get_main ();
- f64 time = vlib_time_now (vlib_main);
- quic_main.wrk_ctx[thread_index].time_now = (int64_t) (time * 1000.f);
- return quic_main.wrk_ctx[thread_index].time_now;
-}
-
-/* Transport proto callback */
-static void
-quic_update_time (f64 now, u8 thread_index)
-{
- tw_timer_wheel_1t_3w_1024sl_ov_t *tw;