CHECK(isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE, &addr,
ns_client_request, ifp, accept_cb, ifp, 10,
- NULL, NULL, &ifp->tcplistensocket));
+ NULL, NULL, false, &ifp->tcplistensocket));
ifp->flags |= NS_INTERFACEFLAG_LISTENING;
isc_async_current(loopmgr, sendquery, ifp->tcplistensocket);
}
isc_nm_streamdnsconnect(netmgr, &localaddr, &query->sockaddr,
tcp_connected, connectquery,
- local_timeout, tlsctx, sess_cache);
+ local_timeout, tlsctx, sess_cache,
+ false, NULL);
#if HAVE_LIBNGHTTP2
} else if (query->lookup->https_mode) {
char uri[4096] = { 0 };
} else {
isc_nm_streamdnsconnect(netmgr, &localaddr, &query->sockaddr,
tcp_connected, connectquery,
- local_timeout, NULL, NULL);
+ local_timeout, NULL, NULL, false, NULL);
}
return;
case TCP:
isc_nm_streamdnsconnect(netmgr, &sockaddr_local,
&sockaddr_remote, connect_cb, NULL,
- timeout, NULL, NULL);
+ timeout, NULL, NULL, false, NULL);
break;
case DOT: {
isc_tlsctx_createclient(&tls_ctx);
isc_nm_streamdnsconnect(netmgr, &sockaddr_local,
&sockaddr_remote, connect_cb, NULL,
- timeout, tls_ctx, NULL);
+ timeout, tls_ctx, NULL, false, NULL);
break;
}
#if HAVE_LIBNGHTTP2
case TCP:
result = isc_nm_listenstreamdns(
netmgr, ISC_NM_LISTEN_ALL, &sockaddr, read_cb, NULL,
- accept_cb, NULL, 0, NULL, NULL, &sock);
+ accept_cb, NULL, 0, NULL, NULL, false, &sock);
break;
case DOT: {
isc_tlsctx_createserver(NULL, NULL, &tls_ctx);
result = isc_nm_listenstreamdns(
netmgr, ISC_NM_LISTEN_ALL, &sockaddr, read_cb, NULL,
- accept_cb, NULL, 0, NULL, tls_ctx, &sock);
+ accept_cb, NULL, 0, NULL, tls_ctx, false, &sock);
break;
}
#if HAVE_LIBNGHTTP2
"connecting from %s to %s, timeout %u", localbuf,
peerbuf, resp->timeout);
- isc_nm_streamdnsconnect(disp->mgr->nm, &disp->local,
- &disp->peer, tcp_connected, disp,
- resp->timeout, tlsctx, sess_cache);
+ isc_nm_streamdnsconnect(
+ disp->mgr->nm, &disp->local, &disp->peer, tcp_connected,
+ disp, resp->timeout, tlsctx, sess_cache, false, NULL);
break;
case DNS_DISPATCHSTATE_CONNECTING:
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
int backlog, isc_quota_t *quota, isc_tlsctx_t *tlsctx,
- isc_nmsocket_t **sockp);
+ bool proxy, isc_nmsocket_t **sockp);
/*%<
* Start listening for DNS messages over the TCP interface 'iface', using
* net manager 'mgr'.
* Passing a non-NULL value as 'tlsctx' instructs the underlying code
* to create a DNS over TLS listener.
*
+ * Passing 'proxy == true' instruct the code that a PROXY header is
+ * sent before any data after the connection is accepted.
+ *
* 'quota' is passed to isc_nm_listentcp() when opening the raw TCP socket.
*/
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 *sslctx,
- isc_tlsctx_client_session_cache_t *client_sess_cache);
+ isc_tlsctx_client_session_cache_t *client_sess_cache,
+ bool proxy, isc_nm_proxyheader_info_t *proxy_info);
/*%<
* Establish a DNS client connection via a TCP or TLS connection, bound to
* the address 'local' and connected to the address 'peer'.
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 *ctx,
- isc_tlsctx_client_session_cache_t *client_sess_cache) {
+ isc_tlsctx_client_session_cache_t *client_sess_cache,
+ bool proxy, isc_nm_proxyheader_info_t *proxy_info) {
isc_nmsocket_t *nsock = NULL;
isc__networker_t *worker = NULL;
nsock->connect_cbarg = cbarg;
nsock->connect_timeout = timeout;
- if (ctx == NULL) {
+ if (ctx == NULL && !proxy) {
INSIST(client_sess_cache == NULL);
isc_nm_tcpconnect(mgr, local, peer,
streamdns_transport_connected, nsock,
nsock->connect_timeout);
+ } else if (ctx == NULL && proxy) {
+ INSIST(client_sess_cache == NULL);
+ isc_nm_proxystreamconnect(mgr, local, peer,
+ streamdns_transport_connected, nsock,
+ nsock->connect_timeout, proxy_info);
} else {
isc_nm_tlsconnect(mgr, local, peer,
streamdns_transport_connected, nsock, ctx,
client_sess_cache, nsock->connect_timeout,
- false, NULL);
+ proxy, proxy_info);
}
}
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
int backlog, isc_quota_t *quota, isc_tlsctx_t *tlsctx,
- isc_nmsocket_t **sockp) {
+ bool proxy, isc_nmsocket_t **sockp) {
isc_result_t result;
isc_nmsocket_t *listener = NULL;
isc__networker_t *worker = NULL;
listener->recv_cb = recv_cb;
listener->recv_cbarg = recv_cbarg;
- if (tlsctx == NULL) {
+ if (tlsctx == NULL && !proxy) {
result = isc_nm_listentcp(mgr, workers, iface,
streamdns_accept_cb, listener,
backlog, quota, &listener->outer);
+ } else if (tlsctx == NULL && proxy) {
+ result = isc_nm_listenproxystream(
+ mgr, workers, iface, streamdns_accept_cb, listener,
+ backlog, quota, &listener->outer);
} else {
result = isc_nm_listentls(
mgr, workers, iface, streamdns_accept_cb, listener,
- backlog, quota, tlsctx, false, &listener->outer);
+ backlog, quota, tlsctx, proxy, &listener->outer);
}
if (result != ISC_R_SUCCESS) {
listener->closed = true;
break;
case isc_nm_tlslistener:
case isc_nm_tcplistener:
+ case isc_nm_proxystreamlistener:
if (sock->streamdns.listener != NULL) {
isc__nmsocket_detach(&sock->streamdns.listener);
}
break;
case isc_nm_tlssocket:
case isc_nm_tcpsocket:
+ case isc_nm_proxystreamsocket:
if (sock->streamdns.sock != NULL) {
isc__nmsocket_detach(&sock->streamdns.sock);
}
result = isc_nm_listenstreamdns(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
- &ifp->mgr->sctx->tcpquota, NULL, &ifp->tcplistensocket);
+ &ifp->mgr->sctx->tcpquota, NULL, false, &ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
"creating TCP socket: %s",
result = isc_nm_listenstreamdns(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
- &ifp->mgr->sctx->tcpquota, sslctx, &ifp->tcplistensocket);
+ &ifp->mgr->sctx->tcpquota, sslctx, false,
+ &ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
*test = (test_dispatch_t){ 0 };
/* Server */
- result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE,
- &tcp_server_addr, noop_nameserver, NULL,
- accept_cb, NULL, 0, NULL, NULL, &sock);
+ result = isc_nm_listenstreamdns(
+ netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, noop_nameserver,
+ NULL, accept_cb, NULL, 0, NULL, NULL, false, &sock);
assert_int_equal(result, ISC_R_SUCCESS);
/* ensure we stop listening after the test is done */
*test = (test_dispatch_t){ 0 };
/* Server */
- result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE,
- &tcp_server_addr, nameserver, NULL,
- accept_cb, NULL, 0, NULL, NULL, &sock);
+ result = isc_nm_listenstreamdns(
+ netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, nameserver, NULL,
+ accept_cb, NULL, 0, NULL, NULL, false, &sock);
assert_int_equal(result, ISC_R_SUCCESS);
isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock);
/* Server */
result = isc_nm_listenstreamdns(
netmgr, ISC_NM_LISTEN_ONE, &tls_server_addr, nameserver, NULL,
- accept_cb, NULL, 0, NULL, tls_listen_tlsctx, &sock);
+ accept_cb, NULL, 0, NULL, tls_listen_tlsctx, false, &sock);
assert_int_equal(result, ISC_R_SUCCESS);
isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock);
*test = (test_dispatch_t){ 0 };
/* Server */
- result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE,
- &tcp_server_addr, nameserver, NULL,
- accept_cb, NULL, 0, NULL, NULL, &sock);
+ result = isc_nm_listenstreamdns(
+ netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, nameserver, NULL,
+ accept_cb, NULL, 0, NULL, NULL, false, &sock);
assert_int_equal(result, ISC_R_SUCCESS);
/* ensure we stop listening after the test is done */
*test = (test_dispatch_t){ 0 };
/* Server */
- result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE,
- &tcp_server_addr, nameserver, NULL,
- accept_cb, NULL, 0, NULL, NULL, &sock);
+ result = isc_nm_listenstreamdns(
+ netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, nameserver, NULL,
+ accept_cb, NULL, 0, NULL, NULL, false, &sock);
assert_int_equal(result, ISC_R_SUCCESS);
/* ensure we stop listening after the test is done */
isc_nm_recv_cb_t recv_cb) {
isc_result_t result = isc_nm_listenstreamdns(
listen_nm, nworkers, &tcp_listen_addr, recv_cb, NULL, accept_cb,
- NULL, 128, NULL, NULL, &listen_sock);
+ NULL, 128, NULL, NULL, stream_use_PROXY, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
isc_loop_teardown(mainloop, stop_listening, listen_sock);
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);
+ NULL, NULL, stream_use_PROXY, NULL);
}
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);
+ NULL, NULL, stream_use_PROXY, NULL);
}
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);
+ NULL, NULL, stream_use_PROXY, NULL);
}
ISC_LOOP_TEST_IMPL(tcpdns_timeout_recovery) {
isc_nm_recv_cb_t recv_cb) {
isc_result_t result = isc_nm_listenstreamdns(
listen_nm, nworkers, &tcp_listen_addr, recv_cb, NULL, accept_cb,
- NULL, 128, NULL, tcp_listen_tlsctx, &listen_sock);
+ NULL, 128, NULL, tcp_listen_tlsctx, stream_use_PROXY,
+ &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
isc_loop_teardown(mainloop, stop_listening, listen_sock);
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,
- tcp_tlsctx_client_sess_cache);
+ isc_nm_streamdnsconnect(
+ nm, &tcp_connect_addr, &tcp_listen_addr, connect_connect_cb,
+ tlsdns_connect, T_CONNECT, tcp_connect_tlsctx,
+ tcp_tlsctx_client_sess_cache, stream_use_PROXY, NULL);
}
ISC_LOOP_TEST_IMPL(tlsdns_noop) {
isc_nm_streamdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
connect_success_cb, tlsdns_connect, T_CONNECT,
tcp_connect_tlsctx,
- tcp_tlsctx_client_sess_cache);
+ tcp_tlsctx_client_sess_cache, stream_use_PROXY,
+ NULL);
}
ISC_LOOP_TEST_IMPL(tlsdns_noresponse) {
isc_nm_streamdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
connect_connect_cb, tlsdns_connect, T_CONNECT,
tcp_connect_tlsctx,
- tcp_tlsctx_client_sess_cache);
+ tcp_tlsctx_client_sess_cache, stream_use_PROXY,
+ NULL);
}
ISC_LOOP_TEST_IMPL(tlsdns_timeout_recovery) {
connect_readcb = timeout_retry_cb;
isc_nm_settimeouts(connect_nm, T_SOFT, T_SOFT, T_SOFT, T_SOFT);
isc_refcount_increment0(&active_cconnects);
- 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);
+ 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, stream_use_PROXY, NULL);
}
ISC_LOOP_TEST_IMPL(tlsdns_recv_one) {