From 9e30ec43555b9556cebb1df76ae6824364a9ef02 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 24 Aug 2023 15:49:05 +0200 Subject: [PATCH] - dnsoverquic, fix for newer ngtcp2 versions. detect ngtcp2_ccerr_default, ngtcp2/ngtcp2_crypto_quictls.h, struct ngtcp2_pkt_hd.tokenlen, struct ngtcp2_settings.tokenlen and struct ngtcp2_version_cid. --- config.h.in | 20 +++++++ configure | 56 +++++++++++++++++--- configure.ac | 10 +++- services/listen_dnsport.c | 71 +++++++++++++++++++++++-- services/listen_dnsport.h | 4 ++ testcode/doqclient.c | 65 ++++++++++++++++++++--- util/netevent.c | 109 ++++++++++++++++++++++++++++++++------ 7 files changed, 298 insertions(+), 37 deletions(-) diff --git a/config.h.in b/config.h.in index 938dd94c9..6dd686960 100644 --- a/config.h.in +++ b/config.h.in @@ -420,9 +420,20 @@ /* Define this to use ngtcp2. */ #undef HAVE_NGTCP2 +/* Define to 1 if you have the `ngtcp2_ccerr_default' function. */ +#undef HAVE_NGTCP2_CCERR_DEFAULT + /* Define to 1 if you have the `ngtcp2_crypto_encrypt_cb' function. */ #undef HAVE_NGTCP2_CRYPTO_ENCRYPT_CB +/* Define to 1 if you have the header file. + */ +#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H + +/* Define to 1 if you have the header file. + */ +#undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H + /* Define to 1 if you have the header file. */ #undef HAVE_NGTCP2_NGTCP2_H @@ -631,6 +642,15 @@ /* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */ #undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST +/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_pkt_hd'. */ +#undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + +/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_settings'. */ +#undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN + +/* Define to 1 if the system has the type `struct ngtcp2_version_cid'. */ +#undef HAVE_STRUCT_NGTCP2_VERSION_CID + /* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */ #undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN diff --git a/configure b/configure index 053bedd69..61f1e123a 100755 --- a/configure +++ b/configure @@ -20097,13 +20097,14 @@ $as_echo "#define HAVE_NGTCP2 1" >>confdefs.h if test x_$found_libngtcp2 != x_yes; then as_fn_error $? "Could not find libngtcp2, ngtcp2.h" "$LINENO" 5 fi - for ac_header in ngtcp2/ngtcp2.h + for ac_header in ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h do : - ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2.h" "ac_cv_header_ngtcp2_ngtcp2_h" "$ac_includes_default + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -if test "x$ac_cv_header_ngtcp2_ngtcp2_h" = xyes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_NGTCP2_NGTCP2_H 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -20218,12 +20219,13 @@ if test "x$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" = xyes; the LIBS="$LIBS -lngtcp2_crypto_quictls" fi - for ac_func in ngtcp2_crypto_encrypt_cb + for ac_func in ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default do : - ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_encrypt_cb" "ac_cv_func_ngtcp2_crypto_encrypt_cb" -if test "x$ac_cv_func_ngtcp2_crypto_encrypt_cb" = xyes; then : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_NGTCP2_CRYPTO_ENCRYPT_CB 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi @@ -20242,6 +20244,44 @@ else fi done + ac_fn_c_check_type "$LINENO" "struct ngtcp2_version_cid" "ac_cv_type_struct_ngtcp2_version_cid" "$ac_includes_default + #include + +" +if test "x$ac_cv_type_struct_ngtcp2_version_cid" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_NGTCP2_VERSION_CID 1 +_ACEOF + + +fi + + ac_fn_c_check_member "$LINENO" "struct ngtcp2_pkt_hd" "tokenlen" "ac_cv_member_struct_ngtcp2_pkt_hd_tokenlen" "$ac_includes_default + #include + +" +if test "x$ac_cv_member_struct_ngtcp2_pkt_hd_tokenlen" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN 1 +_ACEOF + + +fi +ac_fn_c_check_member "$LINENO" "struct ngtcp2_settings" "tokenlen" "ac_cv_member_struct_ngtcp2_settings_tokenlen" "$ac_includes_default + #include + +" +if test "x$ac_cv_member_struct_ngtcp2_settings_tokenlen" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN 1 +_ACEOF + + +fi + fi # set static linking for uninstalled libraries if requested diff --git a/configure.ac b/configure.ac index 9f09ad3b0..764090730 100644 --- a/configure.ac +++ b/configure.ac @@ -1525,7 +1525,7 @@ if test x_$withval = x_yes -o x_$withval != x_no; then if test x_$found_libngtcp2 != x_yes; then AC_MSG_ERROR([Could not find libngtcp2, ngtcp2.h]) fi - AC_CHECK_HEADERS([ngtcp2/ngtcp2.h],,, [AC_INCLUDES_DEFAULT]) + AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS([ngtcp2_conn_server_new], [], [], [AC_INCLUDES_DEFAULT #include ]) @@ -1534,8 +1534,14 @@ if test x_$withval = x_yes -o x_$withval != x_no; then ]) AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ]) AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ]) - AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb]) + AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default]) AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])]) + AC_CHECK_TYPES([struct ngtcp2_version_cid],,,[AC_INCLUDES_DEFAULT + #include + ]) + AC_CHECK_MEMBERS([struct ngtcp2_pkt_hd.tokenlen, struct ngtcp2_settings.tokenlen],,,[AC_INCLUDES_DEFAULT + #include + ]) fi # set static linking for uninstalled libraries if requested diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index ba3669945..fbc73b1ab 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -89,8 +89,12 @@ #ifdef HAVE_NGTCP2 #include #include +#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H +#include +#else #include #endif +#endif #ifdef HAVE_OPENSSL_SSL_H #include @@ -3484,7 +3488,11 @@ doq_conn_create(struct comm_point* c, struct doq_pkt_addr* paddr, } conn->key.dcidlen = dcidlen; conn->version = version; +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_default(&conn->ccerr); +#else ngtcp2_connection_close_error_default(&conn->last_error); +#endif rbtree_init(&conn->stream_tree, &doq_stream_cmp); conn->timer.conn = conn; lock_basic_init(&conn->lock); @@ -4660,8 +4668,13 @@ doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen, settings.initial_ts = doq_get_timestamp_nanosec(); settings.max_stream_window = 6*1024*1024; settings.max_window = 6*1024*1024; +#ifdef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN + settings.token = (void*)token; + settings.tokenlen = tokenlen; +#else settings.token.base = (void*)token; settings.token.len = tokenlen; +#endif ngtcp2_transport_params_default(¶ms); params.max_idle_timeout = conn->doq_socket->idle_timeout; @@ -4947,8 +4960,13 @@ doq_conn_start_closing_period(struct comm_point* c, struct doq_conn* conn) * conn to be closed. It is now in the closing period. */ ret = ngtcp2_conn_write_connection_close(conn->conn, &ps.path, &pi, sldns_buffer_begin(c->doq_socket->pkt_buf), - sldns_buffer_remaining(c->doq_socket->pkt_buf), &conn->last_error, - doq_get_timestamp_nanosec()); + sldns_buffer_remaining(c->doq_socket->pkt_buf), +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + &conn->ccerr +#else + &conn->last_error +#endif + , doq_get_timestamp_nanosec()); if(ret < 0) { log_err("doq ngtcp2_conn_write_connection_close failed: %s", ngtcp2_strerror(ret)); @@ -4997,9 +5015,14 @@ doq_conn_send_close(struct comm_point* c, struct doq_conn* conn) static int doq_conn_close_error(struct comm_point* c, struct doq_conn* conn) { +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + if(conn->ccerr.type == NGTCP2_CCERR_TYPE_IDLE_CLOSE) + return 0; +#else if(conn->last_error.type == NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_IDLE_CLOSE) return 0; +#endif if(!doq_conn_start_closing_period(c, conn)) return 0; if(ngtcp2_conn_is_in_draining_period(conn->conn)) { @@ -5055,18 +5078,40 @@ doq_conn_recv(struct comm_point* c, struct doq_pkt_addr* paddr, *err_drop = 1; return 0; } else if(ret == NGTCP2_ERR_CRYPTO) { - if(!conn->last_error.error_code) { + if( +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + !conn->ccerr.error_code +#else + !conn->last_error.error_code +#endif + ) { /* in picotls the tls alert may need to be * copied, but this is with openssl. And there * is conn->tls_alert. */ +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_tls_alert(&conn->ccerr, + conn->tls_alert, NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_tls_alert( &conn->last_error, conn->tls_alert, NULL, 0); +#endif } } else { - if(!conn->last_error.error_code) { + if( +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + !conn->ccerr.error_code +#else + !conn->last_error.error_code +#endif + ) { +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_liberr(&conn->ccerr, ret, + NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_liberr( &conn->last_error, ret, NULL, 0); +#endif } } log_err("ngtcp2_conn_read_pkt failed: %s", @@ -5163,7 +5208,12 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn, continue; } else if(ret == NGTCP2_ERR_STREAM_DATA_BLOCKED) { verbose(VERB_ALGO, "doq: ngtcp2_conn_writev_stream returned NGTCP2_ERR_STREAM_DATA_BLOCKED"); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_application_error( + &conn->ccerr, -1, NULL, 0); +#else ngtcp2_connection_close_error_set_application_error(&conn->last_error, -1, NULL, 0); +#endif if(err_drop) *err_drop = 0; if(!doq_conn_close_error(c, conn)) { @@ -5173,7 +5223,12 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn, return 0; } else if(ret == NGTCP2_ERR_STREAM_SHUT_WR) { verbose(VERB_ALGO, "doq: ngtcp2_conn_writev_stream returned NGTCP2_ERR_STREAM_SHUT_WR"); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_application_error( + &conn->ccerr, -1, NULL, 0); +#else ngtcp2_connection_close_error_set_application_error(&conn->last_error, -1, NULL, 0); +#endif if(err_drop) *err_drop = 0; if(!doq_conn_close_error(c, conn)) { @@ -5185,8 +5240,12 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn, log_err("doq: ngtcp2_conn_writev_stream failed: %s", ngtcp2_strerror(ret)); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_liberr(&conn->ccerr, ret, NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_liberr( &conn->last_error, ret, NULL, 0); +#endif if(err_drop) *err_drop = 0; if(!doq_conn_close_error(c, conn)) { @@ -5353,8 +5412,12 @@ doq_conn_handle_timeout(struct doq_conn* conn) if(rv != 0) { verbose(VERB_ALGO, "ngtcp2_conn_handle_expiry failed: %s", ngtcp2_strerror(rv)); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_liberr(&conn->ccerr, rv, NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_liberr( &conn->last_error, rv, NULL, 0); +#endif if(!doq_conn_close_error(conn->doq_socket->cp, conn)) { /* failed, return for deletion */ return 0; diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h index 19b927d82..6f607c6ad 100644 --- a/services/listen_dnsport.h +++ b/services/listen_dnsport.h @@ -584,7 +584,11 @@ struct doq_conn { * elements can be removed as well. */ struct doq_conid* conid_list; /** the ngtcp2 last error for the connection */ +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + struct ngtcp2_ccerr ccerr; +#else struct ngtcp2_connection_close_error last_error; +#endif /** the recent tls alert error code */ uint8_t tls_alert; /** the ssl context, SSL* */ diff --git a/testcode/doqclient.c b/testcode/doqclient.c index d02b7dda3..a9a1c8a1f 100644 --- a/testcode/doqclient.c +++ b/testcode/doqclient.c @@ -48,7 +48,11 @@ #ifdef HAVE_NGTCP2 #include #include +#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H +#include +#else #include +#endif #include #include #ifdef HAVE_TIME_H @@ -106,7 +110,11 @@ struct doq_client_data { /** the quic version to use */ uint32_t quic_version; /** the last error */ +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + struct ngtcp2_ccerr ccerr; +#else struct ngtcp2_connection_close_error last_error; +#endif /** the recent tls alert error code */ uint8_t tls_alert; /** the buffer for packet operations */ @@ -1362,8 +1370,11 @@ doq_client_send_pkt(struct doq_client_data* data, uint32_t ecn, uint8_t* buf, return 0; } log_err("doq sendmsg: %s", strerror(errno)); - ngtcp2_connection_close_error_set_transport_error_liberr( - &data->last_error, NGTCP2_ERR_INTERNAL, NULL, 0); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_application_error(&data->ccerr, -1, NULL, 0); +#else + ngtcp2_connection_close_error_set_application_error(&data->last_error, -1, NULL, 0); +#endif return 0; } return 1; @@ -1397,8 +1408,14 @@ write_conn_close(struct doq_client_data* data) /* Drop blocked packet if there is one, the connection is being * closed. And thus no further data traffic. */ data->have_blocked_pkt = 0; - if(data->last_error.type == - NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_IDLE_CLOSE) { + if( +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + data->ccerr.type == NGTCP2_CCERR_TYPE_IDLE_CLOSE +#else + data->last_error.type == + NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_IDLE_CLOSE +#endif + ) { /* do not call ngtcp2_conn_write_connection_close on the * connection because the ngtcp2_conn_handle_expiry call * has returned NGTCP2_ERR_IDLE_CLOSE. But continue to close @@ -1410,8 +1427,13 @@ write_conn_close(struct doq_client_data* data) sldns_buffer_clear(data->pkt_buf); ret = ngtcp2_conn_write_connection_close( data->conn, &ps.path, &pi, sldns_buffer_begin(data->pkt_buf), - sldns_buffer_remaining(data->pkt_buf), &data->last_error, - get_timestamp_nanosec()); + sldns_buffer_remaining(data->pkt_buf), +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + &data->ccerr +#else + &data->last_error +#endif + , get_timestamp_nanosec()); if(ret < 0) { log_err("ngtcp2_conn_write_connection_close failed: %s", ngtcp2_strerror(ret)); @@ -1447,8 +1469,12 @@ void doq_client_timer_cb(int ATTR_UNUSED(fd), if(rv != 0) { log_err("ngtcp2_conn_handle_expiry failed: %s", ngtcp2_strerror(rv)); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_liberr(&data->ccerr, rv, NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_liberr( &data->last_error, rv, NULL, 0); +#endif disconnect(data); return; } @@ -1542,19 +1568,36 @@ on_read(struct doq_client_data* data) if(rv != 0) { log_err("ngtcp2_conn_read_pkt failed: %s", ngtcp2_strerror(rv)); - if(data->last_error.error_code == 0) { + if( +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + data->ccerr.error_code == 0 +#else + data->last_error.error_code == 0 +#endif + ) { if(rv == NGTCP2_ERR_CRYPTO) { /* in picotls the tls alert may need * to be copied, but this is with * openssl. And we have the value * data.tls_alert. */ +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_tls_alert( + &data->ccerr, data->tls_alert, + NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_tls_alert( &data->last_error, data->tls_alert, NULL, 0); +#endif } else { +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_liberr(&data->ccerr, + rv, NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_liberr( &data->last_error, rv, NULL, 0); +#endif } } disconnect(data); @@ -1730,8 +1773,12 @@ write_streams(struct doq_client_data* data) } log_err("ngtcp2_conn_writev_stream failed: %s", ngtcp2_strerror(ret)); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_set_liberr(&data->ccerr, ret, NULL, 0); +#else ngtcp2_connection_close_error_set_transport_error_liberr( &data->last_error, ret, NULL, 0); +#endif disconnect(data); return 0; } @@ -2010,7 +2057,11 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base, data->fd = open_svr_udp(data); get_local_addr(data); data->conn = conn_client_setup(data); +#ifdef HAVE_NGTCP2_CCERR_DEFAULT + ngtcp2_ccerr_default(&data->ccerr); +#else ngtcp2_connection_close_error_default(&data->last_error); +#endif data->transport_file = transport_file; data->session_file = session_file; if(data->transport_file && data->session_file) diff --git a/util/netevent.c b/util/netevent.c index 2ecbf49c7..a06fa4e12 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -1549,19 +1549,35 @@ static int doq_decode_pkt_header_negotiate(struct comm_point* c, struct doq_pkt_addr* paddr, struct doq_conn** conn) { +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + struct ngtcp2_version_cid vc; +#else uint32_t version; const uint8_t *dcid, *scid; size_t dcidlen, scidlen; +#endif int rv; +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + rv = ngtcp2_pkt_decode_version_cid(&vc, + sldns_buffer_begin(c->doq_socket->pkt_buf), + sldns_buffer_limit(c->doq_socket->pkt_buf), + c->doq_socket->sv_scidlen); +#else rv = ngtcp2_pkt_decode_version_cid(&version, &dcid, &dcidlen, &scid, &scidlen, sldns_buffer_begin(c->doq_socket->pkt_buf), sldns_buffer_limit(c->doq_socket->pkt_buf), c->doq_socket->sv_scidlen); +#endif if(rv != 0) { if(rv == NGTCP2_ERR_VERSION_NEGOTIATION) { /* send the version negotiation */ - doq_send_version_negotiation(c, paddr, scid, scidlen, - dcid, dcidlen); + doq_send_version_negotiation(c, paddr, +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + vc.scid, vc.scidlen, vc.dcid, vc.dcidlen +#else + scid, scidlen, dcid, dcidlen +#endif + ); return 0; } verbose(VERB_ALGO, "doq: could not decode version " @@ -1572,12 +1588,34 @@ doq_decode_pkt_header_negotiate(struct comm_point* c, if(verbosity >= VERB_ALGO) { verbose(VERB_ALGO, "ngtcp2_pkt_decode_version_cid packet has " - "QUIC protocol version %u", (unsigned)version); - log_hex("dcid", (void*)dcid, dcidlen); - log_hex("scid", (void*)scid, scidlen); + "QUIC protocol version %u", (unsigned) +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + vc. +#endif + version + ); + log_hex("dcid", +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + (void*)vc.dcid, vc.dcidlen +#else + (void*)dcid, dcidlen +#endif + ); + log_hex("scid", +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + (void*)vc.scid, vc.scidlen +#else + (void*)scid, scidlen +#endif + ); } *conn = doq_conn_find_by_addr_or_cid(c->doq_socket->table, paddr, - dcid, dcidlen); +#ifdef HAVE_STRUCT_NGTCP2_VERSION_CID + vc.dcid, vc.dcidlen +#else + dcid, dcidlen +#endif + ); if(*conn) (*conn)->doq_socket = c->doq_socket; return 1; @@ -1676,8 +1714,13 @@ doq_verify_retry_token(struct comm_point* c, struct doq_pkt_addr* paddr, ts = doq_get_timestamp_nanosec(); verbose(VERB_ALGO, "doq: verifying retry token from %s %s", host, port); - if(ngtcp2_crypto_verify_retry_token(ocid, hd->token.base, - hd->token.len, c->doq_socket->static_secret, + if(ngtcp2_crypto_verify_retry_token(ocid, +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + hd->token, hd->tokenlen, +#else + hd->token.base, hd->token.len, +#endif + c->doq_socket->static_secret, c->doq_socket->static_secret_len, hd->version, (void*)&paddr->addr, paddr->addrlen, &hd->dcid, 10*NGTCP2_SECONDS, ts) != 0) { @@ -1701,7 +1744,12 @@ doq_verify_token(struct comm_point* c, struct doq_pkt_addr* paddr, return 0; ts = doq_get_timestamp_nanosec(); verbose(VERB_ALGO, "doq: verifying token from %s %s", host, port); - if(ngtcp2_crypto_verify_regular_token(hd->token.base, hd->token.len, + if(ngtcp2_crypto_verify_regular_token( +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + hd->token, hd->tokenlen, +#else + hd->token.base, hd->token.len, +#endif c->doq_socket->static_secret, c->doq_socket->static_secret_len, (void*)&paddr->addr, paddr->addrlen, 3600*NGTCP2_SECONDS, ts) != 0) { @@ -1804,7 +1852,12 @@ doq_setup_new_conn(struct comm_point* c, struct doq_pkt_addr* paddr, * meaning is reversed. */ if(!doq_conn_setup(conn, hd->scid.data, hd->scid.datalen, (ocid?ocid->data:NULL), (ocid?ocid->datalen:0), - hd->token.base, hd->token.len)) { +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + hd->token, hd->tokenlen +#else + hd->token.base, hd->token.len +#endif + )) { log_err("doq: could not set up connection"); doq_delete_connection(c, conn); return NULL; @@ -1818,41 +1871,59 @@ doq_address_validation(struct comm_point* c, struct doq_pkt_addr* paddr, struct ngtcp2_pkt_hd* hd, struct ngtcp2_cid* ocid, struct ngtcp2_cid** pocid) { +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + const uint8_t* token = hd->token; + size_t tokenlen = hd->tokenlen; +#else + const uint8_t* token = hd->token.base; + size_t tokenlen = hd->token.len; +#endif verbose(VERB_ALGO, "doq stateless address validation"); - if(hd->token.len == 0) { + + if(tokenlen == 0 || token == NULL) { doq_send_retry(c, paddr, hd); return 0; } - if(hd->token.base[0] != NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY && + if(token[0] != NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY && hd->dcid.datalen < NGTCP2_MIN_INITIAL_DCIDLEN) { doq_send_stateless_connection_close(c, paddr, hd, NGTCP2_INVALID_TOKEN); return 0; } - if(hd->token.base[0] == NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY) { + if(token[0] == NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY) { if(!doq_verify_retry_token(c, paddr, ocid, hd)) { doq_send_stateless_connection_close(c, paddr, hd, NGTCP2_INVALID_TOKEN); return 0; } *pocid = ocid; - } else if(hd->token.base[0] == NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR) { + } else if(token[0] == NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR) { if(!doq_verify_token(c, paddr, hd)) { doq_send_retry(c, paddr, hd); return 0; } +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + hd->token = NULL; + hd->tokenlen = 0; +#else hd->token.base = NULL; hd->token.len = 0; +#endif } else { verbose(VERB_ALGO, "doq address validation: unrecognised " "token in hd.token.base with magic byte 0x%2.2x", - (int)hd->token.base[0]); + (int)token[0]); if(c->doq_socket->validate_addr) { doq_send_retry(c, paddr, hd); return 0; } +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + hd->token = NULL; + hd->tokenlen = 0; +#else hd->token.base = NULL; hd->token.len = 0; +#endif } return 1; } @@ -1878,7 +1949,13 @@ doq_accept(struct comm_point* c, struct doq_pkt_addr* paddr, ngtcp2_strerror(rv)); return 0; } - if(c->doq_socket->validate_addr || hd.token.len) { + if(c->doq_socket->validate_addr || +#ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN + hd.tokenlen +#else + hd.token.len +#endif + ) { if(!doq_address_validation(c, paddr, &hd, &ocid, &pocid)) return 0; } -- 2.47.2