isc_sockaddr_t local; /*%< local address */
isc_sockaddr_t peer; /*%< peer address (TCP) */
+ dns_dispatchopt_t options;
dns_dispatchstate_t state;
bool reading;
isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
- const isc_sockaddr_t *destaddr, dns_dispatch_t **dispp) {
+ const isc_sockaddr_t *destaddr,
+ dns_dispatchopt_t options, dns_dispatch_t **dispp) {
dns_dispatch_t *disp = NULL;
uint32_t tid = isc_tid();
dispatch_allocate(mgr, isc_socktype_tcp, tid, &disp);
+ disp->options = options;
disp->peer = *destaddr;
if (localaddr != NULL) {
.peer = &disp->peer,
};
- rcu_read_lock();
- cds_lfht_add(mgr->tcps[tid], dispatch_hash(&key), &disp->ht_node);
- rcu_read_unlock();
+ if ((disp->options & DNS_DISPATCHOPT_UNSHARED) == 0) {
+ rcu_read_lock();
+ cds_lfht_add(mgr->tcps[tid], dispatch_hash(&key),
+ &disp->ht_node);
+ rcu_read_unlock();
+ }
if (isc_log_wouldlog(dns_lctx, 90)) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
disp->magic = 0;
- if (disp->socktype == isc_socktype_tcp) {
+ if (disp->socktype == isc_socktype_tcp &&
+ (disp->options & DNS_DISPATCHOPT_UNSHARED) == 0)
+ {
(void)cds_lfht_del(mgr->tcps[tid], &disp->ht_node);
}
#endif
isc_result_t
-dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, 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 **respp) {
+dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop,
+ dns_dispatchopt_t 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 **respp) {
REQUIRE(VALID_DISPATCH(disp));
REQUIRE(dest != NULL);
REQUIRE(respp != NULL && *respp == NULL);
uint32_t ndisp;
};
-/*
- */
-#define DNS_DISPATCHOPT_FIXEDID 0x00000001U
+typedef enum dns_dispatchopt {
+ DNS_DISPATCHOPT_FIXEDID = 1 << 0,
+ DNS_DISPATCHOPT_UNSHARED = 1 << 1, /* Don't share this connection */
+} dns_dispatchopt_t;
isc_result_t
dns_dispatchmgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
- const isc_sockaddr_t *destaddr, dns_dispatch_t **dispp);
+ const isc_sockaddr_t *destaddr,
+ dns_dispatchopt_t options, dns_dispatch_t **dispp);
/*%<
* Create a new TCP dns_dispatch.
*
void *cbarg);
isc_result_t
-dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, 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);
+dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop,
+ dns_dispatchopt_t 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);
/*%<
* Add a response entry for this dispatch.
*
}
result = dns_dispatch_createtcp(requestmgr->dispatchmgr, srcaddr,
- destaddr, dispatchp);
+ destaddr, 0, dispatchp);
return (result);
}
}
isc_sockaddr_setport(&addr, 0);
- result = dns_dispatch_createtcp(res->view->dispatchmgr, &addr,
- &sockaddr, &query->dispatch);
+ result = dns_dispatch_createtcp(
+ res->view->dispatchmgr, &addr, &sockaddr,
+ DNS_DISPATCHOPT_UNSHARED, &query->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup_query;
}
dns_xfrin_ref(xfr);
- /*
- * Reuse an existing TCP connection if possible. For XoT, we can't
- * do this because other connections could be using a different
- * certificate, so we just create a new dispatch every time.
- */
- if (xfr->disp == NULL &&
- (xfr->transport == NULL ||
- dns_transport_get_type(xfr->transport) == DNS_TRANSPORT_TCP))
- {
- dns_dispatchmgr_t *dispmgr = dns_view_getdispatchmgr(xfr->view);
- if (dispmgr == NULL) {
- result = ISC_R_SHUTTINGDOWN;
- } else {
- result = dns_dispatch_gettcp(dispmgr, &xfr->primaryaddr,
- &xfr->sourceaddr,
- &xfr->disp);
- dns_dispatchmgr_detach(&dispmgr);
- }
- }
- if (result == ISC_R_SUCCESS) {
- char peer[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_format(&xfr->primaryaddr, peer, sizeof(peer));
- xfrin_log(xfr, ISC_LOG_DEBUG(1),
- "attached to TCP connection to %s", peer);
- } else if (xfr->disp == NULL) {
- dns_dispatchmgr_t *dispmgr = dns_view_getdispatchmgr(xfr->view);
- if (dispmgr == NULL) {
- result = ISC_R_SHUTTINGDOWN;
- } else {
- result = dns_dispatch_createtcp(
- dispmgr, &xfr->sourceaddr, &xfr->primaryaddr,
- &xfr->disp);
- dns_dispatchmgr_detach(&dispmgr);
- }
- CHECK(result);
- }
-
/* If this is a retry, we need to cancel the previous dispentry */
- if (xfr->dispentry != NULL) {
- dns_dispatch_done(&xfr->dispentry);
+ xfrin_cancelio(xfr);
+
+ dns_dispatchmgr_t *dispmgr = dns_view_getdispatchmgr(xfr->view);
+ if (dispmgr == NULL) {
+ result = ISC_R_SHUTTINGDOWN;
+ goto failure;
+ } else {
+ result = dns_dispatch_createtcp(
+ dispmgr, &xfr->sourceaddr, &xfr->primaryaddr,
+ DNS_DISPATCHOPT_UNSHARED, &xfr->disp);
+ dns_dispatchmgr_detach(&dispmgr);
+ if (result != ISC_R_SUCCESS) {
+ goto failure;
+ }
}
LIBDNS_XFRIN_START(xfr, xfr->info);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatch_createtcp(dispatchmgr, &tcp_connect_addr,
- &tcp_server_addr, &dispatch);
+ &tcp_server_addr, 0, &dispatch);
assert_int_equal(result, ISC_R_SUCCESS);
dns_dispatchmgr_detach(&dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatch_createtcp(dispatchmgr, &tcp_connect_addr,
- &tcp_server_addr, &dispatch);
+ &tcp_server_addr, 0, &dispatch);
assert_int_equal(result, ISC_R_SUCCESS);
dns_dispatchmgr_detach(&dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatch_createtcp(dispatchmgr, &tcp_connect_addr,
- &tcp_server_addr, &dispatch);
+ &tcp_server_addr, 0, &dispatch);
assert_int_equal(result, ISC_R_SUCCESS);
dns_dispatchmgr_detach(&dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_dispatch_createtcp(dispatchmgr, &tls_connect_addr,
- &tls_server_addr, &dispatch);
+ &tls_server_addr, 0, &dispatch);
assert_int_equal(result, ISC_R_SUCCESS);
dns_dispatchmgr_detach(&dispatchmgr);