From 881747218ba0ad411f6f1bf361c2c09c805d4aa8 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 19 Sep 2022 10:24:20 +0000 Subject: [PATCH 1/4] Convert xfrin.c:get_create_tlsctx() into a library function In order to make xfrin.c:get_create_tlsctx() reusable, move the function into transport.c, and make changes into its prototype to not use the 'dns_xfrin_ctx_t' type, thus making it more universal. This change prepares ground for adding transport support into the dispatch manager. Also, move the typedefs for 'dns_transport_t' and 'dns_transport_list_t' from transport.h into types.h. --- lib/dns/include/dns/transport.h | 25 +++- lib/dns/include/dns/types.h | 2 + lib/dns/transport.c | 214 ++++++++++++++++++++++++++++++++ lib/dns/xfrin.c | 214 +------------------------------- 4 files changed, 240 insertions(+), 215 deletions(-) diff --git a/lib/dns/include/dns/transport.h b/lib/dns/include/dns/transport.h index e74ccd7f97..d3df43d6b8 100644 --- a/lib/dns/include/dns/transport.h +++ b/lib/dns/include/dns/transport.h @@ -13,7 +13,9 @@ #pragma once -#include +#include + +#include typedef enum { DNS_TRANSPORT_NONE = 0, @@ -29,9 +31,6 @@ typedef enum { DNS_HTTP_POST = 1, } dns_http_mode_t; -typedef struct dns_transport dns_transport_t; -typedef struct dns_transport_list dns_transport_list_t; - dns_transport_t * dns_transport_new(const dns_name_t *name, dns_transport_type_t type, dns_transport_list_t *list); @@ -72,6 +71,24 @@ dns_transport_get_prefer_server_ciphers(const dns_transport_t *transport, * 'preferp' pointer. */ +isc_result_t +dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer, + isc_tlsctx_cache_t *tlsctx_cache, isc_mem_t *mctx, + isc_tlsctx_t **pctx, + isc_tlsctx_client_session_cache_t **psess_cache); +/*%< + * Get the transport's TLS Context and the TLS Client Session Cache associated + * with it. + * + * Requires: + *\li 'transport' is a valid, 'DNS_TRANSPORT_TLS' type transport. + *\li 'peer' is not NULL. + *\li 'tlsctx_cache' is not NULL. + *\li 'mctx' is not NULL. + *\li 'pctx' is not NULL and '*pctx' is NULL. + *\li 'psess_cache' is not NULL and '*psess_cache' is NULL. + */ + void dns_transport_set_certfile(dns_transport_t *transport, const char *certfile); void diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index 4d69639f13..b4207adcf2 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -140,6 +140,8 @@ typedef struct dns_ssutable dns_ssutable_t; typedef struct dns_stats dns_stats_t; typedef uint32_t dns_rdatastatstype_t; typedef struct dns_tkeyctx dns_tkeyctx_t; +typedef struct dns_transport dns_transport_t; +typedef struct dns_transport_list dns_transport_list_t; typedef uint16_t dns_trust_t; typedef struct dns_tsec dns_tsec_t; typedef struct dns_tsig_keyring dns_tsig_keyring_t; diff --git a/lib/dns/transport.c b/lib/dns/transport.c index ae1ab7415b..8e0a8f6661 100644 --- a/lib/dns/transport.c +++ b/lib/dns/transport.c @@ -15,9 +15,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -332,6 +334,218 @@ dns_transport_get_prefer_server_ciphers(const dns_transport_t *transport, return false; } +isc_result_t +dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer, + isc_tlsctx_cache_t *tlsctx_cache, isc_mem_t *mctx, + isc_tlsctx_t **pctx, + isc_tlsctx_client_session_cache_t **psess_cache) { + isc_result_t result = ISC_R_FAILURE; + isc_tlsctx_t *tlsctx = NULL, *found = NULL; + isc_tls_cert_store_t *store = NULL, *found_store = NULL; + isc_tlsctx_client_session_cache_t *sess_cache = NULL; + isc_tlsctx_client_session_cache_t *found_sess_cache = NULL; + uint32_t tls_versions; + const char *ciphers = NULL; + bool prefer_server_ciphers; + uint16_t family; + const char *tlsname = NULL; + + REQUIRE(VALID_TRANSPORT(transport)); + REQUIRE(transport->type == DNS_TRANSPORT_TLS); + REQUIRE(peer != NULL); + REQUIRE(tlsctx_cache != NULL); + REQUIRE(mctx != NULL); + REQUIRE(pctx != NULL && *pctx == NULL); + REQUIRE(psess_cache != NULL && *psess_cache == NULL); + + family = (isc_sockaddr_pf(peer) == PF_INET6) ? AF_INET6 : AF_INET; + + tlsname = dns_transport_get_tlsname(transport); + INSIST(tlsname != NULL && *tlsname != '\0'); + + /* + * Let's try to re-use the already created context. This way + * we have a chance to resume the TLS session, bypassing the + * full TLS handshake procedure, making establishing + * subsequent TLS connections faster. + */ + result = isc_tlsctx_cache_find(tlsctx_cache, tlsname, + isc_tlsctx_cache_tls, family, &found, + &found_store, &found_sess_cache); + if (result != ISC_R_SUCCESS) { + const char *hostname = + dns_transport_get_remote_hostname(transport); + const char *ca_file = dns_transport_get_cafile(transport); + const char *cert_file = dns_transport_get_certfile(transport); + const char *key_file = dns_transport_get_keyfile(transport); + char peer_addr_str[INET6_ADDRSTRLEN] = { 0 }; + isc_netaddr_t peer_netaddr = { 0 }; + bool hostname_ignore_subject; + + /* + * So, no context exists. Let's create one using the + * parameters from the configuration file and try to + * store it for further reuse. + */ + result = isc_tlsctx_createclient(&tlsctx); + if (result != ISC_R_SUCCESS) { + goto failure; + } + tls_versions = dns_transport_get_tls_versions(transport); + if (tls_versions != 0) { + isc_tlsctx_set_protocols(tlsctx, tls_versions); + } + ciphers = dns_transport_get_ciphers(transport); + if (ciphers != NULL) { + isc_tlsctx_set_cipherlist(tlsctx, ciphers); + } + + if (dns_transport_get_prefer_server_ciphers( + transport, &prefer_server_ciphers)) { + isc_tlsctx_prefer_server_ciphers(tlsctx, + prefer_server_ciphers); + } + + if (hostname != NULL || ca_file != NULL) { + /* + * The situation when 'found_store != NULL' while + * 'found == NULL' may occur as there is a one-to-many + * relation between cert stores and per-transport TLS + * contexts. That is, there could be one store + * shared between multiple contexts. + */ + if (found_store == NULL) { + /* + * 'ca_file' can equal 'NULL' here, in + * which case the store with system-wide + * CA certificates will be created. + */ + result = isc_tls_cert_store_create(ca_file, + &store); + + if (result != ISC_R_SUCCESS) { + goto failure; + } + } else { + store = found_store; + } + + INSIST(store != NULL); + if (hostname == NULL) { + /* + * If CA bundle file is specified, but + * hostname is not, then use the peer + * IP address for validation, just like + * dig does. + */ + INSIST(ca_file != NULL); + isc_netaddr_fromsockaddr(&peer_netaddr, peer); + isc_netaddr_format(&peer_netaddr, peer_addr_str, + sizeof(peer_addr_str)); + hostname = peer_addr_str; + } + + /* + * According to RFC 8310, Subject field MUST NOT + * be inspected when verifying hostname for DoT. + * Only SubjectAltName must be checked. + */ + hostname_ignore_subject = true; + result = isc_tlsctx_enable_peer_verification( + tlsctx, false, store, hostname, + hostname_ignore_subject); + if (result != ISC_R_SUCCESS) { + goto failure; + } + + /* + * Let's load client certificate and enable + * Mutual TLS. We do that only in the case when + * Strict TLS is enabled, because Mutual TLS is + * an extension of it. + */ + if (cert_file != NULL) { + INSIST(key_file != NULL); + + result = isc_tlsctx_load_certificate( + tlsctx, key_file, cert_file); + if (result != ISC_R_SUCCESS) { + goto failure; + } + } + } + + isc_tlsctx_enable_dot_client_alpn(tlsctx); + + sess_cache = isc_tlsctx_client_session_cache_new( + mctx, tlsctx, + ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE); + + found_store = NULL; + result = isc_tlsctx_cache_add(tlsctx_cache, tlsname, + isc_tlsctx_cache_tls, family, + tlsctx, store, sess_cache, &found, + &found_store, &found_sess_cache); + if (result == ISC_R_EXISTS) { + /* + * It seems the entry has just been created from + * within another thread while we were initialising + * ours. Although this is unlikely, it could happen + * after startup/re-initialisation. In such a case, + * discard the new context and associated data and use + * the already established one from now on. + * + * Such situation will not occur after the + * initial 'warm-up', so it is not critical + * performance-wise. + */ + INSIST(found != NULL); + isc_tlsctx_free(&tlsctx); + isc_tls_cert_store_free(&store); + isc_tlsctx_client_session_cache_detach(&sess_cache); + /* Let's return the data from the cache. */ + *psess_cache = found_sess_cache; + *pctx = found; + } else { + /* + * Adding the fresh values into the cache has been + * successful, let's return them + */ + INSIST(result == ISC_R_SUCCESS); + *psess_cache = sess_cache; + *pctx = tlsctx; + } + } else { + /* + * The cache lookup has been successful, let's return the + * results. + */ + INSIST(result == ISC_R_SUCCESS); + *psess_cache = found_sess_cache; + *pctx = found; + } + + return (ISC_R_SUCCESS); + +failure: + if (tlsctx != NULL) { + isc_tlsctx_free(&tlsctx); + } + + /* + * The 'found_store' is being managed by the TLS context + * cache. Thus, we should keep it as it is, as it will get + * destroyed alongside the cache. As there is one store per + * multiple TLS contexts, we need to handle store deletion in a + * special way. + */ + if (store != NULL && store != found_store) { + isc_tls_cert_store_free(&store); + } + + return (result); +} + static void transport_destroy(dns_transport_t *transport) { isc_refcount_destroy(&transport->references); diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index a360263265..e27d0d6909 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -927,216 +927,6 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr, *xfrp = xfr; } -static isc_result_t -get_create_tlsctx(const dns_xfrin_ctx_t *xfr, isc_tlsctx_t **pctx, - isc_tlsctx_client_session_cache_t **psess_cache) { - isc_result_t result = ISC_R_FAILURE; - isc_tlsctx_t *tlsctx = NULL, *found = NULL; - isc_tls_cert_store_t *store = NULL, *found_store = NULL; - isc_tlsctx_client_session_cache_t *sess_cache = NULL, - *found_sess_cache = NULL; - uint32_t tls_versions; - const char *ciphers = NULL; - bool prefer_server_ciphers; - const uint16_t family = isc_sockaddr_pf(&xfr->primaryaddr) == PF_INET6 - ? AF_INET6 - : AF_INET; - const char *tlsname = NULL; - - REQUIRE(psess_cache != NULL && *psess_cache == NULL); - REQUIRE(pctx != NULL && *pctx == NULL); - - INSIST(xfr->transport != NULL); - tlsname = dns_transport_get_tlsname(xfr->transport); - INSIST(tlsname != NULL && *tlsname != '\0'); - - /* - * Let's try to re-use the already created context. This way - * we have a chance to resume the TLS session, bypassing the - * full TLS handshake procedure, making establishing - * subsequent TLS connections for XoT faster. - */ - result = isc_tlsctx_cache_find(xfr->tlsctx_cache, tlsname, - isc_tlsctx_cache_tls, family, &found, - &found_store, &found_sess_cache); - if (result != ISC_R_SUCCESS) { - const char *hostname = - dns_transport_get_remote_hostname(xfr->transport); - const char *ca_file = dns_transport_get_cafile(xfr->transport); - const char *cert_file = - dns_transport_get_certfile(xfr->transport); - const char *key_file = - dns_transport_get_keyfile(xfr->transport); - char primary_addr_str[INET6_ADDRSTRLEN] = { 0 }; - isc_netaddr_t primary_netaddr = { 0 }; - bool hostname_ignore_subject; - /* - * So, no context exists. Let's create one using the - * parameters from the configuration file and try to - * store it for further reuse. - */ - result = isc_tlsctx_createclient(&tlsctx); - if (result != ISC_R_SUCCESS) { - goto failure; - } - tls_versions = dns_transport_get_tls_versions(xfr->transport); - if (tls_versions != 0) { - isc_tlsctx_set_protocols(tlsctx, tls_versions); - } - ciphers = dns_transport_get_ciphers(xfr->transport); - if (ciphers != NULL) { - isc_tlsctx_set_cipherlist(tlsctx, ciphers); - } - - if (dns_transport_get_prefer_server_ciphers( - xfr->transport, &prefer_server_ciphers)) - { - isc_tlsctx_prefer_server_ciphers(tlsctx, - prefer_server_ciphers); - } - - if (hostname != NULL || ca_file != NULL) { - /* - * The situation when 'found_store != NULL' while 'found - * == NULL' might appear as there is one to many - * relation between per transport TLS contexts and cert - * stores. That is, there could be one store shared - * between multiple contexts. - */ - if (found_store == NULL) { - /* - * 'ca_file' can equal 'NULL' here, in - * that case the store with system-wide - * CA certificates will be created, just - * as planned. - */ - result = isc_tls_cert_store_create(ca_file, - &store); - - if (result != ISC_R_SUCCESS) { - goto failure; - } - } else { - store = found_store; - } - - INSIST(store != NULL); - if (hostname == NULL) { - /* - * If CA bundle file is specified, but - * hostname is not, then use the primary - * IP address for validation, just like - * dig does. - */ - INSIST(ca_file != NULL); - isc_netaddr_fromsockaddr(&primary_netaddr, - &xfr->primaryaddr); - isc_netaddr_format(&primary_netaddr, - primary_addr_str, - sizeof(primary_addr_str)); - hostname = primary_addr_str; - } - /* - * According to RFC 8310, Subject field MUST NOT - * be inspected when verifying hostname for DoT. - * Only SubjectAltName must be checked. - */ - hostname_ignore_subject = true; - result = isc_tlsctx_enable_peer_verification( - tlsctx, false, store, hostname, - hostname_ignore_subject); - if (result != ISC_R_SUCCESS) { - goto failure; - } - - /* - * Let's load client certificate and enable - * Mutual TLS. We do that only in the case when - * Strict TLS is enabled, because Mutual TLS is - * an extension of it. - */ - if (cert_file != NULL) { - INSIST(key_file != NULL); - - result = isc_tlsctx_load_certificate( - tlsctx, key_file, cert_file); - if (result != ISC_R_SUCCESS) { - goto failure; - } - } - } - - isc_tlsctx_enable_dot_client_alpn(tlsctx); - - sess_cache = isc_tlsctx_client_session_cache_new( - xfr->mctx, tlsctx, - ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE); - - found_store = NULL; - result = isc_tlsctx_cache_add(xfr->tlsctx_cache, tlsname, - isc_tlsctx_cache_tls, family, - tlsctx, store, sess_cache, &found, - &found_store, &found_sess_cache); - if (result == ISC_R_EXISTS) { - /* - * It seems the entry has just been created from within - * another thread while we were initialising - * ours. Although this is unlikely, it could happen - * after startup/re-initialisation. In such a case, - * discard the new context and associated data and use - * the already established one from now on. - * - * Such situation will not occur after the - * initial 'warm-up', so it is not critical - * performance-wise. - */ - INSIST(found != NULL); - isc_tlsctx_free(&tlsctx); - isc_tls_cert_store_free(&store); - isc_tlsctx_client_session_cache_detach(&sess_cache); - /* Let's return the data from the cache. */ - *psess_cache = found_sess_cache; - *pctx = found; - } else { - /* - * Adding the fresh values into the cache has been - * successful, let's return them - */ - INSIST(result == ISC_R_SUCCESS); - *psess_cache = sess_cache; - *pctx = tlsctx; - } - } else { - /* - * The cache lookup has been successful, let's return the - * results. - */ - INSIST(result == ISC_R_SUCCESS); - *psess_cache = found_sess_cache; - *pctx = found; - } - - return (ISC_R_SUCCESS); - -failure: - if (tlsctx != NULL) { - isc_tlsctx_free(&tlsctx); - } - - /* - * The 'found_store' is being managed by the TLS context - * cache. Thus, we should keep it as it is, as it will get - * destroyed alongside the cache. As there is one store per - * multiple TLS contexts, we need to handle store deletion in a - * special way. - */ - if (store != NULL && store != found_store) { - isc_tls_cert_store_free(&store); - } - - return (result); -} - static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr) { isc_result_t result; @@ -1163,7 +953,9 @@ xfrin_start(dns_xfrin_ctx_t *xfr) { connect_xfr, 30000); break; case DNS_TRANSPORT_TLS: { - result = get_create_tlsctx(xfr, &tlsctx, &sess_cache); + result = dns_transport_get_tlsctx( + xfr->transport, &xfr->primaryaddr, xfr->tlsctx_cache, + xfr->mctx, &tlsctx, &sess_cache); if (result != ISC_R_SUCCESS) { goto failure; } From 90959f6166dbb1143c89ac4b919a243e2fecf1ed Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 19 Sep 2022 11:04:22 +0000 Subject: [PATCH 2/4] Implement TLS transport support for dns_request and dns_dispatch This change prepares ground for sending DNS requests using DoT, which, in particular, will be used for forwarding dynamic updates to TLS-enabled primaries. --- bin/nsupdate/nsupdate.c | 32 +++++------ bin/tests/system/pipelined/pipequeries.c | 8 +-- bin/tests/system/tkey/keycreate.c | 7 ++- bin/tests/system/tkey/keydelete.c | 7 ++- bin/tools/mdig.c | 4 +- lib/dns/dispatch.c | 70 ++++++++++++++++++++++-- lib/dns/include/dns/dispatch.h | 1 + lib/dns/include/dns/request.h | 7 ++- lib/dns/request.c | 22 +++++--- lib/dns/resolver.c | 2 +- lib/dns/zone.c | 35 ++++++------ tests/dns/dispatch_test.c | 31 ++++++----- 12 files changed, 149 insertions(+), 77 deletions(-) diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 4f4a349420..caac7f8489 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -2480,10 +2480,10 @@ send_update(dns_name_t *zone, isc_sockaddr_t *primary) { updatemsg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; } - result = dns_request_create(requestmgr, updatemsg, srcaddr, primary, -1, - options, tsigkey, timeout, udp_timeout, - udp_retries, global_task, update_completed, - NULL, &request); + result = dns_request_create(requestmgr, updatemsg, srcaddr, primary, + NULL, NULL, -1, options, tsigkey, timeout, + udp_timeout, udp_retries, global_task, + update_completed, NULL, &request); check_result(result, "dns_request_create"); if (debugging) { @@ -2589,10 +2589,10 @@ recvsoa(isc_task_t *task, isc_event_t *event) { srcaddr = localaddr4; } - result = dns_request_create(requestmgr, soaquery, srcaddr, addr, - -1, 0, NULL, FIND_TIMEOUT * 20, - FIND_TIMEOUT, 3, global_task, - recvsoa, reqinfo, &request); + result = dns_request_create( + requestmgr, soaquery, srcaddr, addr, NULL, NULL, -1, 0, + NULL, FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, global_task, + recvsoa, reqinfo, &request); check_result(result, "dns_request_create"); requests++; return; @@ -2808,10 +2808,10 @@ sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, srcaddr = localaddr4; } - result = dns_request_create(requestmgr, msg, srcaddr, destaddr, -1, 0, - default_servers ? NULL : tsigkey, - FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, - global_task, recvsoa, reqinfo, request); + result = dns_request_create( + requestmgr, msg, srcaddr, destaddr, NULL, NULL, -1, 0, + default_servers ? NULL : tsigkey, FIND_TIMEOUT * 20, + FIND_TIMEOUT, 3, global_task, recvsoa, reqinfo, request); check_result(result, "dns_request_create"); requests++; } @@ -3010,10 +3010,10 @@ send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, srcaddr = localaddr4; } - result = dns_request_create(requestmgr, msg, srcaddr, destaddr, -1, - options, tsigkey, FIND_TIMEOUT * 20, - FIND_TIMEOUT, 3, global_task, recvgss, - reqinfo, request); + result = dns_request_create(requestmgr, msg, srcaddr, destaddr, NULL, + NULL, -1, options, tsigkey, + FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, + global_task, recvgss, reqinfo, request); check_result(result, "dns_request_create"); if (debugging) { show_message(stdout, msg, "Outgoing update query:"); diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index 8003a390e8..623f9748c2 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -169,10 +169,10 @@ sendquery(isc_task_t *task) { ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(message, qname, DNS_SECTION_QUESTION); - result = dns_request_create(requestmgr, message, - have_src ? &srcaddr : NULL, &dstaddr, -1, - DNS_REQUESTOPT_TCP, NULL, TIMEOUT, 0, 0, - task, recvresponse, message, &request); + result = dns_request_create( + requestmgr, message, have_src ? &srcaddr : NULL, &dstaddr, NULL, + NULL, -1, DNS_REQUESTOPT_TCP, NULL, TIMEOUT, 0, 0, task, + recvresponse, message, &request); CHECK("dns_request_create", result); return (ISC_R_SUCCESS); diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c index 26f2aa7b13..255c29125e 100644 --- a/bin/tests/system/tkey/keycreate.c +++ b/bin/tests/system/tkey/keycreate.c @@ -178,9 +178,10 @@ sendquery(void *arg) { DNS_TSIG_HMACMD5_NAME, &nonce, 3600); CHECK("dns_tkey_builddhquery", result); - result = dns_request_create(requestmgr, query, NULL, &address, -1, - DNS_REQUESTOPT_TCP, initialkey, TIMEOUT, 0, - 0, task, recvquery, query, &request); + result = dns_request_create(requestmgr, query, NULL, &address, NULL, + NULL, -1, DNS_REQUESTOPT_TCP, initialkey, + TIMEOUT, 0, 0, task, recvquery, query, + &request); CHECK("dns_request_create", result); } diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c index a3083d755b..4bfdd0feae 100644 --- a/bin/tests/system/tkey/keydelete.c +++ b/bin/tests/system/tkey/keydelete.c @@ -122,9 +122,10 @@ sendquery(void *arg) { result = dns_tkey_builddeletequery(query, tsigkey); CHECK("dns_tkey_builddeletequery", result); - result = dns_request_create(requestmgr, query, NULL, &address, -1, - DNS_REQUESTOPT_TCP, tsigkey, TIMEOUT, 0, 0, - task, recvquery, query, &request); + result = dns_request_create(requestmgr, query, NULL, &address, NULL, + NULL, -1, DNS_REQUESTOPT_TCP, tsigkey, + TIMEOUT, 0, 0, task, recvquery, query, + &request); CHECK("dns_request_create", result); } diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index af7269480e..368730b0e9 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -756,8 +756,8 @@ sendquery(struct query *query) { } result = dns_request_create( - requestmgr, message, have_src ? &srcaddr : NULL, &dstaddr, dscp, - options, NULL, query->timeout, query->udptimeout, + requestmgr, message, have_src ? &srcaddr : NULL, &dstaddr, NULL, + NULL, dscp, options, NULL, query->timeout, query->udptimeout, query->udpretries, global_task, recvresponse, message, &request); CHECK("dns_request_create", result); diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index fcee9751c2..15062f523c 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include typedef ISC_LIST(dns_dispentry_t) dns_displist_t; @@ -75,6 +77,8 @@ struct dns_dispentry { isc_refcount_t references; dns_dispatch_t *disp; isc_nmhandle_t *handle; /*%< netmgr handle for UDP connection */ + dns_transport_t *transport; + isc_tlsctx_cache_t *tlsctx_cache; unsigned int bucket; unsigned int retries; unsigned int timeout; @@ -407,6 +411,14 @@ dispentry_destroy(dns_dispentry_t *resp) { isc_nmhandle_detach(&resp->handle); } + if (resp->tlsctx_cache != NULL) { + isc_tlsctx_cache_detach(&resp->tlsctx_cache); + } + + if (resp->transport != NULL) { + dns_transport_detach(&resp->transport); + } + isc_refcount_destroy(&resp->references); isc_mem_put(disp->mgr->mctx, resp, sizeof(*resp)); @@ -1384,6 +1396,7 @@ dns_dispatch_detach(dns_dispatch_t **dispp) { isc_result_t dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, unsigned int timeout, const isc_sockaddr_t *dest, + dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache, dispatch_cb_t connected, dispatch_cb_t sent, dispatch_cb_t response, void *arg, dns_messageid_t *idp, dns_dispentry_t **resp) { @@ -1486,6 +1499,14 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, return (ISC_R_NOMORE); } + if (transport != NULL) { + dns_transport_attach(transport, &res->transport); + } + + if (tlsctx_cache != NULL) { + isc_tlsctx_cache_attach(tlsctx_cache, &res->tlsctx_cache); + } + dns_dispatch_attach(disp, &res->disp); res->id = id; @@ -1791,16 +1812,45 @@ isc_result_t dns_dispatch_connect(dns_dispentry_t *resp) { dns_dispatch_t *disp = NULL; uint_fast32_t tcpstate = DNS_DISPATCHSTATE_NONE; + dns_transport_type_t transport_type = DNS_TRANSPORT_NONE; + isc_tlsctx_t *tlsctx = NULL; + isc_tlsctx_client_session_cache_t *sess_cache = NULL; REQUIRE(VALID_RESPONSE(resp)); disp = resp->disp; + if (disp->socktype == isc_socktype_tcp) { + transport_type = DNS_TRANSPORT_TCP; + } else if (disp->socktype == isc_socktype_udp) { + transport_type = DNS_TRANSPORT_UDP; + } else { + return (ISC_R_NOTIMPLEMENTED); + } + + if (resp->transport != NULL) { + transport_type = dns_transport_get_type(resp->transport); + } + + if (transport_type == DNS_TRANSPORT_TLS) { + isc_result_t result; + + result = dns_transport_get_tlsctx( + resp->transport, &resp->peer, resp->tlsctx_cache, + resp->disp->mgr->mctx, &tlsctx, &sess_cache); + + if (result != ISC_R_SUCCESS) { + return (result); + } + INSIST(tlsctx != NULL); + } + /* This will be detached once we've connected. */ dispentry_attach(resp, &(dns_dispentry_t *){ NULL }); - switch (disp->socktype) { - case isc_socktype_tcp: + switch (transport_type) { + case DNS_TRANSPORT_TCP: + case DNS_TRANSPORT_TLS: /* * Check whether the dispatch is already connecting * or connected. @@ -1815,9 +1865,17 @@ dns_dispatch_connect(dns_dispentry_t *resp) { ISC_LIST_APPEND(disp->pending, resp, plink); UNLOCK(&disp->lock); dns_dispatch_attach(disp, &(dns_dispatch_t *){ NULL }); - isc_nm_tcpdnsconnect(disp->mgr->nm, &disp->local, - &disp->peer, tcp_connected, disp, - resp->timeout); + if (transport_type == DNS_TRANSPORT_TLS) { + isc_nm_tlsdnsconnect( + disp->mgr->nm, &disp->local, + &disp->peer, tcp_connected, disp, + resp->timeout, tlsctx, sess_cache); + } else { + isc_nm_tcpdnsconnect(disp->mgr->nm, + &disp->local, &disp->peer, + tcp_connected, disp, + resp->timeout); + } break; case DNS_DISPATCHSTATE_CONNECTING: @@ -1841,7 +1899,7 @@ dns_dispatch_connect(dns_dispentry_t *resp) { break; - case isc_socktype_udp: + case DNS_TRANSPORT_UDP: isc_nm_udpconnect(disp->mgr->nm, &resp->local, &resp->peer, udp_connected, resp, resp->timeout); break; diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index b82a46c5a9..fff052cdd0 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -266,6 +266,7 @@ typedef void (*dispatch_cb_t)(isc_result_t eresult, isc_region_t *region, isc_result_t dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, unsigned int timeout, const isc_sockaddr_t *dest, + dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache, dispatch_cb_t connected, dispatch_cb_t sent, dispatch_cb_t response, void *arg, dns_messageid_t *idp, dns_dispentry_t **resp); diff --git a/lib/dns/include/dns/request.h b/lib/dns/include/dns/request.h index c454161a60..5f72aef76e 100644 --- a/lib/dns/include/dns/request.h +++ b/lib/dns/include/dns/request.h @@ -130,7 +130,8 @@ dns_requestmgr_detach(dns_requestmgr_t **requestmgrp); isc_result_t dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, const isc_sockaddr_t *srcaddr, - const isc_sockaddr_t *destaddr, isc_dscp_t dscp, + const isc_sockaddr_t *destaddr, dns_transport_t *transport, + isc_tlsctx_cache_t *tlsctx_cache, isc_dscp_t dscp, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, @@ -174,7 +175,9 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_result_t dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, const isc_sockaddr_t *srcaddr, - const isc_sockaddr_t *destaddr, isc_dscp_t dscp, + const isc_sockaddr_t *destaddr, + dns_transport_t *transport, + isc_tlsctx_cache_t *tlsctx_cache, isc_dscp_t dscp, unsigned int options, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, diff --git a/lib/dns/request.c b/lib/dns/request.c index 9e78d5b9c7..0a53f2b620 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M') @@ -407,7 +409,9 @@ get_dispatch(bool tcp, bool newtcp, dns_requestmgr_t *requestmgr, isc_result_t dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, const isc_sockaddr_t *srcaddr, - const isc_sockaddr_t *destaddr, isc_dscp_t dscp, + const isc_sockaddr_t *destaddr, + dns_transport_t *transport, + isc_tlsctx_cache_t *tlsctx_cache, isc_dscp_t dscp, unsigned int options, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, @@ -504,9 +508,9 @@ again: } result = dns_dispatch_add(request->dispatch, dispopt, request->timeout, - destaddr, req_connected, req_senddone, - req_response, request, &id, - &request->dispentry); + destaddr, transport, tlsctx_cache, + req_connected, req_senddone, req_response, + request, &id, &request->dispentry); if (result != ISC_R_SUCCESS) { if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) { newtcp = true; @@ -572,7 +576,8 @@ cleanup: isc_result_t dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, const isc_sockaddr_t *srcaddr, - const isc_sockaddr_t *destaddr, isc_dscp_t dscp, + const isc_sockaddr_t *destaddr, dns_transport_t *transport, + isc_tlsctx_cache_t *tlsctx_cache, isc_dscp_t dscp, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, @@ -659,9 +664,10 @@ again: goto detach; } - result = dns_dispatch_add( - request->dispatch, 0, request->timeout, destaddr, req_connected, - req_senddone, req_response, request, &id, &request->dispentry); + result = dns_dispatch_add(request->dispatch, 0, request->timeout, + destaddr, transport, tlsctx_cache, + req_connected, req_senddone, req_response, + request, &id, &request->dispentry); if (result != ISC_R_SUCCESS) { goto detach; } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index a22a68b097..8825948287 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2283,7 +2283,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, /* Set up the dispatch and set the query ID */ result = dns_dispatch_add( query->dispatch, 0, isc_interval_ms(&fctx->interval), - &query->addrinfo->sockaddr, resquery_connected, + &query->addrinfo->sockaddr, NULL, NULL, resquery_connected, resquery_senddone, resquery_response, query, &query->id, &query->dispentry); if (result != ISC_R_SUCCESS) { diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 08e140ca09..73a12b4772 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -12788,10 +12788,10 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) { timeout = 30; } - result = dns_request_create(notify->zone->view->requestmgr, message, - &src, ¬ify->dst, dscp, options, key, - timeout * 3, timeout, 2, notify->zone->task, - notify_done, notify, ¬ify->request); + result = dns_request_create( + notify->zone->view->requestmgr, message, &src, ¬ify->dst, + NULL, NULL, dscp, options, key, timeout * 3, timeout, 2, + notify->zone->task, notify_done, notify, ¬ify->request); if (result == ISC_R_SUCCESS) { if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { inc_stats(notify->zone, @@ -13498,7 +13498,7 @@ stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4, result = dns_request_create( zone->view->requestmgr, message, &zone->sourceaddr, - &zone->primaryaddr, args->dscp, DNS_REQUESTOPT_TCP, + &zone->primaryaddr, NULL, NULL, args->dscp, DNS_REQUESTOPT_TCP, args->tsig_key, args->timeout * 3, args->timeout, 2, zone->task, stub_glue_response_cb, request, &request->request); @@ -14741,8 +14741,8 @@ again: } result = dns_request_create( zone->view->requestmgr, message, &zone->sourceaddr, - &zone->primaryaddr, dscp, options, key, timeout * 3, timeout, 2, - zone->task, refresh_callback, zone, &zone->request); + &zone->primaryaddr, NULL, NULL, dscp, options, key, timeout * 3, + timeout, 2, zone->task, refresh_callback, zone, &zone->request); if (result != ISC_R_SUCCESS) { zone_idetach(&dummy); zone_debuglog(zone, __func__, 1, @@ -15024,10 +15024,11 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { cb_args->timeout = timeout; cb_args->reqnsid = reqnsid; - result = dns_request_create( - zone->view->requestmgr, message, &zone->sourceaddr, - &zone->primaryaddr, dscp, DNS_REQUESTOPT_TCP, key, timeout * 3, - timeout, 2, zone->task, stub_callback, cb_args, &zone->request); + result = dns_request_create(zone->view->requestmgr, message, + &zone->sourceaddr, &zone->primaryaddr, NULL, + NULL, dscp, DNS_REQUESTOPT_TCP, key, + timeout * 3, timeout, 2, zone->task, + stub_callback, cb_args, &zone->request); if (result != ISC_R_SUCCESS) { zone_debuglog(zone, __func__, 1, "dns_request_create() failed: %s", @@ -18292,11 +18293,11 @@ sendtoprimary(dns_forward_t *forward) { result = ISC_R_NOTIMPLEMENTED; goto unlock; } - result = dns_request_createraw(forward->zone->view->requestmgr, - forward->msgbuf, &src, &forward->addr, - dscp, forward->options, 15 /* XXX */, 0, - 0, forward->zone->task, forward_callback, - forward, &forward->request); + result = dns_request_createraw( + forward->zone->view->requestmgr, forward->msgbuf, &src, + &forward->addr, NULL, NULL, dscp, forward->options, + 15 /* XXX */, 0, 0, forward->zone->task, forward_callback, + forward, &forward->request); if (result == ISC_R_SUCCESS) { if (!ISC_LINK_LINKED(forward, link)) { ISC_LIST_APPEND(forward->zone->forwards, forward, link); @@ -21217,7 +21218,7 @@ checkds_send_toaddr(isc_task_t *task, isc_event_t *event) { options |= DNS_REQUESTOPT_TCP; result = dns_request_create( checkds->zone->view->requestmgr, message, &src, &checkds->dst, - dscp, options, key, timeout * 3, timeout, 2, + NULL, NULL, dscp, options, key, timeout * 3, timeout, 2, checkds->zone->task, checkds_done, checkds, &checkds->request); if (result != ISC_R_SUCCESS) { dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), diff --git a/tests/dns/dispatch_test.c b/tests/dns/dispatch_test.c index 0b910e4438..ed2c00d948 100644 --- a/tests/dns/dispatch_test.c +++ b/tests/dns/dispatch_test.c @@ -409,10 +409,10 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_connect) { assert_int_equal(result, ISC_R_SUCCESS); dns_dispatchmgr_detach(&dispatchmgr); - result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT, - &tcp_server_addr, timeout_connected, - client_senddone, response_timeout, - &testdata.region, &id, &dispentry); + result = dns_dispatch_add( + dispatch, 0, T_CLIENT_CONNECT, &tcp_server_addr, NULL, NULL, + timeout_connected, client_senddone, response_timeout, + &testdata.region, &id, &dispentry); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatch_detach(&dispatch); @@ -454,9 +454,9 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_response) { dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT, - &tcp_server_addr, connected, client_senddone, - response_timeout, &testdata.region, &id, - &dispentry); + &tcp_server_addr, NULL, NULL, connected, + client_senddone, response_timeout, + &testdata.region, &id, &dispentry); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatch_detach(&dispatch); @@ -488,8 +488,9 @@ ISC_LOOP_TEST_IMPL(dispatch_tcp_response) { dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT, - &tcp_server_addr, connected, client_senddone, - response, &testdata.region, &id, &dispentry); + &tcp_server_addr, NULL, NULL, connected, + client_senddone, response, &testdata.region, + &id, &dispentry); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatch_detach(&dispatch); @@ -521,9 +522,9 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_udp_response) { dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT, - &udp_server_addr, connected, client_senddone, - response_timeout, &testdata.region, &id, - &dispentry); + &udp_server_addr, NULL, NULL, connected, + client_senddone, response_timeout, + &testdata.region, &id, &dispentry); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatch_detach(&dispatch); @@ -555,9 +556,9 @@ ISC_LOOP_TEST_IMPL(dispatch_getnext) { dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT, - &udp_server_addr, connected, client_senddone, - response_getnext, &testdata.region, &id, - &dispentry); + &udp_server_addr, NULL, NULL, connected, + client_senddone, response_getnext, + &testdata.region, &id, &dispentry); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatch_detach(&dispatch); From 91a05950197cbb61ea111bbf8874c5fcacd27c54 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 19 Sep 2022 12:33:32 +0000 Subject: [PATCH 3/4] Test TLS transport in dispatch_test.c Add a new check in dispatch_test.c unit test to confirm that sending and receiving data using TLS transport works. --- tests/dns/dispatch_test.c | 86 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/dns/dispatch_test.c b/tests/dns/dispatch_test.c index ed2c00d948..16a104e032 100644 --- a/tests/dns/dispatch_test.c +++ b/tests/dns/dispatch_test.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,15 @@ static isc_sockaddr_t udp_server_addr; static isc_sockaddr_t udp_connect_addr; static isc_sockaddr_t tcp_server_addr; static isc_sockaddr_t tcp_connect_addr; +static isc_sockaddr_t tls_server_addr; +static isc_sockaddr_t tls_connect_addr; + +static isc_tlsctx_cache_t *tls_tlsctx_client_cache = NULL; +static isc_tlsctx_t *tls_listen_tlsctx = NULL; +static dns_name_t tls_name; +static const char *tls_name_str = "ephemeral"; +static dns_transport_t *tls_transport = NULL; +static dns_transport_list_t *transport_list = NULL; static dns_dispatchmgr_t *dispatchmgr = NULL; static dns_dispatch_t *dispatch = NULL; @@ -116,6 +126,9 @@ setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) { static int setup_test(void **state) { + isc_buffer_t namesrc, namebuf; + char namedata[DNS_NAME_FORMATSIZE + 1]; + uv_os_sock_t socket = -1; setup_loopmgr(state); @@ -129,6 +142,9 @@ setup_test(void **state) { tcp_connect_addr = (isc_sockaddr_t){ .length = 0 }; isc_sockaddr_fromin6(&tcp_connect_addr, &in6addr_loopback, 0); + tls_connect_addr = (isc_sockaddr_t){ .length = 0 }; + isc_sockaddr_fromin6(&tls_connect_addr, &in6addr_loopback, 0); + udp_server_addr = (isc_sockaddr_t){ .length = 0 }; socket = setup_ephemeral_port(&udp_server_addr, SOCK_DGRAM); if (socket < 0) { @@ -143,6 +159,13 @@ setup_test(void **state) { } close(socket); + tls_server_addr = (isc_sockaddr_t){ .length = 0 }; + socket = setup_ephemeral_port(&tls_server_addr, SOCK_STREAM); + if (socket < 0) { + return (-1); + } + close(socket); + isc_nm_settimeouts(netmgr, T_SERVER_INIT, T_SERVER_IDLE, T_SERVER_KEEPALIVE, T_SERVER_ADVERTISED); @@ -158,11 +181,36 @@ setup_test(void **state) { testdata.region.length = sizeof(testdata.rbuf); memset(testdata.message, 0, sizeof(testdata.message)); + tls_tlsctx_client_cache = isc_tlsctx_cache_new(mctx); + + if (isc_tlsctx_createserver(NULL, NULL, &tls_listen_tlsctx) != + ISC_R_SUCCESS) { + return (-1); + } + + dns_name_init(&tls_name, NULL); + isc_buffer_constinit(&namesrc, tls_name_str, strlen(tls_name_str)); + isc_buffer_add(&namesrc, strlen(tls_name_str)); + isc_buffer_init(&namebuf, namedata, sizeof(namedata)); + if (dns_name_fromtext(&tls_name, &namesrc, dns_rootname, + DNS_NAME_DOWNCASE, &namebuf) != ISC_R_SUCCESS) + { + return (-1); + } + transport_list = dns_transport_list_new(mctx); + tls_transport = dns_transport_new(&tls_name, DNS_TRANSPORT_TLS, + transport_list); + dns_transport_set_tlsname(tls_transport, tls_name_str); + return (0); } static int teardown_test(void **state) { + dns_transport_list_detach(&transport_list); + isc_tlsctx_cache_detach(&tls_tlsctx_client_cache); + isc_tlsctx_free(&tls_listen_tlsctx); + isc_netmgr_destroy(&connect_nm); teardown_netmgr(state); @@ -500,6 +548,43 @@ ISC_LOOP_TEST_IMPL(dispatch_tcp_response) { dns_dispatch_connect(dispentry); } +ISC_LOOP_TEST_IMPL(dispatch_tls_response) { + isc_result_t result; + uint16_t id; + + /* Server */ + result = isc_nm_listentlsdns( + netmgr, ISC_NM_LISTEN_ONE, &tls_server_addr, nameserver, NULL, + accept_cb, NULL, 0, NULL, tls_listen_tlsctx, &sock); + assert_int_equal(result, ISC_R_SUCCESS); + + isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); + + /* Client */ + testdata.region.base = testdata.message; + testdata.region.length = sizeof(testdata.message); + + result = dns_dispatchmgr_create(mctx, connect_nm, &dispatchmgr); + assert_int_equal(result, ISC_R_SUCCESS); + + result = dns_dispatch_createtcp(dispatchmgr, &tls_connect_addr, + &tls_server_addr, -1, &dispatch); + assert_int_equal(result, ISC_R_SUCCESS); + dns_dispatchmgr_detach(&dispatchmgr); + + result = dns_dispatch_add( + dispatch, 0, T_CLIENT_CONNECT, &tls_server_addr, tls_transport, + tls_tlsctx_client_cache, connected, client_senddone, response, + &testdata.region, &id, &dispentry); + assert_int_equal(result, ISC_R_SUCCESS); + dns_dispatch_detach(&dispatch); + + testdata.message[0] = (id >> 8) & 0xff; + testdata.message[1] = id & 0xff; + + dns_dispatch_connect(dispentry); +} + ISC_LOOP_TEST_IMPL(dispatch_timeout_udp_response) { isc_result_t result; uint16_t id; @@ -575,6 +660,7 @@ ISC_TEST_ENTRY_CUSTOM(dispatchset_get, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatch_timeout_tcp_response, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatch_timeout_tcp_connect, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatch_tcp_response, setup_test, teardown_test) +ISC_TEST_ENTRY_CUSTOM(dispatch_tls_response, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatch_getnext, setup_test, teardown_test) ISC_TEST_LIST_END From f113bc8142e85821edd4d62cff51da6991f1a71d Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 19 Sep 2022 14:14:50 +0000 Subject: [PATCH 4/4] Add CHANGES note for [GL #3529] --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index a72e8aefb9..443aefc743 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5975. [func] Implement TLS transport support for dns_request and + dns_dispatch. [GL #3529] + 5974. [bug] Fix an assertion failure in dispatch caused by extra read callback call. [GL #3545]