mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 08:50:00 -04:00
Merge branch '3529-tls-transport-support-in-dns_request-and-dns_dispatch' into 'main'
Resolve "Implement TLS transport support for dns_request" Closes #3529 See merge request isc-projects/bind9!6751
This commit is contained in:
commit
b574904041
17 changed files with 478 additions and 292 deletions
3
CHANGES
3
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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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:");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <isc/stats.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/time.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
|
|
@ -37,6 +38,7 @@
|
|||
#include <dns/log.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/stats.h>
|
||||
#include <dns/transport.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <dns/name.h>
|
||||
#include <isc/tls.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <isc/result.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
|
|
@ -33,6 +34,7 @@
|
|||
#include <dns/rdata.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/request.h>
|
||||
#include <dns/transport.h>
|
||||
#include <dns/tsig.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@
|
|||
|
||||
#include <isc/list.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/name.h>
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
214
lib/dns/xfrin.c
214
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <isc/buffer.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/uv.h>
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -409,10 +457,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 +502,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 +536,46 @@ 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);
|
||||
|
||||
testdata.message[0] = (id >> 8) & 0xff;
|
||||
testdata.message[1] = id & 0xff;
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -521,9 +607,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 +641,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);
|
||||
|
||||
|
|
@ -574,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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue