]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- dnsoverquic, fix for newer ngtcp2.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 24 Aug 2023 16:08:16 +0000 (18:08 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 24 Aug 2023 16:08:16 +0000 (18:08 +0200)
config.h.in
configure
configure.ac
services/listen_dnsport.c
services/listen_dnsport.h
testcode/doqclient.c
util/netevent.c
util/netevent.h

index 97887a2fa09844915c529995c503535b772c600f..5f6ef28678312959fdf4f9b30204d8d3404bad67 100644 (file)
 /* Define to 1 if you have the `ngtcp2_ccerr_default' function. */
 #undef HAVE_NGTCP2_CCERR_DEFAULT
 
+/* Define to 1 if you have the `ngtcp2_conn_encode_0rtt_transport_params'
+   function. */
+#undef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
+
+/* Define to 1 if you have the `ngtcp2_conn_get_max_local_streams_uni'
+   function. */
+#undef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
+
+/* Define to 1 if you have the `ngtcp2_conn_get_num_scid' function. */
+#undef HAVE_NGTCP2_CONN_GET_NUM_SCID
+
+/* Define to 1 if you have the `ngtcp2_conn_in_closing_period' function. */
+#undef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+
+/* Define to 1 if you have the `ngtcp2_conn_in_draining_period' function. */
+#undef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+
 /* Define if ngtcp2_conn_shutdown_stream has 4 arguments. */
 #undef HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4
 
+/* Define to 1 if you have the `ngtcp2_conn_tls_early_data_rejected' function.
+   */
+#undef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
+
 /* 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
+   `ngtcp2_crypto_quictls_configure_client_context' function. */
+#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
+
+/* Define to 1 if you have the
+   `ngtcp2_crypto_quictls_configure_server_context' function. */
+#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+
+/* Define to 1 if you have the
+   `ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
+#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+
+/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
+#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
+
 /* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_openssl.h> header file.
    */
 #undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H
 /* Define to 1 if `tokenlen' is a member of `struct ngtcp2_pkt_hd'. */
 #undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
 
+/* Define to 1 if `max_tx_udp_payload_size' is a member of `struct
+   ngtcp2_settings'. */
+#undef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
+
 /* Define to 1 if `tokenlen' is a member of `struct ngtcp2_settings'. */
 #undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN
 
+/* Define to 1 if `original_dcid_present' is a member of `struct
+   ngtcp2_transport_params'. */
+#undef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT
+
 /* Define to 1 if the system has the type `struct ngtcp2_version_cid'. */
 #undef HAVE_STRUCT_NGTCP2_VERSION_CID
 
index dcc533371d88c1efca23edf01dd61f900440e402..77a3a8123c5e806ce5322ad400af6fd9cea0ceef 100755 (executable)
--- a/configure
+++ b/configure
@@ -20219,7 +20219,7 @@ 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 ngtcp2_ccerr_default
+    for ac_func in ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -20255,6 +20255,18 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+fi
+ac_fn_c_check_type "$LINENO" "ngtcp2_encryption_level" "ac_cv_type_ngtcp2_encryption_level" "$ac_includes_default
+    #include <ngtcp2/ngtcp2.h>
+
+"
+if test "x$ac_cv_type_ngtcp2_encryption_level" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NGTCP2_ENCRYPTION_LEVEL 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
@@ -20280,6 +20292,30 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+fi
+ac_fn_c_check_member "$LINENO" "struct ngtcp2_settings" "max_tx_udp_payload_size" "ac_cv_member_struct_ngtcp2_settings_max_tx_udp_payload_size" "$ac_includes_default
+    #include <ngtcp2/ngtcp2.h>
+
+"
+if test "x$ac_cv_member_struct_ngtcp2_settings_max_tx_udp_payload_size" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "struct ngtcp2_transport_params" "original_dcid_present" "ac_cv_member_struct_ngtcp2_transport_params_original_dcid_present" "$ac_includes_default
+    #include <ngtcp2/ngtcp2.h>
+
+"
+if test "x$ac_cv_member_struct_ngtcp2_transport_params_original_dcid_present" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT 1
+_ACEOF
+
+
 fi
 
 
index 96f979a3c1e96ab7ded2d00ebb194e8552479074..6f7f3e2c4cb6ebff7b48604a531afc0a9f86dd16 100644 (file)
@@ -1534,12 +1534,12 @@ 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 ngtcp2_ccerr_default])
+    AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
     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
+    AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT
     #include <ngtcp2/ngtcp2.h>
     ])
-    AC_CHECK_MEMBERS([struct ngtcp2_pkt_hd.tokenlen, struct ngtcp2_settings.tokenlen],,,[AC_INCLUDES_DEFAULT
+    AC_CHECK_MEMBERS([struct ngtcp2_pkt_hd.tokenlen, struct ngtcp2_settings.tokenlen, struct ngtcp2_settings.max_tx_udp_payload_size, struct ngtcp2_transport_params.original_dcid_present],,,[AC_INCLUDES_DEFAULT
     #include <ngtcp2/ngtcp2.h>
     ])
 
index 956f740e848fac1621469e4a85602bd2625c255c..5c37a12f114ea3ec88f3e9222b51b6c33df5a03f 100644 (file)
@@ -4196,8 +4196,10 @@ doq_handshake_completed_cb(ngtcp2_conn* ATTR_UNUSED(conn), void* user_data)
        verbose(VERB_ALGO, "doq handshake_completed callback");
        verbose(VERB_ALGO, "ngtcp2_conn_get_max_data_left is %d",
                (int)ngtcp2_conn_get_max_data_left(doq_conn->conn));
+#ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
        verbose(VERB_ALGO, "ngtcp2_conn_get_max_local_streams_uni is %d",
                (int)ngtcp2_conn_get_max_local_streams_uni(doq_conn->conn));
+#endif
        verbose(VERB_ALGO, "ngtcp2_conn_get_streams_uni_left is %d",
                (int)ngtcp2_conn_get_streams_uni_left(doq_conn->conn));
        verbose(VERB_ALGO, "ngtcp2_conn_get_streams_bidi_left is %d",
@@ -4275,7 +4277,12 @@ doq_recv_stream_data_cb(ngtcp2_conn* ATTR_UNUSED(conn), uint32_t flags,
        verbose(VERB_ALGO, "doq recv stream data stream id %d offset %d "
                "datalen %d%s%s", (int)stream_id, (int)offset, (int)datalen,
                ((flags&NGTCP2_STREAM_DATA_FLAG_FIN)!=0?" FIN":""),
-               ((flags&NGTCP2_STREAM_DATA_FLAG_EARLY)!=0?" EARLY":""));
+#ifdef NGTCP2_STREAM_DATA_FLAG_0RTT
+               ((flags&NGTCP2_STREAM_DATA_FLAG_0RTT)!=0?" 0RTT":"")
+#else
+               ((flags&NGTCP2_STREAM_DATA_FLAG_EARLY)!=0?" EARLY":"")
+#endif
+               );
        stream = doq_stream_find(doq_conn, stream_id);
        if(!stream) {
                verbose(VERB_ALGO, "doq: received stream data for "
@@ -4398,6 +4405,7 @@ doq_log_printf_cb(void* ATTR_UNUSED(user_data), const char* fmt, ...)
        va_end(ap);
 }
 
+#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
 /** the doq application tx key callback, false on failure */
 static int
 doq_application_tx_key_cb(struct doq_conn* conn)
@@ -4407,8 +4415,10 @@ doq_application_tx_key_cb(struct doq_conn* conn)
         * the client instead initiates by opening bidi streams. */
        verbose(VERB_ALGO, "doq ngtcp2_conn_get_max_data_left is %d",
                (int)ngtcp2_conn_get_max_data_left(conn->conn));
+#ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
        verbose(VERB_ALGO, "doq ngtcp2_conn_get_max_local_streams_uni is %d",
                (int)ngtcp2_conn_get_max_local_streams_uni(conn->conn));
+#endif
        verbose(VERB_ALGO, "doq ngtcp2_conn_get_streams_uni_left is %d",
                (int)ngtcp2_conn_get_streams_uni_left(conn->conn));
        verbose(VERB_ALGO, "doq ngtcp2_conn_get_streams_bidi_left is %d",
@@ -4423,8 +4433,17 @@ doq_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
        size_t secret_len)
 {
        struct doq_conn* doq_conn = (struct doq_conn*)SSL_get_app_data(ssl);
-       ngtcp2_crypto_level level =
+#ifdef HAVE_NGTCP2_ENCRYPTION_LEVEL
+       ngtcp2_encryption_level
+#else
+       ngtcp2_crypto_level
+#endif
+               level =
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+               ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
+#else
                ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+#endif
 
        if(read_secret) {
                verbose(VERB_ALGO, "doq: ngtcp2_crypto_derive_and_install_rx_key for level %d ossl %d", (int)level, (int)ossl_level);
@@ -4460,8 +4479,17 @@ doq_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
        const uint8_t *data, size_t len)
 {
        struct doq_conn* doq_conn = (struct doq_conn*)SSL_get_app_data(ssl);
-       ngtcp2_crypto_level level =
+#ifdef HAVE_NGTCP2_ENCRYPTION_LEVEL
+       ngtcp2_encryption_level
+#else
+       ngtcp2_crypto_level
+#endif
+               level =
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+               ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
+#else
                ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+#endif
        int rv;
 
        verbose(VERB_ALGO, "doq_add_handshake_data: "
@@ -4492,6 +4520,7 @@ doq_send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
        doq_conn->tls_alert = alert;
        return 1;
 }
+#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
 
 /** ALPN select callback for the doq SSL context */
 static int
@@ -4514,7 +4543,9 @@ static SSL_CTX*
 doq_ctx_server_setup(struct doq_server_socket* doq_socket)
 {
        char* sid_ctx = "unbound server";
+#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
        SSL_QUIC_METHOD* quic_method;
+#endif
        SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
        if(!ctx) {
                log_crypto_err("Could not SSL_CTX_new");
@@ -4575,6 +4606,13 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket)
        }
 
        SSL_CTX_set_max_early_data(ctx, 0xffffffff);
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+       if(ngtcp2_crypto_quictls_configure_server_context(ctx) != 0) {
+               log_err("ngtcp2_crypto_quictls_configure_server_context failed");
+               SSL_CTX_free(ctx);
+               return NULL;
+       }
+#else
        /* The quic_method needs to remain valid during the SSL_CTX
         * lifetime, so we allocate it. It is freed with the
         * doq_server_socket. */
@@ -4590,9 +4628,17 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket)
        quic_method->flush_flight = doq_flush_flight;
        quic_method->send_alert = doq_send_alert;
        SSL_CTX_set_quic_method(ctx, doq_socket->quic_method);
+#endif
        return ctx;
 }
 
+/** Get the ngtcp2_conn from ssl userdata of type ngtcp2_conn_ref */
+static ngtcp2_conn* doq_conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
+{
+       struct doq_conn* conn = (struct doq_conn*)conn_ref->user_data;
+       return conn->conn;
+}
+
 /** create new SSL session for server connection */
 static SSL*
 doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
@@ -4602,7 +4648,13 @@ doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
                log_crypto_err("doq: SSL_new failed");
                return NULL;
        }
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+       conn->conn_ref.get_conn = &doq_conn_ref_get_conn;
+       conn->conn_ref.user_data = conn;
+       SSL_set_app_data(ssl, &conn->conn_ref);
+#else
        SSL_set_app_data(ssl, conn);
+#endif
        SSL_set_accept_state(ssl);
        SSL_set_quic_early_data_enabled(ssl, 1);
        return ssl;
@@ -4702,6 +4754,9 @@ doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
                ngtcp2_cid_init(&params.original_dcid, conn->key.dcid,
                        conn->key.dcidlen);
        }
+#ifdef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT
+       params.original_dcid_present = 1;
+#endif
        doq_fill_rand(conn->doq_socket->rnd, params.stateless_reset_token,
                sizeof(params.stateless_reset_token));
        sv_scid.datalen = conn->doq_socket->sv_scidlen;
@@ -4886,7 +4941,12 @@ doq_conn_setup_id_array_and_dcid(struct doq_conn* conn,
 int
 doq_conn_setup_conids(struct doq_conn* conn)
 {
-       size_t num_scid = ngtcp2_conn_get_num_scid(conn->conn);
+       size_t num_scid =
+#ifndef HAVE_NGTCP2_CONN_GET_NUM_SCID
+               ngtcp2_conn_get_scid(conn->conn, NULL);
+#else
+               ngtcp2_conn_get_num_scid(conn->conn);
+#endif
        if(num_scid <= 4) {
                struct ngtcp2_cid ids[4];
                /* Usually there are not that many scids when just accepted,
@@ -4954,9 +5014,21 @@ doq_conn_start_closing_period(struct comm_point* c, struct doq_conn* conn)
        ngtcp2_ssize ret;
        if(!conn)
                return 1;
-       if(ngtcp2_conn_is_in_closing_period(conn->conn))
+       if(
+#ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+               ngtcp2_conn_in_closing_period(conn->conn)
+#else
+               ngtcp2_conn_is_in_closing_period(conn->conn)
+#endif
+               )
                return 1;
-       if(ngtcp2_conn_is_in_draining_period(conn->conn)) {
+       if(
+#ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+               ngtcp2_conn_in_draining_period(conn->conn)
+#else
+               ngtcp2_conn_is_in_draining_period(conn->conn)
+#endif
+               ) {
                doq_conn_write_disable(conn);
                return 1;
        }
@@ -5031,7 +5103,13 @@ doq_conn_close_error(struct comm_point* c, struct doq_conn* conn)
 #endif
        if(!doq_conn_start_closing_period(c, conn))
                return 0;
-       if(ngtcp2_conn_is_in_draining_period(conn->conn)) {
+       if(
+#ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+               ngtcp2_conn_in_draining_period(conn->conn)
+#else
+               ngtcp2_conn_is_in_draining_period(conn->conn)
+#endif
+               ) {
                doq_conn_write_disable(conn);
                return 1;
        }
index 6f607c6ad7fa4593ca3853c9adeba3b4b8c50583..984dcc02768cc22c5ca639c97e39f900120d4f11 100644 (file)
@@ -51,6 +51,7 @@
 #endif
 #ifdef HAVE_NGTCP2
 #include <ngtcp2/ngtcp2.h>
+#include <ngtcp2/ngtcp2_crypto.h>
 #endif
 struct listen_list;
 struct config_file;
@@ -593,6 +594,10 @@ struct doq_conn {
        uint8_t tls_alert;
        /** the ssl context, SSL* */
        void* ssl;
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
+       /** the connection reference for ngtcp2_conn and userdata in ssl */
+       struct ngtcp2_crypto_conn_ref conn_ref;
+#endif
        /** closure packet, if any */
        uint8_t* close_pkt;
        /** length of closure packet. */
index a9a1c8a1f019ec49410827c37da0c742271c0be2..f058ccb32a9f1902adacf3086b15c43bdd37390d 100644 (file)
@@ -107,6 +107,10 @@ struct doq_client_data {
        SSL_CTX* ctx;
        /** SSL object */
        SSL* ssl;
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
+       /** the connection reference for ngtcp2_conn and userdata in ssl */
+       struct ngtcp2_crypto_conn_ref conn_ref;
+#endif
        /** the quic version to use */
        uint32_t quic_version;
        /** the last error */
@@ -193,8 +197,10 @@ struct doq_client_stream {
        int query_is_done;
 };
 
+#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
 /** the quic method struct, must remain valid during the QUIC connection. */
 static SSL_QUIC_METHOD quic_method;
+#endif
 
 /** write handle routine */
 static void on_write(struct doq_client_data* data);
@@ -202,6 +208,8 @@ static void on_write(struct doq_client_data* data);
 static void update_timer(struct doq_client_data* data);
 /** disconnect we are done */
 static void disconnect(struct doq_client_data* data);
+/** fetch and write the transport file */
+static void early_data_write_transport(struct doq_client_data* data);
 
 /** usage of doqclient */
 static void usage(char* argv[])
@@ -776,7 +784,11 @@ early_data_is_rejected(struct doq_client_data* data)
 {
        int rv;
        verbose(1, "early data was rejected by the server");
+#ifdef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
+       rv = ngtcp2_conn_tls_early_data_rejected(data->conn);
+#else
        rv = ngtcp2_conn_early_data_rejected(data->conn);
+#endif
        if(rv != 0) {
                log_err("ngtcp2_conn_early_data_rejected failed: %s",
                        ngtcp2_strerror(rv));
@@ -814,8 +826,10 @@ handshake_completed(ngtcp2_conn* ATTR_UNUSED(conn), void* user_data)
        verbose(1, "handshake_completed callback");
        verbose(1, "ngtcp2_conn_get_max_data_left is %d",
                (int)ngtcp2_conn_get_max_data_left(data->conn));
+#ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
        verbose(1, "ngtcp2_conn_get_max_local_streams_uni is %d",
                (int)ngtcp2_conn_get_max_local_streams_uni(data->conn));
+#endif
        verbose(1, "ngtcp2_conn_get_streams_uni_left is %d",
                (int)ngtcp2_conn_get_streams_uni_left(data->conn));
        verbose(1, "ngtcp2_conn_get_streams_bidi_left is %d",
@@ -843,6 +857,9 @@ handshake_completed(ngtcp2_conn* ATTR_UNUSED(conn), void* user_data)
                        verbose(1, "early data was accepted by the server");
                }
        }
+       if(data->transport_file) {
+               early_data_write_transport(data);
+       }
        return 0;
 }
 
@@ -856,8 +873,10 @@ extend_max_local_streams_bidi(ngtcp2_conn* ATTR_UNUSED(conn),
                (int)max_streams);
        verbose(1, "ngtcp2_conn_get_max_data_left is %d",
                (int)ngtcp2_conn_get_max_data_left(data->conn));
+#ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
        verbose(1, "ngtcp2_conn_get_max_local_streams_uni is %d",
                (int)ngtcp2_conn_get_max_local_streams_uni(data->conn));
+#endif
        verbose(1, "ngtcp2_conn_get_streams_uni_left is %d",
                (int)ngtcp2_conn_get_streams_uni_left(data->conn));
        verbose(1, "ngtcp2_conn_get_streams_bidi_left is %d",
@@ -878,7 +897,12 @@ recv_stream_data(ngtcp2_conn* ATTR_UNUSED(conn), uint32_t flags,
        verbose(1, "recv_stream_data stream %d offset %d datalen %d%s%s",
                (int)stream_id, (int)offset, (int)datalen,
                ((flags&NGTCP2_STREAM_DATA_FLAG_FIN)!=0?" FIN":""),
-               ((flags&NGTCP2_STREAM_DATA_FLAG_EARLY)!=0?" EARLY":""));
+#ifdef NGTCP2_STREAM_DATA_FLAG_0RTT
+               ((flags&NGTCP2_STREAM_DATA_FLAG_0RTT)!=0?" 0RTT":"")
+#else
+               ((flags&NGTCP2_STREAM_DATA_FLAG_EARLY)!=0?" EARLY":"")
+#endif
+               );
        if(verbosity > 0)
                log_hex("data", (void*)data, datalen);
        if(verbosity > 0) {
@@ -1017,8 +1041,13 @@ static struct ngtcp2_conn* conn_client_setup(struct doq_client_data* data)
 
        data->quic_version = client_chosen_version;
        ngtcp2_settings_default(&settings);
-       if(str_is_ip6(data->svr))
+       if(str_is_ip6(data->svr)) {
+#ifdef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
+               settings.max_tx_udp_payload_size = 1232;
+#else
                settings.max_udp_payload_size = 1232;
+#endif
+       }
        settings.rand_ctx.native_handle = data->rnd;
        if(verbosity > 0) {
                /* make debug logs */
@@ -1067,6 +1096,7 @@ static struct ngtcp2_conn* conn_client_setup(struct doq_client_data* data)
        return conn;
 }
 
+#ifndef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
 /** write the transport file */
 static void
 transport_file_write(const char* file, struct ngtcp2_transport_params* params)
@@ -1101,17 +1131,45 @@ transport_file_write(const char* file, struct ngtcp2_transport_params* params)
        }
        fclose(out);
 }
+#endif /* HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS */
 
 /** fetch and write the transport file */
 static void
 early_data_write_transport(struct doq_client_data* data)
 {
+#ifdef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
+       FILE* out;
+       uint8_t buf[1024];
+       ngtcp2_ssize len = ngtcp2_conn_encode_0rtt_transport_params(data->conn,
+               buf, sizeof(buf));
+       if(len < 0) {
+               log_err("ngtcp2_conn_encode_0rtt_transport_params failed: %s",
+                       ngtcp2_strerror(len));
+               return;
+       }
+       out = fopen(data->transport_file, "w");
+       if(!out) {
+               perror(data->transport_file);
+               return;
+       }
+       if(fwrite(buf, 1, len, out) != 1) {
+               log_err("fwrite %s failed: %s", data->transport_file,
+                       strerror(errno));
+       }
+       if(ferror(out)) {
+               verbose(1, "There was an error writing %s: %s",
+                       data->transport_file, strerror(errno));
+       }
+       fclose(out);
+#else
        struct ngtcp2_transport_params params;
        memset(&params, 0, sizeof(params));
        ngtcp2_conn_get_remote_transport_params(data->conn, &params);
        transport_file_write(data->transport_file, &params);
+#endif
 }
 
+#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
 /** applicatation rx key callback, this is where the rx key is set,
  * and streams can be opened, like http3 unidirectional streams, like
  * the http3 control and http3 qpack encode and decoder streams. */
@@ -1121,8 +1179,10 @@ application_rx_key_cb(struct doq_client_data* data)
        verbose(1, "application_rx_key_cb callback");
        verbose(1, "ngtcp2_conn_get_max_data_left is %d",
                (int)ngtcp2_conn_get_max_data_left(data->conn));
+#ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
        verbose(1, "ngtcp2_conn_get_max_local_streams_uni is %d",
                (int)ngtcp2_conn_get_max_local_streams_uni(data->conn));
+#endif
        verbose(1, "ngtcp2_conn_get_streams_uni_left is %d",
                (int)ngtcp2_conn_get_streams_uni_left(data->conn));
        verbose(1, "ngtcp2_conn_get_streams_bidi_left is %d",
@@ -1141,8 +1201,17 @@ set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
 {
        struct doq_client_data* data = (struct doq_client_data*)
                SSL_get_app_data(ssl);
-       ngtcp2_crypto_level level =
+#ifdef HAVE_NGTCP2_ENCRYPTION_LEVEL
+       ngtcp2_encryption_level
+#else
+       ngtcp2_crypto_level
+#endif
+               level =
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+               ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
+#else
                ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+#endif
 
        if(read_secret) {
                if(ngtcp2_crypto_derive_and_install_rx_key(data->conn, NULL,
@@ -1173,8 +1242,17 @@ add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
 {
        struct doq_client_data* doqdata = (struct doq_client_data*)
                SSL_get_app_data(ssl);
-       ngtcp2_crypto_level level =
+#ifdef HAVE_NGTCP2_ENCRYPTION_LEVEL
+       ngtcp2_encryption_level
+#else
+       ngtcp2_crypto_level
+#endif
+               level =
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
+               ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
+#else
                ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
+#endif
        int rv;
 
        rv = ngtcp2_conn_submit_crypto_data(doqdata->conn, level, data, len);
@@ -1204,6 +1282,7 @@ send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
        data->tls_alert = alert;
        return 1;
 }
+#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT */
 
 /** new session callback. We can write it to file for resumption later. */
 static int
@@ -1238,15 +1317,31 @@ ctx_client_setup(void)
        SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
        SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
        SSL_CTX_set_default_verify_paths(ctx);
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
+       if(ngtcp2_crypto_quictls_configure_client_context(ctx) != 0) {
+               log_err("ngtcp2_crypto_quictls_configure_client_context failed");
+               exit(1);
+       }
+#else
        memset(&quic_method, 0, sizeof(quic_method));
        quic_method.set_encryption_secrets = &set_encryption_secrets;
        quic_method.add_handshake_data = &add_handshake_data;
        quic_method.flush_flight = &flush_flight;
        quic_method.send_alert = &send_alert;
        SSL_CTX_set_quic_method(ctx, &quic_method);
+#endif
        return ctx;
 }
 
+/** Get the connection ngtcp2_conn from the ssl app data
+ * ngtcp2_crypto_conn_ref */
+static ngtcp2_conn* conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
+{
+       struct doq_client_data* data = (struct doq_client_data*)
+               conn_ref->user_data;
+       return data->conn;
+}
+
 /* setup the TLS object */
 static SSL*
 ssl_client_setup(struct doq_client_data* data)
@@ -1256,7 +1351,13 @@ ssl_client_setup(struct doq_client_data* data)
                log_crypto_err("Could not SSL_new");
                exit(1);
        }
+#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
+       data->conn_ref.get_conn = &conn_ref_get_conn;
+       data->conn_ref.user_data = data;
+       SSL_set_app_data(ssl, &data->conn_ref);
+#else
        SSL_set_app_data(ssl, data);
+#endif
        SSL_set_connect_state(ssl);
        if(!SSL_set_fd(ssl, data->fd)) {
                log_crypto_err("Could not SSL_set_fd");
@@ -1402,8 +1503,18 @@ write_conn_close(struct doq_client_data* data)
        struct ngtcp2_path_storage ps;
        struct ngtcp2_pkt_info pi;
        ngtcp2_ssize ret;
-       if(!data->conn || ngtcp2_conn_is_in_closing_period(data->conn) ||
-               ngtcp2_conn_is_in_draining_period(data->conn))
+       if(!data->conn ||
+#ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+               ngtcp2_conn_in_closing_period(data->conn) ||
+#else
+               ngtcp2_conn_is_in_closing_period(data->conn) ||
+#endif
+#ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+               ngtcp2_conn_in_draining_period(data->conn)
+#else
+               ngtcp2_conn_is_in_draining_period(data->conn)
+#endif
+               )
                return;
        /* Drop blocked packet if there is one, the connection is being
         * closed. And thus no further data traffic. */
@@ -1869,7 +1980,13 @@ on_write(struct doq_client_data* data)
                if(!send_blocked_pkt(data))
                        return;
        }
-       if(ngtcp2_conn_is_in_closing_period(data->conn))
+       if(
+#ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+               ngtcp2_conn_in_closing_period(data->conn)
+#else
+               ngtcp2_conn_is_in_closing_period(data->conn)
+#endif
+               )
                return;
        if(!write_streams(data))
                return;
@@ -1933,6 +2050,7 @@ early_data_setup_session(struct doq_client_data* data)
        return 1;
 }
 
+#ifndef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
 /** parse one line from the transport file */
 static int
 transport_parse_line(struct ngtcp2_transport_params* params, char* line)
@@ -1971,11 +2089,44 @@ transport_parse_line(struct ngtcp2_transport_params* params, char* line)
        }
        return 0;
 }
+#endif /* HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS */
 
 /** setup the early data transport file and read it */
 static int
 early_data_setup_transport(struct doq_client_data* data)
 {
+#ifdef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
+       FILE* in;
+       uint8_t buf[1024];
+       size_t len;
+       int rv;
+       in = fopen(data->transport_file, "r");
+       if(!in) {
+               if(errno == ENOENT) {
+                       verbose(1, "transport file %s does not exist",
+                               data->transport_file);
+                       return 0;
+               }
+               perror(data->transport_file);
+               return 0;
+       }
+       len = fread(buf, 1, sizeof(buf), in);
+       if(ferror(in)) {
+               log_err("%s: read failed: %s", data->transport_file,
+                       strerror(errno));
+               fclose(in);
+               return 0;
+       }
+       fclose(in);
+       rv = ngtcp2_conn_decode_and_set_0rtt_transport_params(data->conn,
+               buf, len);
+       if(rv != 0) {
+               log_err("ngtcp2_conn_decode_and_set_0rtt_transport_params failed: %s",
+                       ngtcp2_strerror(rv));
+               return 0;
+       }
+       return 1;
+#else
        FILE* in;
        char buf[1024];
        struct ngtcp2_transport_params params;
@@ -2006,6 +2157,7 @@ early_data_setup_transport(struct doq_client_data* data)
        }
        fclose(in);
        ngtcp2_conn_set_early_remote_transport_params(data->conn, &params);
+#endif
        return 1;
 }
 
index e93fe0e785c266ee6f402c3bbe5bb297ee94d30f..e2284603f84bfac45d9747f56a9ec52c3f748e68 100644 (file)
@@ -2323,8 +2323,17 @@ doq_timer_cb(void* arg)
 
        while((conn = doq_timer_timeout_conn(doq_socket)) != NULL) {
                if(conn->is_deleted ||
+#ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+                       ngtcp2_conn_in_closing_period(conn->conn) ||
+#else
                        ngtcp2_conn_is_in_closing_period(conn->conn) ||
-                       ngtcp2_conn_is_in_draining_period(conn->conn)) {
+#endif
+#ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+                       ngtcp2_conn_in_draining_period(conn->conn)
+#else
+                       ngtcp2_conn_is_in_draining_period(conn->conn)
+#endif
+                       ) {
                        if(verbosity >= VERB_ALGO) {
                                char remotestr[256];
                                addr_to_str((void*)&conn->key.paddr.addr,
@@ -2385,8 +2394,17 @@ comm_point_doq_callback(int fd, short event, void* arg)
        num_len = doq_write_list_length(c);
        while((conn = doq_pop_write_conn(c)) != NULL) {
                if(conn->is_deleted ||
+#ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+                       ngtcp2_conn_in_closing_period(conn->conn) ||
+#else
                        ngtcp2_conn_is_in_closing_period(conn->conn) ||
-                       ngtcp2_conn_is_in_draining_period(conn->conn)) {
+#endif
+#ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+                       ngtcp2_conn_in_draining_period(conn->conn)
+#else
+                       ngtcp2_conn_is_in_draining_period(conn->conn)
+#endif
+                       ) {
                        conn->doq_socket = NULL;
                        lock_basic_unlock(&conn->lock);
                        if(c->doq_socket->have_blocked_pkt) {
@@ -2483,7 +2501,13 @@ comm_point_doq_callback(int fd, short event, void* arg)
                        doq_done_setup_timer_and_write(c, conn);
                        continue;
                }
-               if(ngtcp2_conn_is_in_closing_period(conn->conn)) {
+               if(
+#ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
+                       ngtcp2_conn_in_closing_period(conn->conn)
+#else
+                       ngtcp2_conn_is_in_closing_period(conn->conn)
+#endif
+                       ) {
                        if(!doq_conn_send_close(c, conn)) {
                                doq_delete_connection(c, conn);
                        } else {
@@ -2491,7 +2515,13 @@ comm_point_doq_callback(int fd, short event, void* arg)
                        }
                        continue;
                }
-               if(ngtcp2_conn_is_in_draining_period(conn->conn)) {
+               if(
+#ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
+                       ngtcp2_conn_in_draining_period(conn->conn)
+#else
+                       ngtcp2_conn_is_in_draining_period(conn->conn)
+#endif
+                       ) {
                        doq_done_setup_timer_and_write(c, conn);
                        continue;
                }
@@ -2637,7 +2667,9 @@ doq_server_socket_delete(struct doq_server_socket* doq_socket)
                return;
        free(doq_socket->static_secret);
        SSL_CTX_free(doq_socket->ctx);
+#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
        free(doq_socket->quic_method);
+#endif
        free(doq_socket->ssl_service_key);
        free(doq_socket->ssl_service_pem);
        free(doq_socket->ssl_verify_pem);
index a698c95631fb136917d1557b2d60e3e13b17f325..ac89add8d66e05e9812ea0e9282a2aca19f0e3f8 100644 (file)
@@ -1054,8 +1054,10 @@ struct doq_server_socket {
        size_t static_secret_len;
        /** ssl context, SSL_CTX* */
        void* ctx;
+#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
        /** quic method functions, SSL_QUIC_METHOD* */
        void* quic_method;
+#endif
        /** the comm point for this doq server socket */
        struct comm_point* cp;
        /** the buffer for packets, doq in and out */