Lines Matching +full:port +full:- +full:id
2 * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
24 * QUIC Port Structure
29 static int port_init(QUIC_PORT *port);
30 static void port_cleanup(QUIC_PORT *port);
34 static void port_rx_pre(QUIC_PORT *port);
51 * An original connection ID (`QUIC_CONN_ID`) used to identify the QUIC
52 * connection. This ID helps associate the token with a specific connection.
79 * - timestamp is 8 bytes
80 * - odcid and rscid are maximally 42 bytes in total
81 * - remote_addr_len is a size_t (8 bytes)
82 * - remote_addr is in the worst case 110 bytes (in the case of using a
84 * - is_retry is a single byte
98 DEFINE_LIST_OF_IMPL(port, QUIC_PORT);
102 QUIC_PORT *port; in ossl_quic_port_new() local
104 if ((port = OPENSSL_zalloc(sizeof(QUIC_PORT))) == NULL) in ossl_quic_port_new()
107 port->engine = args->engine; in ossl_quic_port_new()
108 port->channel_ctx = args->channel_ctx; in ossl_quic_port_new()
109 port->is_multi_conn = args->is_multi_conn; in ossl_quic_port_new()
110 port->validate_addr = args->do_addr_validation; in ossl_quic_port_new()
111 port->get_conn_user_ssl = args->get_conn_user_ssl; in ossl_quic_port_new()
112 port->user_ssl_arg = args->user_ssl_arg; in ossl_quic_port_new()
114 if (!port_init(port)) { in ossl_quic_port_new()
115 OPENSSL_free(port); in ossl_quic_port_new()
119 return port; in ossl_quic_port_new()
122 void ossl_quic_port_free(QUIC_PORT *port) in ossl_quic_port_free() argument
124 if (port == NULL) in ossl_quic_port_free()
127 port_cleanup(port); in ossl_quic_port_free()
128 OPENSSL_free(port); in ossl_quic_port_free()
131 static int port_init(QUIC_PORT *port) in port_init() argument
133 size_t rx_short_dcid_len = (port->is_multi_conn ? INIT_DCID_LEN : 0); in port_init()
139 if (port->engine == NULL || port->channel_ctx == NULL) in port_init()
142 if ((port->err_state = OSSL_ERR_STATE_new()) == NULL) in port_init()
145 if ((port->demux = ossl_quic_demux_new(/*BIO=*/NULL, in port_init()
147 get_time, port)) == NULL) in port_init()
150 ossl_quic_demux_set_default_handler(port->demux, in port_init()
152 port); in port_init()
154 if ((port->srtm = ossl_quic_srtm_new(port->engine->libctx, in port_init()
155 port->engine->propq)) == NULL) in port_init()
158 if ((port->lcidm = ossl_quic_lcidm_new(port->engine->libctx, in port_init()
162 port->rx_short_dcid_len = (unsigned char)rx_short_dcid_len; in port_init()
163 port->tx_init_dcid_len = INIT_DCID_LEN; in port_init()
164 port->state = QUIC_PORT_STATE_RUNNING; in port_init()
166 ossl_list_port_insert_tail(&port->engine->port_list, port); in port_init()
167 port->on_engine_list = 1; in port_init()
168 port->bio_changed = 1; in port_init()
171 if ((port->token_ctx = EVP_CIPHER_CTX_new()) == NULL in port_init()
172 || (cipher = EVP_CIPHER_fetch(port->engine->libctx, in port_init()
173 "AES-256-GCM", NULL)) == NULL in port_init()
174 || !EVP_EncryptInit_ex(port->token_ctx, cipher, NULL, NULL, NULL) in port_init()
175 || (key_len = EVP_CIPHER_CTX_get_key_length(port->token_ctx)) <= 0 in port_init()
177 || !RAND_bytes_ex(port->engine->libctx, token_key, key_len, 0) in port_init()
178 || !EVP_EncryptInit_ex(port->token_ctx, NULL, NULL, token_key, NULL)) in port_init()
186 port_cleanup(port); in port_init()
190 static void port_cleanup(QUIC_PORT *port) in port_cleanup() argument
192 assert(ossl_list_ch_num(&port->channel_list) == 0); in port_cleanup()
194 ossl_quic_demux_free(port->demux); in port_cleanup()
195 port->demux = NULL; in port_cleanup()
197 ossl_quic_srtm_free(port->srtm); in port_cleanup()
198 port->srtm = NULL; in port_cleanup()
200 ossl_quic_lcidm_free(port->lcidm); in port_cleanup()
201 port->lcidm = NULL; in port_cleanup()
203 OSSL_ERR_STATE_free(port->err_state); in port_cleanup()
204 port->err_state = NULL; in port_cleanup()
206 if (port->on_engine_list) { in port_cleanup()
207 ossl_list_port_remove(&port->engine->port_list, port); in port_cleanup()
208 port->on_engine_list = 0; in port_cleanup()
211 EVP_CIPHER_CTX_free(port->token_ctx); in port_cleanup()
212 port->token_ctx = NULL; in port_cleanup()
215 static void port_transition_failed(QUIC_PORT *port) in port_transition_failed() argument
217 if (port->state == QUIC_PORT_STATE_FAILED) in port_transition_failed()
220 port->state = QUIC_PORT_STATE_FAILED; in port_transition_failed()
223 int ossl_quic_port_is_running(const QUIC_PORT *port) in ossl_quic_port_is_running() argument
225 return port->state == QUIC_PORT_STATE_RUNNING; in ossl_quic_port_is_running()
228 QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port) in ossl_quic_port_get0_engine() argument
230 return port->engine; in ossl_quic_port_get0_engine()
233 QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port) in ossl_quic_port_get0_reactor() argument
235 return ossl_quic_engine_get0_reactor(port->engine); in ossl_quic_port_get0_reactor()
238 QUIC_DEMUX *ossl_quic_port_get0_demux(QUIC_PORT *port) in ossl_quic_port_get0_demux() argument
240 return port->demux; in ossl_quic_port_get0_demux()
243 CRYPTO_MUTEX *ossl_quic_port_get0_mutex(QUIC_PORT *port) in ossl_quic_port_get0_mutex() argument
245 return ossl_quic_engine_get0_mutex(port->engine); in ossl_quic_port_get0_mutex()
248 OSSL_TIME ossl_quic_port_get_time(QUIC_PORT *port) in ossl_quic_port_get_time() argument
250 return ossl_quic_engine_get_time(port->engine); in ossl_quic_port_get_time()
253 static OSSL_TIME get_time(void *port) in get_time() argument
255 return ossl_quic_port_get_time((QUIC_PORT *)port); in get_time()
258 int ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT *port) in ossl_quic_port_get_rx_short_dcid_len() argument
260 return port->rx_short_dcid_len; in ossl_quic_port_get_rx_short_dcid_len()
263 int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port) in ossl_quic_port_get_tx_init_dcid_len() argument
265 return port->tx_init_dcid_len; in ossl_quic_port_get_tx_init_dcid_len()
268 size_t ossl_quic_port_get_num_incoming_channels(const QUIC_PORT *port) in ossl_quic_port_get_num_incoming_channels() argument
270 return ossl_list_incoming_ch_num(&port->incoming_channel_list); in ossl_quic_port_get_num_incoming_channels()
274 * QUIC Port: Network BIO Configuration
281 if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0) { in validate_poll_descriptor()
289 BIO *ossl_quic_port_get_net_rbio(QUIC_PORT *port) in ossl_quic_port_get_net_rbio() argument
291 return port->net_rbio; in ossl_quic_port_get_net_rbio()
294 BIO *ossl_quic_port_get_net_wbio(QUIC_PORT *port) in ossl_quic_port_get_net_wbio() argument
296 return port->net_wbio; in ossl_quic_port_get_net_wbio()
299 static int port_update_poll_desc(QUIC_PORT *port, BIO *net_bio, int for_write) in port_update_poll_desc() argument
306 /* Non-pollable BIO */ in port_update_poll_desc()
313 * TODO(QUIC MULTIPORT): We currently only support one port per in port_update_poll_desc()
319 * guaranteed to be the only port under it. in port_update_poll_desc()
322 ossl_quic_reactor_set_poll_w(&port->engine->rtor, &d); in port_update_poll_desc()
324 ossl_quic_reactor_set_poll_r(&port->engine->rtor, &d); in port_update_poll_desc()
329 int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port, int force) in ossl_quic_port_update_poll_descriptors() argument
333 if (!force && !port->bio_changed) in ossl_quic_port_update_poll_descriptors()
336 if (!port_update_poll_desc(port, port->net_rbio, /*for_write=*/0)) in ossl_quic_port_update_poll_descriptors()
339 if (!port_update_poll_desc(port, port->net_wbio, /*for_write=*/1)) in ossl_quic_port_update_poll_descriptors()
342 port->bio_changed = 0; in ossl_quic_port_update_poll_descriptors()
350 * - Addressed mode, in which our BIO_sendmmsg calls have destination
354 * - Unaddressed mode, in which the BIO provided to us on the network side
375 static void port_update_addressing_mode(QUIC_PORT *port) in port_update_addressing_mode() argument
379 if (port->net_rbio != NULL) in port_update_addressing_mode()
380 rcaps = BIO_dgram_get_effective_caps(port->net_rbio); in port_update_addressing_mode()
382 if (port->net_wbio != NULL) in port_update_addressing_mode()
383 wcaps = BIO_dgram_get_effective_caps(port->net_wbio); in port_update_addressing_mode()
385 port->addressed_mode_r = ((rcaps & BIO_DGRAM_CAP_PROVIDES_SRC_ADDR) != 0); in port_update_addressing_mode()
386 port->addressed_mode_w = ((wcaps & BIO_DGRAM_CAP_HANDLES_DST_ADDR) != 0); in port_update_addressing_mode()
387 port->bio_changed = 1; in port_update_addressing_mode()
390 int ossl_quic_port_is_addressed_r(const QUIC_PORT *port) in ossl_quic_port_is_addressed_r() argument
392 return port->addressed_mode_r; in ossl_quic_port_is_addressed_r()
395 int ossl_quic_port_is_addressed_w(const QUIC_PORT *port) in ossl_quic_port_is_addressed_w() argument
397 return port->addressed_mode_w; in ossl_quic_port_is_addressed_w()
400 int ossl_quic_port_is_addressed(const QUIC_PORT *port) in ossl_quic_port_is_addressed() argument
402 return ossl_quic_port_is_addressed_r(port) && ossl_quic_port_is_addressed_w(port); in ossl_quic_port_is_addressed()
411 int ossl_quic_port_set_net_rbio(QUIC_PORT *port, BIO *net_rbio) in ossl_quic_port_set_net_rbio() argument
413 if (port->net_rbio == net_rbio) in ossl_quic_port_set_net_rbio()
416 if (!port_update_poll_desc(port, net_rbio, /*for_write=*/0)) in ossl_quic_port_set_net_rbio()
419 ossl_quic_demux_set_bio(port->demux, net_rbio); in ossl_quic_port_set_net_rbio()
420 port->net_rbio = net_rbio; in ossl_quic_port_set_net_rbio()
421 port_update_addressing_mode(port); in ossl_quic_port_set_net_rbio()
425 int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio) in ossl_quic_port_set_net_wbio() argument
429 if (port->net_wbio == net_wbio) in ossl_quic_port_set_net_wbio()
432 if (!port_update_poll_desc(port, net_wbio, /*for_write=*/1)) in ossl_quic_port_set_net_wbio()
435 OSSL_LIST_FOREACH(ch, ch, &port->channel_list) in ossl_quic_port_set_net_wbio()
436 ossl_qtx_set_bio(ch->qtx, net_wbio); in ossl_quic_port_set_net_wbio()
438 port->net_wbio = net_wbio; in ossl_quic_port_set_net_wbio()
439 port_update_addressing_mode(port); in ossl_quic_port_set_net_wbio()
443 SSL_CTX *ossl_quic_port_get_channel_ctx(QUIC_PORT *port) in ossl_quic_port_get_channel_ctx() argument
445 return port->channel_ctx; in ossl_quic_port_get_channel_ctx()
449 * QUIC Port: Channel Lifecycle
453 static SSL *port_new_handshake_layer(QUIC_PORT *port, QUIC_CHANNEL *ch) in port_new_handshake_layer() argument
465 if (!ossl_assert(port->get_conn_user_ssl != NULL)) in port_new_handshake_layer()
467 user_ssl = port->get_conn_user_ssl(ch, port->user_ssl_arg); in port_new_handshake_layer()
471 ql = (QUIC_LISTENER *)port->user_ssl_arg; in port_new_handshake_layer()
475 * existing qc->tls in port_new_handshake_layer()
477 if (!ossl_assert(qc->tls == NULL)) { in port_new_handshake_layer()
482 tls = ossl_ssl_connection_new_int(port->channel_ctx, user_ssl, TLS_method()); in port_new_handshake_layer()
483 qc->tls = tls; in port_new_handshake_layer()
489 if (ql != NULL && ql->obj.ssl.ctx->new_pending_conn_cb != NULL) in port_new_handshake_layer()
490 if (!ql->obj.ssl.ctx->new_pending_conn_cb(ql->obj.ssl.ctx, user_ssl, in port_new_handshake_layer()
491 ql->obj.ssl.ctx->new_pending_conn_arg)) { in port_new_handshake_layer()
497 tls_conn->s3.flags |= TLS1_FLAGS_QUIC | TLS1_FLAGS_QUIC_INTERNAL; in port_new_handshake_layer()
500 tls_conn->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN; in port_new_handshake_layer()
501 tls_conn->pha_enabled = 0; in port_new_handshake_layer()
505 static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx, in port_make_channel() argument
511 args.port = port; in port_make_channel()
513 args.lcidm = port->lcidm; in port_make_channel()
514 args.srtm = port->srtm; in port_make_channel()
521 * the ch->tls and optionally the qlog_title be configured prior to in port_make_channel()
536 ch->tls = (tls != NULL) ? tls : port_new_handshake_layer(port, ch); in port_make_channel()
538 if (ch->tls == NULL) { in port_make_channel()
547 ch->use_qlog = 1; in port_make_channel()
548 if (ch->tls->ctx->qlog_title != NULL) { in port_make_channel()
549 if ((ch->qlog_title = OPENSSL_strdup(ch->tls->ctx->qlog_title)) == NULL) { in port_make_channel()
564 ossl_qtx_set_bio(ch->qtx, port->net_wbio); in port_make_channel()
568 QUIC_CHANNEL *ossl_quic_port_create_outgoing(QUIC_PORT *port, SSL *tls) in ossl_quic_port_create_outgoing() argument
570 return port_make_channel(port, tls, NULL, /* is_server= */ 0, in ossl_quic_port_create_outgoing()
574 QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls) in ossl_quic_port_create_incoming() argument
578 assert(port->tserver_ch == NULL); in ossl_quic_port_create_incoming()
581 * pass -1 for qrx to indicate port will create qrx in ossl_quic_port_create_incoming()
584 ch = port_make_channel(port, tls, NULL, /* is_server= */ 1, in ossl_quic_port_create_incoming()
586 port->tserver_ch = ch; in ossl_quic_port_create_incoming()
587 port->allow_incoming = 1; in ossl_quic_port_create_incoming()
591 QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port) in ossl_quic_port_pop_incoming() argument
595 ch = ossl_list_incoming_ch_head(&port->incoming_channel_list); in ossl_quic_port_pop_incoming()
599 ossl_list_incoming_ch_remove(&port->incoming_channel_list, ch); in ossl_quic_port_pop_incoming()
603 int ossl_quic_port_have_incoming(QUIC_PORT *port) in ossl_quic_port_have_incoming() argument
605 return ossl_list_incoming_ch_head(&port->incoming_channel_list) != NULL; in ossl_quic_port_have_incoming()
608 void ossl_quic_port_drop_incoming(QUIC_PORT *port) in ossl_quic_port_drop_incoming() argument
616 ch = ossl_quic_port_pop_incoming(port); in ossl_quic_port_drop_incoming()
627 * ch->tls ref and frees the channel in ossl_quic_port_drop_incoming()
643 void ossl_quic_port_set_allow_incoming(QUIC_PORT *port, int allow_incoming) in ossl_quic_port_set_allow_incoming() argument
645 port->allow_incoming = allow_incoming; in ossl_quic_port_set_allow_incoming()
649 * QUIC Port: Ticker-Mutator
654 * Tick function for this port. This does everything related to network I/O for
655 * this port's network BIOs, and services child channels.
657 void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *res, in ossl_quic_port_subtick() argument
662 res->net_read_desired = ossl_quic_port_is_running(port); in ossl_quic_port_subtick()
663 res->net_write_desired = 0; in ossl_quic_port_subtick()
664 res->notify_other_threads = 0; in ossl_quic_port_subtick()
665 res->tick_deadline = ossl_time_infinite(); in ossl_quic_port_subtick()
667 if (!port->engine->inhibit_tick) { in ossl_quic_port_subtick()
669 if (ossl_quic_port_is_running(port)) in ossl_quic_port_subtick()
670 port_rx_pre(port); in ossl_quic_port_subtick()
673 OSSL_LIST_FOREACH(ch, ch, &port->channel_list) { in ossl_quic_port_subtick()
683 static void port_rx_pre(QUIC_PORT *port) in port_rx_pre() argument
696 * recv-type function before calling a Winsock send-type function, that call in port_rx_pre()
703 if (!port->allow_incoming && !port->have_sent_any_pkt) in port_rx_pre()
710 ret = ossl_quic_demux_pump(port->demux); in port_rx_pre()
714 * should tear down the port. All connections skip straight to the in port_rx_pre()
718 ossl_quic_port_raise_net_error(port, NULL); in port_rx_pre()
726 static void port_bind_channel(QUIC_PORT *port, const BIO_ADDR *peer, in port_bind_channel() argument
737 if (port->tserver_ch != NULL) { in port_bind_channel()
738 ch = port->tserver_ch; in port_bind_channel()
739 port->tserver_ch = NULL; in port_bind_channel()
741 ossl_qrx_set_msg_callback(ch->qrx, ch->msg_callback, in port_bind_channel()
742 ch->msg_callback_ssl); in port_bind_channel()
743 ossl_qrx_set_msg_callback_arg(ch->qrx, ch->msg_callback_arg); in port_bind_channel()
745 ch = port_make_channel(port, NULL, qrx, /* is_server= */ 1, in port_bind_channel()
761 if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx, in port_bind_channel()
762 ch->port->engine->propq, in port_bind_channel()
764 ch->qrx, NULL)) in port_bind_channel()
767 if (odcid->id_len != 0) { in port_bind_channel()
773 ossl_quic_tx_packetiser_set_validated(ch->txp); in port_bind_channel()
789 ossl_list_incoming_ch_insert_tail(&port->incoming_channel_list, ch); in port_bind_channel()
793 static int port_try_handle_stateless_reset(QUIC_PORT *port, const QUIC_URXE *e) in port_try_handle_stateless_reset() argument
819 * and -1 if an error was encountered. in port_try_handle_stateless_reset()
821 if (e->data_len < QUIC_STATELESS_RESET_TOKEN_LEN + 5 in port_try_handle_stateless_reset()
826 if (!ossl_quic_srtm_lookup(port->srtm, in port_try_handle_stateless_reset()
827 (QUIC_STATELESS_RESET_TOKEN *)(data + e->data_len in port_try_handle_stateless_reset()
828 - sizeof(QUIC_STATELESS_RESET_TOKEN)), in port_try_handle_stateless_reset()
841 OPENSSL_free(token->remote_addr); in cleanup_validation_token()
850 * @param rscid Retry source connection ID of the connection attempt.
859 token->is_retry = is_retry; in generate_token()
860 token->timestamp = ossl_time_now(); in generate_token()
861 token->remote_addr = NULL; in generate_token()
862 token->odcid = odcid; in generate_token()
863 token->rscid = rscid; in generate_token()
865 if (!BIO_ADDR_rawaddress(peer, NULL, &token->remote_addr_len) in generate_token()
866 || token->remote_addr_len == 0 in generate_token()
867 || (token->remote_addr = OPENSSL_malloc(token->remote_addr_len)) == NULL in generate_token()
868 || !BIO_ADDR_rawaddress(peer, token->remote_addr, in generate_token()
869 &token->remote_addr_len)) { in generate_token()
894 || (token->is_retry != 0 && token->is_retry != 1)) { in marshal_validation_token()
900 || !WPACKET_memset(&wpkt, token->is_retry, 1) in marshal_validation_token()
901 || !WPACKET_memcpy(&wpkt, &token->timestamp, in marshal_validation_token()
902 sizeof(token->timestamp)) in marshal_validation_token()
903 || (token->is_retry in marshal_validation_token()
904 && (!WPACKET_sub_memcpy_u8(&wpkt, &token->odcid.id, in marshal_validation_token()
905 token->odcid.id_len) in marshal_validation_token()
906 || !WPACKET_sub_memcpy_u8(&wpkt, &token->rscid.id, in marshal_validation_token()
907 token->rscid.id_len))) in marshal_validation_token()
908 || !WPACKET_sub_memcpy_u8(&wpkt, token->remote_addr, token->remote_addr_len) in marshal_validation_token()
917 memcpy(buffer, buf_mem->data, *buffer_len); in marshal_validation_token()
923 * @brief Encrypts a validation token using AES-256-GCM
925 * @param port The QUIC port containing the encryption key
939 static int encrypt_validation_token(const QUIC_PORT *port, in encrypt_validation_token() argument
949 if ((tag_len = EVP_CIPHER_CTX_get_tag_length(port->token_ctx)) == 0 in encrypt_validation_token()
950 || (iv_len = EVP_CIPHER_CTX_get_iv_length(port->token_ctx)) <= 0) in encrypt_validation_token()
962 if (!RAND_bytes_ex(port->engine->libctx, ciphertext, iv_len, 0) in encrypt_validation_token()
963 || !EVP_EncryptInit_ex(port->token_ctx, NULL, NULL, NULL, iv) in encrypt_validation_token()
964 || !EVP_EncryptUpdate(port->token_ctx, data, &len, plaintext, pt_len) in encrypt_validation_token()
965 || !EVP_EncryptFinal_ex(port->token_ctx, data + pt_len, &len) in encrypt_validation_token()
966 || !EVP_CIPHER_CTX_ctrl(port->token_ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tag)) in encrypt_validation_token()
975 * @brief Decrypts a validation token using AES-256-GCM
977 * @param port The QUIC port containing the decryption key
989 static int decrypt_validation_token(const QUIC_PORT *port, in decrypt_validation_token() argument
999 if ((tag_len = EVP_CIPHER_CTX_get_tag_length(port->token_ctx)) == 0 in decrypt_validation_token()
1000 || (iv_len = EVP_CIPHER_CTX_get_iv_length(port->token_ctx)) <= 0) in decrypt_validation_token()
1007 *pt_len = ct_len - iv_len - tag_len; in decrypt_validation_token()
1014 tag = ciphertext + ct_len - tag_len; in decrypt_validation_token()
1016 if (!EVP_DecryptInit_ex(port->token_ctx, NULL, NULL, NULL, iv) in decrypt_validation_token()
1017 || !EVP_DecryptUpdate(port->token_ctx, plaintext, &len, data, in decrypt_validation_token()
1018 ct_len - iv_len - tag_len) in decrypt_validation_token()
1019 || !EVP_CIPHER_CTX_ctrl(port->token_ctx, EVP_CTRL_GCM_SET_TAG, tag_len, in decrypt_validation_token()
1021 || !EVP_DecryptFinal_ex(port->token_ctx, plaintext + len, &len)) in decrypt_validation_token()
1047 token->remote_addr = NULL; in parse_validation_token()
1050 || !PACKET_copy_bytes(&pkt, &token->is_retry, sizeof(token->is_retry)) in parse_validation_token()
1051 || !(token->is_retry == 0 || token->is_retry == 1) in parse_validation_token()
1052 || !PACKET_copy_bytes(&pkt, (unsigned char *)&token->timestamp, in parse_validation_token()
1053 sizeof(token->timestamp)) in parse_validation_token()
1054 || (token->is_retry in parse_validation_token()
1056 || (token->odcid.id_len = (unsigned char)PACKET_remaining(&subpkt)) in parse_validation_token()
1059 (unsigned char *)&token->odcid.id, in parse_validation_token()
1060 token->odcid.id_len) in parse_validation_token()
1062 || (token->rscid.id_len = (unsigned char)PACKET_remaining(&subpkt)) in parse_validation_token()
1064 || !PACKET_copy_bytes(&subpkt, (unsigned char *)&token->rscid.id, in parse_validation_token()
1065 token->rscid.id_len))) in parse_validation_token()
1067 || (token->remote_addr_len = PACKET_remaining(&subpkt)) == 0 in parse_validation_token()
1068 || (token->remote_addr = OPENSSL_malloc(token->remote_addr_len)) == NULL in parse_validation_token()
1069 || !PACKET_copy_bytes(&subpkt, token->remote_addr, token->remote_addr_len) in parse_validation_token()
1083 * includes a generated validation token and a new connection ID, following
1086 * @param port Pointer to the QUIC port from which to send the packet.
1092 * - Generates a validation token for the client.
1093 * - Sets the destination and source connection IDs.
1094 * - Calculates the integrity tag and sets the token length.
1095 * - Encodes and sends the packet via the BIO network interface.
1100 static void port_send_retry(QUIC_PORT *port, in port_send_retry() argument
1123 * src ConnId comes from local conn ID manager in port_send_retry()
1126 hdr.dst_conn_id = client_hdr->src_conn_id; in port_send_retry()
1128 * this is the random connection ID, we expect client is in port_send_retry()
1129 * going to send the ID with next INITIAL packet which in port_send_retry()
1132 ok = ossl_quic_lcidm_get_unused_cid(port->lcidm, &hdr.src_conn_id); in port_send_retry()
1139 if (!generate_token(peer, client_hdr->dst_conn_id, in port_send_retry()
1142 || !encrypt_validation_token(port, buffer, token_buf_len, NULL, in port_send_retry()
1145 || !encrypt_validation_token(port, buffer, token_buf_len, ct_buf, in port_send_retry()
1150 hdr.dst_conn_id = client_hdr->src_conn_id; in port_send_retry()
1156 ok = ossl_quic_calculate_retry_integrity_tag(port->engine->libctx, in port_send_retry()
1157 port->engine->propq, &hdr, in port_send_retry()
1158 &client_hdr->dst_conn_id, in port_send_retry()
1160 - QUIC_RETRY_INTEGRITY_TAG_LEN); in port_send_retry()
1176 ok = ossl_quic_wire_encode_pkt_hdr(&wpkt, client_hdr->dst_conn_id.id_len, in port_send_retry()
1191 * on a non-blocking BIO in port_send_retry()
1193 if (!BIO_sendmmsg(port->net_wbio, msg, sizeof(BIO_MSG), 1, 0, &written)) in port_send_retry()
1195 "port retry send failed due to network BIO I/O error"); in port_send_retry()
1208 * @param port Pointer to the QUIC_PORT structure representing the port
1218 static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer, in port_send_version_negotiation() argument
1233 hdr.dst_conn_id = client_hdr->src_conn_id; in port_send_version_negotiation()
1234 hdr.src_conn_id = client_hdr->dst_conn_id; in port_send_version_negotiation()
1262 if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, client_hdr->dst_conn_id.id_len, in port_send_version_negotiation()
1285 if (!BIO_sendmmsg(port->net_wbio, msg, sizeof(BIO_MSG), 1, 0, &written)) in port_send_version_negotiation()
1287 "port version negotiation send failed"); in port_send_version_negotiation()
1306 * ID (ODCID)/original source connection ID (SCID) and stores it in the provided
1311 * @param port Pointer to the QUIC port from which to send the packet.
1313 * @param odcid Pointer to the connection ID structure to store the ODCID if the
1315 * @param scid Pointer to the connection ID structure to store the SCID if the
1322 * - Token length meets the required minimum.
1323 * - Buffer matches expected format.
1324 * - Peer address matches previous connection address.
1325 * - Token has not expired. Currently set to 10 seconds for tokens from RETRY
1329 static int port_validate_token(QUIC_PKT_HDR *hdr, QUIC_PORT *port, in port_validate_token() argument
1342 if (!decrypt_validation_token(port, hdr->token, hdr->token_len, NULL, in port_validate_token()
1345 || !decrypt_validation_token(port, hdr->token, hdr->token_len, in port_validate_token()
1373 * source connection ID for SCID. in port_validate_token()
1381 * TODO(QUIC FUTURE): Consider handling AEAD validation at the port in port_validate_token()
1385 if (token.rscid.id_len != hdr->dst_conn_id.id_len in port_validate_token()
1386 || memcmp(&token.rscid.id, &hdr->dst_conn_id.id, in port_validate_token()
1392 if (!ossl_quic_lcidm_get_unused_cid(port->lcidm, odcid)) in port_validate_token()
1394 *scid = hdr->src_conn_id; in port_validate_token()
1432 if (!ch->is_server) in generate_new_token()
1446 if (!RAND_bytes_ex(ch->port->engine->libctx, rscid.id, 8, 0)) { in generate_new_token()
1453 if (!generate_token(peer, ch->init_dcid, rscid, &token, 0) in generate_new_token()
1455 || !encrypt_validation_token(ch->port, buffer, token_buf_len, NULL, in generate_new_token()
1458 || !encrypt_validation_token(ch->port, buffer, token_buf_len, ct_buf, in generate_new_token()
1466 ch->pending_new_token = ct_buf; in generate_new_token()
1467 ch->pending_new_token_len = ct_len; in generate_new_token()
1479 QUIC_PORT *port = arg; in port_default_packet_handler() local
1492 if (!ossl_quic_port_is_running(port)) in port_default_packet_handler()
1495 if (port_try_handle_stateless_reset(port, e)) in port_default_packet_handler()
1499 && ossl_quic_lcidm_lookup(port->lcidm, dcid, NULL, in port_default_packet_handler()
1510 if (!port->allow_incoming) in port_default_packet_handler()
1517 if (e->data_len < QUIC_MIN_INITIAL_DGRAM_LEN) in port_default_packet_handler()
1520 if (!PACKET_buf_init(&pkt, ossl_quic_urxe_data(e), e->data_len)) in port_default_packet_handler()
1525 * operation to fail if we get a 1-RTT packet. This is fine since we only in port_default_packet_handler()
1552 if (e->data_len < 1200) in port_default_packet_handler()
1560 port_send_version_negotiation(port, &e->peer, &hdr); in port_default_packet_handler()
1577 qrx_args.libctx = port->engine->libctx; in port_default_packet_handler()
1578 qrx_args.demux = port->demux; in port_default_packet_handler()
1579 qrx_args.short_conn_id_len = dcid->id_len; in port_default_packet_handler()
1588 if (!ossl_quic_provide_initial_secret(port->engine->libctx, in port_default_packet_handler()
1589 port->engine->propq, in port_default_packet_handler()
1598 if (port->validate_addr == 0) { in port_default_packet_handler()
1601 * channel to create a new QRX for connection ID server chooses. The in port_default_packet_handler()
1604 * See RFC 9000 section 7.2 negotiating connection id to better in port_default_packet_handler()
1616 * TODO(QUIC FUTURE): there should be some logic similar to accounting half-open in port_default_packet_handler()
1620 if (port->validate_addr == 1 && hdr.token == NULL) { in port_default_packet_handler()
1621 port_send_retry(port, &e->peer, &hdr); in port_default_packet_handler()
1632 && port_validate_token(&hdr, port, &e->peer, in port_default_packet_handler()
1646 if (port->validate_addr == 1) { in port_default_packet_handler()
1651 port_send_retry(port, &e->peer, &hdr); in port_default_packet_handler()
1666 port_bind_channel(port, &e->peer, &scid, &hdr.dst_conn_id, in port_default_packet_handler()
1671 * to port. in port_default_packet_handler()
1680 generate_new_token(new_ch, &e->peer); in port_default_packet_handler()
1694 ossl_qrx_update_pn_space(qrx_src, new_ch->qrx); in port_default_packet_handler()
1702 * then the function puts the packet to qrx->rx_pending. We must not call in port_default_packet_handler()
1704 * the packet to qrx->urx_pending which keeps packet waiting for decryption. in port_default_packet_handler()
1713 ossl_quic_demux_release_urxe(port->demux, e); in port_default_packet_handler()
1716 void ossl_quic_port_raise_net_error(QUIC_PORT *port, in ossl_quic_port_raise_net_error() argument
1721 if (!ossl_quic_port_is_running(port)) in ossl_quic_port_raise_net_error()
1729 "port failed due to network BIO I/O error"); in ossl_quic_port_raise_net_error()
1730 OSSL_ERR_STATE_save(port->err_state); in ossl_quic_port_raise_net_error()
1732 port_transition_failed(port); in ossl_quic_port_raise_net_error()
1738 OSSL_LIST_FOREACH(ch, ch, &port->channel_list) in ossl_quic_port_raise_net_error()
1743 void ossl_quic_port_restore_err_state(const QUIC_PORT *port) in ossl_quic_port_restore_err_state() argument
1746 OSSL_ERR_STATE_restore(port->err_state); in ossl_quic_port_restore_err_state()