diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index efe4837e91..09b677e87b 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -3041,7 +3041,7 @@ start_tcp(dig_query_t *query) { } isc_nm_streamdnsconnect(netmgr, &localaddr, &query->sockaddr, tcp_connected, connectquery, - local_timeout, tlsctx, sess_cache, + local_timeout, tlsctx, NULL, sess_cache, proxy_type, ppi); #if HAVE_LIBNGHTTP2 } else if (query->lookup->https_mode) { @@ -3061,14 +3061,14 @@ start_tcp(dig_query_t *query) { isc_nm_httpconnect(netmgr, &localaddr, &query->sockaddr, uri, !query->lookup->https_get, tcp_connected, - connectquery, tlsctx, sess_cache, + connectquery, tlsctx, NULL, sess_cache, local_timeout, proxy_type, ppi); #endif } else { isc_nm_streamdnsconnect(netmgr, &localaddr, &query->sockaddr, tcp_connected, connectquery, - local_timeout, NULL, NULL, proxy_type, - ppi); + local_timeout, NULL, NULL, NULL, + proxy_type, ppi); } return; diff --git a/bin/tests/test_client.c b/bin/tests/test_client.c index 2787b3d990..25a341d177 100644 --- a/bin/tests/test_client.c +++ b/bin/tests/test_client.c @@ -378,16 +378,18 @@ run(void) { connect_cb, NULL, timeout); break; case TCP: - isc_nm_streamdnsconnect( - netmgr, &sockaddr_local, &sockaddr_remote, connect_cb, - NULL, timeout, NULL, NULL, ISC_NM_PROXY_NONE, NULL); + isc_nm_streamdnsconnect(netmgr, &sockaddr_local, + &sockaddr_remote, connect_cb, NULL, + timeout, NULL, NULL, NULL, + ISC_NM_PROXY_NONE, NULL); break; case DOT: { isc_tlsctx_createclient(&tls_ctx); - isc_nm_streamdnsconnect( - netmgr, &sockaddr_local, &sockaddr_remote, connect_cb, - NULL, timeout, tls_ctx, NULL, ISC_NM_PROXY_NONE, NULL); + isc_nm_streamdnsconnect(netmgr, &sockaddr_local, + &sockaddr_remote, connect_cb, NULL, + timeout, tls_ctx, NULL, NULL, + ISC_NM_PROXY_NONE, NULL); break; } #if HAVE_LIBNGHTTP2 @@ -408,7 +410,8 @@ run(void) { } isc_nm_httpconnect(netmgr, &sockaddr_local, &sockaddr_remote, req_url, is_post, connect_cb, NULL, tls_ctx, - NULL, timeout, ISC_NM_PROXY_NONE, NULL); + NULL, NULL, timeout, ISC_NM_PROXY_NONE, + NULL); } break; #endif default: diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 0e33870229..74080270ac 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -2007,7 +2007,7 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { isc_nm_streamdnsconnect(disp->mgr->nm, &disp->local, &disp->peer, tcp_connected, disp, - resp->timeout, tlsctx, sess_cache, + resp->timeout, tlsctx, NULL, sess_cache, ISC_NM_PROXY_NONE, NULL); break; diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 21babdebad..887e256519 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -494,6 +494,7 @@ void isc_nm_proxystreamconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, isc_nm_cb_t cb, void *cbarg, unsigned int timeout, isc_tlsctx_t *tlsctx, + const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, isc_nm_proxyheader_info_t *proxy_info); /*%< @@ -616,6 +617,7 @@ void isc_nm_streamdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, isc_nm_cb_t cb, void *cbarg, unsigned int timeout, isc_tlsctx_t *tlsctx, + const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, isc_nm_proxy_type_t proxy_type, isc_nm_proxyheader_info_t *proxy_info); @@ -672,7 +674,7 @@ isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface, void isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, isc_nm_cb_t connect_cb, void *connect_cbarg, - isc_tlsctx_t *ctx, + isc_tlsctx_t *ctx, const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, unsigned int timeout, bool proxy, isc_nm_proxyheader_info_t *proxy_info); @@ -684,7 +686,7 @@ isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, void isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, const char *uri, bool POST, isc_nm_cb_t cb, void *cbarg, - isc_tlsctx_t *ctx, + isc_tlsctx_t *ctx, const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, unsigned int timeout, isc_nm_proxy_type_t proxy_type, isc_nm_proxyheader_info_t *proxy_info); diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c index 9d153a0f2e..9fd1097f1f 100644 --- a/lib/isc/netmgr/http.c +++ b/lib/isc/netmgr/http.c @@ -1464,7 +1464,7 @@ error: void isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, const char *uri, bool post, isc_nm_cb_t cb, void *cbarg, - isc_tlsctx_t *tlsctx, + isc_tlsctx_t *tlsctx, const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, unsigned int timeout, isc_nm_proxy_type_t proxy_type, isc_nm_proxyheader_info_t *proxy_info) { @@ -1535,8 +1535,8 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, if (tlsctx != NULL) { isc_nm_tlsconnect(mgr, local, peer, transport_connect_cb, sock, tlsctx, - client_sess_cache, timeout, false, - NULL); + sni_hostname, client_sess_cache, + timeout, false, NULL); } else { isc_nm_tcpconnect(mgr, local, peer, transport_connect_cb, sock, timeout); @@ -1546,19 +1546,19 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, if (tlsctx != NULL) { isc_nm_tlsconnect(mgr, local, peer, transport_connect_cb, sock, tlsctx, - client_sess_cache, timeout, true, - proxy_info); + sni_hostname, client_sess_cache, + timeout, true, proxy_info); } else { isc_nm_proxystreamconnect( mgr, local, peer, transport_connect_cb, sock, - timeout, NULL, NULL, proxy_info); + timeout, NULL, NULL, NULL, proxy_info); } break; case ISC_NM_PROXY_ENCRYPTED: INSIST(tlsctx != NULL); isc_nm_proxystreamconnect( mgr, local, peer, transport_connect_cb, sock, timeout, - tlsctx, client_sess_cache, proxy_info); + tlsctx, sni_hostname, client_sess_cache, proxy_info); break; default: UNREACHABLE(); diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index c7f721b2a0..d790590ec4 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -516,6 +516,7 @@ struct isc_nmsocket { isc_tlsctx_t **listener_tls_ctx; /*%< A context reference per worker */ size_t n_listener_tls_ctx; + char *sni_hostname; isc_tlsctx_client_session_cache_t *client_sess_cache; bool client_session_saved; isc_nmsocket_t *tlslistener; diff --git a/lib/isc/netmgr/proxystream.c b/lib/isc/netmgr/proxystream.c index ab1eb5c7fe..883e8cf942 100644 --- a/lib/isc/netmgr/proxystream.c +++ b/lib/isc/netmgr/proxystream.c @@ -459,6 +459,7 @@ void isc_nm_proxystreamconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, isc_nm_cb_t cb, void *cbarg, unsigned int timeout, isc_tlsctx_t *tlsctx, + const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, isc_nm_proxyheader_info_t *proxy_info) { isc_result_t result = ISC_R_FAILURE; @@ -501,8 +502,9 @@ isc_nm_proxystreamconnect(isc_nm_t *mgr, isc_sockaddr_t *local, nsock, nsock->connect_timeout); } else { isc_nm_tlsconnect(mgr, local, peer, proxystream_connect_cb, - nsock, tlsctx, client_sess_cache, - nsock->connect_timeout, false, NULL); + nsock, tlsctx, sni_hostname, + client_sess_cache, nsock->connect_timeout, + false, NULL); } } diff --git a/lib/isc/netmgr/streamdns.c b/lib/isc/netmgr/streamdns.c index d2cd1325f3..30b3903986 100644 --- a/lib/isc/netmgr/streamdns.c +++ b/lib/isc/netmgr/streamdns.c @@ -387,6 +387,7 @@ void isc_nm_streamdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, isc_nm_cb_t cb, void *cbarg, unsigned int timeout, isc_tlsctx_t *tlsctx, + const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, isc_nm_proxy_type_t proxy_type, isc_nm_proxyheader_info_t *proxy_info) { @@ -418,7 +419,7 @@ isc_nm_streamdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, } else { isc_nm_tlsconnect( mgr, local, peer, streamdns_transport_connected, - nsock, tlsctx, client_sess_cache, + nsock, tlsctx, sni_hostname, client_sess_cache, nsock->connect_timeout, false, proxy_info); } break; @@ -427,20 +428,20 @@ isc_nm_streamdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_nm_proxystreamconnect(mgr, local, peer, streamdns_transport_connected, nsock, nsock->connect_timeout, - NULL, NULL, proxy_info); + NULL, NULL, NULL, proxy_info); } else { isc_nm_tlsconnect( mgr, local, peer, streamdns_transport_connected, - nsock, tlsctx, client_sess_cache, + nsock, tlsctx, sni_hostname, client_sess_cache, nsock->connect_timeout, true, proxy_info); } break; case ISC_NM_PROXY_ENCRYPTED: INSIST(tlsctx != NULL); - isc_nm_proxystreamconnect(mgr, local, peer, - streamdns_transport_connected, nsock, - nsock->connect_timeout, tlsctx, - client_sess_cache, proxy_info); + isc_nm_proxystreamconnect( + mgr, local, peer, streamdns_transport_connected, nsock, + nsock->connect_timeout, tlsctx, sni_hostname, + client_sess_cache, proxy_info); break; default: UNREACHABLE(); diff --git a/lib/isc/netmgr/tlsstream.c b/lib/isc/netmgr/tlsstream.c index c045ebe96d..c599600f10 100644 --- a/lib/isc/netmgr/tlsstream.c +++ b/lib/isc/netmgr/tlsstream.c @@ -868,6 +868,14 @@ initialize_tls(isc_nmsocket_t *sock, bool server) { sock->tlsstream.server = server; sock->tlsstream.nsending = 0; sock->tlsstream.state = TLS_INIT; + if (sock->tlsstream.sni_hostname != NULL) { + INSIST(sock->client); + const int ret = SSL_set_tlsext_host_name( + sock->tlsstream.tls, sock->tlsstream.sni_hostname); + if (ret != 1) { + goto error; + } + } return ISC_R_SUCCESS; error: isc_tls_free(&sock->tlsstream.tls); @@ -1201,7 +1209,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg); void isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, isc_nm_cb_t connect_cb, void *connect_cbarg, - isc_tlsctx_t *ctx, + isc_tlsctx_t *ctx, const char *sni_hostname, isc_tlsctx_client_session_cache_t *client_sess_cache, unsigned int timeout, bool proxy, isc_nm_proxyheader_info_t *proxy_info) { @@ -1223,6 +1231,10 @@ isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, sock->connect_cbarg = connect_cbarg; sock->connect_timeout = timeout; isc_tlsctx_attach(ctx, &sock->tlsstream.ctx); + if (sni_hostname != NULL) { + sock->tlsstream.sni_hostname = + isc_mem_strdup(sock->worker->mctx, sni_hostname); + } sock->client = true; if (client_sess_cache != NULL) { INSIST(isc_tlsctx_client_session_cache_getctx( @@ -1234,7 +1246,7 @@ isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, if (proxy) { isc_nm_proxystreamconnect(mgr, local, peer, tcp_connected, sock, sock->connect_timeout, NULL, NULL, - proxy_info); + NULL, proxy_info); } else { isc_nm_tcpconnect(mgr, local, peer, tcp_connected, sock, sock->connect_timeout); @@ -1334,6 +1346,10 @@ isc__nm_tls_cleanup_data(isc_nmsocket_t *sock) { if (sock->tlsstream.ctx != NULL) { isc_tlsctx_free(&sock->tlsstream.ctx); } + if (sock->tlsstream.sni_hostname != NULL) { + isc_mem_free(sock->worker->mctx, + sock->tlsstream.sni_hostname); + } if (sock->tlsstream.client_sess_cache != NULL) { INSIST(sock->client); isc_tlsctx_client_session_cache_detach( diff --git a/tests/isc/doh_test.c b/tests/isc/doh_test.c index d9001468bc..339f4559d1 100644 --- a/tests/isc/doh_test.c +++ b/tests/isc/doh_test.c @@ -213,7 +213,7 @@ connect_send_request(isc_nm_t *mgr, const char *uri, bool post, } isc_nm_httpconnect(mgr, NULL, &tcp_listen_addr, uri, post, - connect_send_cb, data, ctx, client_sess_cache, + connect_send_cb, data, ctx, NULL, client_sess_cache, timeout, get_proxy_type(), NULL); } @@ -698,7 +698,7 @@ doh_timeout_recovery(void *arg ISC_ATTR_UNUSED) { ISC_NM_HTTP_DEFAULT_PATH); isc_nm_httpconnect(connect_nm, NULL, &tcp_listen_addr, req_url, atomic_load(&POST), timeout_request_cb, NULL, ctx, - client_sess_cache, T_CONNECT, get_proxy_type(), + NULL, client_sess_cache, T_CONNECT, get_proxy_type(), NULL); } @@ -947,8 +947,8 @@ doh_recv_two(void *arg ISC_ATTR_UNUSED) { isc_nm_httpconnect(connect_nm, NULL, &tcp_listen_addr, req_url, atomic_load(&POST), doh_connect_send_two_requests_cb, - NULL, ctx, client_sess_cache, 5000, get_proxy_type(), - NULL); + NULL, ctx, NULL, client_sess_cache, 5000, + get_proxy_type(), NULL); isc_loop_teardown(mainloop, listen_sock_close, listen_sock); } diff --git a/tests/isc/netmgr_common.c b/tests/isc/netmgr_common.c index bf7a31d400..7372af4ab0 100644 --- a/tests/isc/netmgr_common.c +++ b/tests/isc/netmgr_common.c @@ -595,7 +595,7 @@ tcp_connect(isc_nm_t *nm) { static void tls_connect(isc_nm_t *nm) { isc_nm_tlsconnect(nm, &tcp_connect_addr, &tcp_listen_addr, - connect_connect_cb, NULL, tcp_connect_tlsctx, + connect_connect_cb, NULL, tcp_connect_tlsctx, NULL, tcp_tlsctx_client_sess_cache, T_CONNECT, stream_use_PROXY, NULL); } @@ -631,7 +631,7 @@ proxystream_connect(isc_nm_t *nm) { isc_nm_proxystreamconnect(nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb, NULL, T_CONNECT, tlsctx, - sess_cache, get_proxyheader_info()); + NULL, sess_cache, get_proxyheader_info()); } stream_connect_function @@ -680,10 +680,11 @@ stream_connect(isc_nm_cb_t cb, void *cbarg, unsigned int timeout) { isc_refcount_increment0(&active_cconnects); if (stream_use_TLS && !stream_PROXY_over_TLS) { - isc_nm_tlsconnect( - connect_nm, &tcp_connect_addr, &tcp_listen_addr, cb, - cbarg, tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache, - timeout, stream_use_PROXY, NULL); + isc_nm_tlsconnect(connect_nm, &tcp_connect_addr, + &tcp_listen_addr, cb, cbarg, + tcp_connect_tlsctx, NULL, + tcp_tlsctx_client_sess_cache, timeout, + stream_use_PROXY, NULL); return; } else if (stream_use_PROXY) { isc_tlsctx_t *tlsctx = stream_PROXY_over_TLS @@ -694,7 +695,7 @@ stream_connect(isc_nm_cb_t cb, void *cbarg, unsigned int timeout) { : NULL; isc_nm_proxystreamconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr, cb, cbarg, timeout, - tlsctx, sess_cache, + tlsctx, NULL, sess_cache, get_proxyheader_info()); return; } else { diff --git a/tests/isc/tcpdns_test.c b/tests/isc/tcpdns_test.c index 0d3b76d22d..f2d3eed9dd 100644 --- a/tests/isc/tcpdns_test.c +++ b/tests/isc/tcpdns_test.c @@ -63,7 +63,7 @@ static void tcpdns_connect(isc_nm_t *nm) { isc_nm_streamdnsconnect(nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb, tcpdns_connect, T_CONNECT, - NULL, NULL, get_proxy_type(), NULL); + NULL, NULL, NULL, get_proxy_type(), NULL); } ISC_LOOP_TEST_IMPL(tcpdns_noop) { @@ -73,7 +73,7 @@ ISC_LOOP_TEST_IMPL(tcpdns_noop) { isc_refcount_increment0(&active_cconnects); isc_nm_streamdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr, connect_success_cb, tcpdns_connect, T_CONNECT, - NULL, NULL, get_proxy_type(), NULL); + NULL, NULL, NULL, get_proxy_type(), NULL); } ISC_LOOP_TEST_IMPL(tcpdns_noresponse) { @@ -82,7 +82,7 @@ ISC_LOOP_TEST_IMPL(tcpdns_noresponse) { isc_refcount_increment0(&active_cconnects); isc_nm_streamdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb, tcpdns_connect, T_CONNECT, - NULL, NULL, get_proxy_type(), NULL); + NULL, NULL, NULL, get_proxy_type(), NULL); } ISC_LOOP_TEST_IMPL(tcpdns_timeout_recovery) { diff --git a/tests/isc/tlsdns_test.c b/tests/isc/tlsdns_test.c index d2b290f070..e8da5b04fd 100644 --- a/tests/isc/tlsdns_test.c +++ b/tests/isc/tlsdns_test.c @@ -63,7 +63,7 @@ static void tlsdns_connect(isc_nm_t *nm) { isc_nm_streamdnsconnect( nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb, - tlsdns_connect, T_CONNECT, tcp_connect_tlsctx, + tlsdns_connect, T_CONNECT, tcp_connect_tlsctx, NULL, tcp_tlsctx_client_sess_cache, get_proxy_type(), NULL); } @@ -74,7 +74,7 @@ ISC_LOOP_TEST_IMPL(tlsdns_noop) { isc_refcount_increment0(&active_cconnects); isc_nm_streamdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr, connect_success_cb, tlsdns_connect, T_CONNECT, - tcp_connect_tlsctx, + tcp_connect_tlsctx, NULL, tcp_tlsctx_client_sess_cache, get_proxy_type(), NULL); } @@ -85,7 +85,7 @@ ISC_LOOP_TEST_IMPL(tlsdns_noresponse) { isc_refcount_increment0(&active_cconnects); isc_nm_streamdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb, tlsdns_connect, T_CONNECT, - tcp_connect_tlsctx, + tcp_connect_tlsctx, NULL, tcp_tlsctx_client_sess_cache, get_proxy_type(), NULL); } @@ -109,7 +109,7 @@ ISC_LOOP_TEST_IMPL(tlsdns_timeout_recovery) { isc_nm_streamdnsconnect( connect_nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb, tlsdns_connect, T_SOFT, tcp_connect_tlsctx, - tcp_tlsctx_client_sess_cache, get_proxy_type(), NULL); + NULL, tcp_tlsctx_client_sess_cache, get_proxy_type(), NULL); } ISC_LOOP_TEST_IMPL(tlsdns_recv_one) {