diff --git a/picohttp/demoserver.c b/picohttp/demoserver.c index 1bdc1102f..7b97d47c3 100644 --- a/picohttp/demoserver.c +++ b/picohttp/demoserver.c @@ -27,9 +27,7 @@ #include "ws2ipdef.h" #pragma warning(disable:4100) #endif -#include #include "picoquic_internal.h" -#include "tls_api.h" #include "h3zero.h" #include "democlient.h" #include "demoserver.h" @@ -600,7 +598,7 @@ int picoquic_h09_server_callback(picoquic_cnx_t* cnx, } /* Callback from the TLS stack upon receiving a list of proposed ALPN in the Client Hello */ -size_t picoquic_demo_server_callback_select_alpn(picoquic_quic_t* quic, ptls_iovec_t* list, size_t count) +size_t picoquic_demo_server_callback_select_alpn(picoquic_quic_t* quic, picoquic_iovec_t* list, size_t count) { size_t ret = count; picoquic_alpn_enum alpn_code = picoquic_alpn_undef; diff --git a/picohttp/demoserver.h b/picohttp/demoserver.h index 40d1814c3..025ebeb5a 100644 --- a/picohttp/demoserver.h +++ b/picohttp/demoserver.h @@ -72,7 +72,7 @@ int picoquic_h09_server_callback(picoquic_cnx_t* cnx, * according to the ALPN selected by the client */ -size_t picoquic_demo_server_callback_select_alpn(picoquic_quic_t* quic, ptls_iovec_t* list, size_t count); +size_t picoquic_demo_server_callback_select_alpn(picoquic_quic_t* quic, picoquic_iovec_t* list, size_t count); int demo_server_is_path_sane(const uint8_t* path, size_t path_length); diff --git a/picoquic/picoquic.h b/picoquic/picoquic.h index 086cdaac1..f8a29e3b3 100644 --- a/picoquic/picoquic.h +++ b/picoquic/picoquic.h @@ -452,6 +452,9 @@ typedef int (*picoquic_stream_data_cb_fn)(picoquic_cnx_t* cnx, */ typedef size_t (*picoquic_alpn_select_fn)(picoquic_quic_t* quic, ptls_iovec_t* list, size_t count); +/* V2 callback using picoquic_iovec_t instead of ptls_iovec_t */ +typedef size_t (*picoquic_alpn_select_fn_v2)(picoquic_quic_t* quic, picoquic_iovec_t* list, size_t count); + /* Function used during callback to provision an ALPN context. The stack * issues a callback of type */ @@ -849,6 +852,9 @@ void picoquic_set_mtu_max(picoquic_quic_t* quic, uint32_t mtu_max); /* Set the ALPN function used to verify incoming ALPN */ void picoquic_set_alpn_select_fn(picoquic_quic_t* quic, picoquic_alpn_select_fn alpn_select_fn); +/* V2 API using picoquic_iovec_t */ +void picoquic_set_alpn_select_fn_v2(picoquic_quic_t* quic, picoquic_alpn_select_fn_v2 alpn_select_fn); + /* Set the default callback function for new connections. * This must be defined for every server implementation. */ diff --git a/picoquic/picoquic_internal.h b/picoquic/picoquic_internal.h index a4ec7cdd8..ed082a8cc 100644 --- a/picoquic/picoquic_internal.h +++ b/picoquic/picoquic_internal.h @@ -575,6 +575,7 @@ typedef struct st_picoquic_quic_t { struct st_picomask_fns_t* picomask_fns; char const* default_alpn; picoquic_alpn_select_fn alpn_select_fn; + picoquic_alpn_select_fn_v2 alpn_select_fn_v2; uint8_t reset_seed[PICOQUIC_RESET_SECRET_SIZE]; uint8_t retry_seed[PICOQUIC_RETRY_SECRET_SIZE]; uint64_t* p_simulated_time; diff --git a/picoquic/quicctx.c b/picoquic/quicctx.c index 42e7280e9..2b54091b1 100644 --- a/picoquic/quicctx.c +++ b/picoquic/quicctx.c @@ -4635,6 +4635,18 @@ void picoquic_set_alpn_select_fn(picoquic_quic_t* quic, picoquic_alpn_select_fn quic->alpn_select_fn = alpn_select_fn; } +void picoquic_set_alpn_select_fn_v2(picoquic_quic_t* quic, picoquic_alpn_select_fn_v2 alpn_select_fn) +{ + if (quic->default_alpn != NULL) { + free((void *)quic->default_alpn); + quic->default_alpn = NULL; + } + quic->alpn_select_fn_v2 = alpn_select_fn; + if (alpn_select_fn != NULL) { + quic->alpn_select_fn = NULL; + } +} + void picoquic_set_default_callback(picoquic_quic_t* quic, picoquic_stream_data_cb_fn callback_fn, void* callback_ctx) { diff --git a/picoquic/tls_api.c b/picoquic/tls_api.c index 08ae3aa8e..9c163d1d0 100644 --- a/picoquic/tls_api.c +++ b/picoquic/tls_api.c @@ -1025,8 +1025,14 @@ int picoquic_client_hello_call_back(ptls_on_client_hello_t* on_hello_cb_ctx, } } } - else if (quic->alpn_select_fn != NULL) { - size_t selected = quic->alpn_select_fn(quic, params->negotiated_protocols.list, params->negotiated_protocols.count); + else { + size_t selected = params->negotiated_protocols.count; + if (quic->alpn_select_fn != NULL) { + selected = quic->alpn_select_fn(quic, params->negotiated_protocols.list, params->negotiated_protocols.count); + } + else if (quic->alpn_select_fn_v2 != NULL) { + selected = quic->alpn_select_fn_v2(quic, (picoquic_iovec_t*)params->negotiated_protocols.list, params->negotiated_protocols.count); + } if (selected < params->negotiated_protocols.count) { alpn_found = params->negotiated_protocols.list[selected].base; diff --git a/picoquicfirst/picoquicdemo.c b/picoquicfirst/picoquicdemo.c index e837b5d31..eeac9e29e 100644 --- a/picoquicfirst/picoquicdemo.c +++ b/picoquicfirst/picoquicdemo.c @@ -316,7 +316,7 @@ int quic_server(const char* server_name, picoquic_quic_config_t * config, int ju else { picoquic_set_key_log_file_from_env(qserver); - picoquic_set_alpn_select_fn(qserver, picoquic_demo_server_callback_select_alpn); + picoquic_set_alpn_select_fn_v2(qserver, picoquic_demo_server_callback_select_alpn); picoquic_use_unique_log_names(qserver, 1); diff --git a/picoquictest/h3zerotest.c b/picoquictest/h3zerotest.c index 9a1fb7e46..860c1f645 100644 --- a/picoquictest/h3zerotest.c +++ b/picoquictest/h3zerotest.c @@ -1843,7 +1843,7 @@ static int demo_server_test(char const * alpn, picoquic_stream_data_cb_fn server * We want to replace that by the demo client callback */ if (ret == 0) { - picoquic_set_alpn_select_fn(test_ctx->qserver, picoquic_demo_server_callback_select_alpn); + picoquic_set_alpn_select_fn_v2(test_ctx->qserver, picoquic_demo_server_callback_select_alpn); picoquic_set_default_callback(test_ctx->qserver, NULL, server_param); picoquic_set_callback(test_ctx->cnx_client, picoquic_demo_client_callback, &callback_ctx); if (ret == 0) { @@ -3153,7 +3153,7 @@ int http_stress_test_one(int do_corrupt, int do_drop, int initial_random) ret = -1; } else { - picoquic_set_alpn_select_fn(qserver, picoquic_demo_server_callback_select_alpn); + picoquic_set_alpn_select_fn_v2(qserver, picoquic_demo_server_callback_select_alpn); if (initial_random) { picoquic_set_random_initial(qserver, 1); } @@ -3679,7 +3679,7 @@ static int h3_grease_test_one(int server_test) * We want to replace that by the demo client callback */ if (ret == 0) { - picoquic_set_alpn_select_fn(test_ctx->qserver, picoquic_demo_server_callback_select_alpn); + picoquic_set_alpn_select_fn_v2(test_ctx->qserver, picoquic_demo_server_callback_select_alpn); picoquic_set_default_callback(test_ctx->qserver, h3zero_callback, server_param); picoquic_set_callback(test_ctx->cnx_client, picoquic_demo_client_callback, &callback_ctx); if (ret == 0) { diff --git a/picoquictest/webtransport_test.c b/picoquictest/webtransport_test.c index 4770b2baa..64bdddac6 100644 --- a/picoquictest/webtransport_test.c +++ b/picoquictest/webtransport_test.c @@ -181,7 +181,7 @@ static int picowt_baton_test_one( server_param.path_table = path_item_list; server_param.path_table_nb = 1; - picoquic_set_alpn_select_fn(test_ctx->qserver, picoquic_demo_server_callback_select_alpn); + picoquic_set_alpn_select_fn_v2(test_ctx->qserver, picoquic_demo_server_callback_select_alpn); picoquic_set_default_callback(test_ctx->qserver, h3zero_callback, &server_param); } } diff --git a/pqbench_app/pqbench.c b/pqbench_app/pqbench.c index bb0179580..4c65d11cf 100644 --- a/pqbench_app/pqbench.c +++ b/pqbench_app/pqbench.c @@ -212,11 +212,10 @@ static int server_loop_cb(picoquic_quic_t* quic, picoquic_packet_loop_cb_enum cb */ /* Callback from the TLS stack upon receiving a list of proposed ALPN in the Client Hello */ -size_t pqb_server_callback_select_alpn(picoquic_quic_t* quic, ptls_iovec_t* ptls_list, size_t count) +size_t pqb_server_callback_select_alpn(picoquic_quic_t* quic, picoquic_iovec_t* list, size_t count) { size_t ret = count; picoquic_cnx_t* cnx = picoquic_get_cnx_in_progress(quic); - picoquic_iovec_t* list = (picoquic_iovec_t*)ptls_list; for (size_t i = 0; i < count; i++) { if ((const char*)list[i].base != NULL && @@ -253,7 +252,7 @@ int pqb_server(picoquic_quic_config_t* config) else { picoquic_set_key_log_file_from_env(qserver); - picoquic_set_alpn_select_fn(qserver, pqb_server_callback_select_alpn); + picoquic_set_alpn_select_fn_v2(qserver, pqb_server_callback_select_alpn); if (config->qlog_dir != NULL) {