2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

Add 'proxy' option to 'listen-on' statement

This commit extends "listen-on" statement with "proxy" options that
allows one to enable PROXYv2 support on a dedicated listener. It can
have the following values:

- "plain" to send PROXYv2 headers without encryption, even in the case
of encrypted transports.
- "encrypted" to send PROXYv2 headers encrypted right after the TLS
handshake.
This commit is contained in:
Artem Boldariev
2023-10-30 17:03:30 +02:00
parent c9d526d84d
commit f650d3eb63
9 changed files with 168 additions and 42 deletions

View File

@@ -413,7 +413,8 @@ static isc_result_t
listenelt_http(const cfg_obj_t *http, const uint16_t family, bool tls, listenelt_http(const cfg_obj_t *http, const uint16_t family, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, in_port_t port, isc_tlsctx_cache_t *tlsctx_cache, in_port_t port,
isc_mem_t *mctx, ns_listenelt_t **target); isc_mem_t *mctx, isc_nm_proxy_type_t proxy,
ns_listenelt_t **target);
#endif #endif
static isc_result_t static isc_result_t
@@ -10791,6 +10792,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
const cfg_obj_t *tlsobj = NULL, *httpobj = NULL; const cfg_obj_t *tlsobj = NULL, *httpobj = NULL;
const cfg_obj_t *portobj = NULL; const cfg_obj_t *portobj = NULL;
const cfg_obj_t *http_server = NULL; const cfg_obj_t *http_server = NULL;
const cfg_obj_t *proxyobj = NULL;
in_port_t port = 0; in_port_t port = 0;
const char *key = NULL, *cert = NULL, *ca_file = NULL, const char *key = NULL, *cert = NULL, *ca_file = NULL,
*dhparam_file = NULL, *ciphers = NULL; *dhparam_file = NULL, *ciphers = NULL;
@@ -10802,6 +10804,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
uint32_t tls_protos = 0; uint32_t tls_protos = 0;
ns_listen_tls_params_t tls_params = { 0 }; ns_listen_tls_params_t tls_params = { 0 };
const char *tlsname = NULL; const char *tlsname = NULL;
isc_nm_proxy_type_t proxy = ISC_NM_PROXY_NONE;
REQUIRE(target != NULL && *target == NULL); REQUIRE(target != NULL && *target == NULL);
@@ -10985,16 +10988,31 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
port = (in_port_t)cfg_obj_asuint32(portobj); port = (in_port_t)cfg_obj_asuint32(portobj);
} }
proxyobj = cfg_tuple_get(ltup, "proxy");
if (proxyobj != NULL && cfg_obj_isstring(proxyobj)) {
const char *proxyval = cfg_obj_asstring(proxyobj);
if (strcasecmp(proxyval, "encrypted") == 0) {
INSIST(do_tls == true);
proxy = ISC_NM_PROXY_ENCRYPTED;
} else if (strcasecmp(proxyval, "plain") == 0) {
proxy = ISC_NM_PROXY_PLAIN;
} else {
UNREACHABLE();
}
}
#ifdef HAVE_LIBNGHTTP2 #ifdef HAVE_LIBNGHTTP2
if (http) { if (http) {
CHECK(listenelt_http(http_server, family, do_tls, &tls_params, CHECK(listenelt_http(http_server, family, do_tls, &tls_params,
tlsctx_cache, port, mctx, &delt)); tlsctx_cache, port, mctx, proxy, &delt));
} }
#endif /* HAVE_LIBNGHTTP2 */ #endif /* HAVE_LIBNGHTTP2 */
if (!http) { if (!http) {
CHECK(ns_listenelt_create(mctx, port, NULL, family, do_tls, CHECK(ns_listenelt_create(mctx, port, NULL, family, do_tls,
&tls_params, tlsctx_cache, &delt)); &tls_params, tlsctx_cache, proxy,
&delt));
} }
result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), config, result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), config,
@@ -11015,7 +11033,8 @@ static isc_result_t
listenelt_http(const cfg_obj_t *http, const uint16_t family, bool tls, listenelt_http(const cfg_obj_t *http, const uint16_t family, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, in_port_t port, isc_tlsctx_cache_t *tlsctx_cache, in_port_t port,
isc_mem_t *mctx, ns_listenelt_t **target) { isc_mem_t *mctx, isc_nm_proxy_type_t proxy,
ns_listenelt_t **target) {
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
ns_listenelt_t *delt = NULL; ns_listenelt_t *delt = NULL;
char **endpoints = NULL; char **endpoints = NULL;
@@ -11080,9 +11099,9 @@ listenelt_http(const cfg_obj_t *http, const uint16_t family, bool tls,
INSIST(i == len); INSIST(i == len);
result = ns_listenelt_create_http(mctx, port, NULL, family, tls, result = ns_listenelt_create_http(
tls_params, tlsctx_cache, endpoints, mctx, port, NULL, family, tls, tls_params, tlsctx_cache, proxy,
len, max_clients, max_streams, &delt); endpoints, len, max_clients, max_streams, &delt);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto error; goto error;
} }

View File

@@ -3066,9 +3066,10 @@ queries may be specified using the :any:`listen-on` and :any:`listen-on-v6` opti
:tags: server :tags: server
:short: Specifies the IPv6 addresses on which a server listens for DNS queries. :short: Specifies the IPv6 addresses on which a server listens for DNS queries.
The :any:`listen-on` and :any:`listen-on-v6` statements can each take an optional The :any:`listen-on` and :any:`listen-on-v6` statements can each
port, TLS configuration identifier, and/or HTTP configuration identifier, take an optional port, PROXYv2 support switch, TLS configuration
in addition to an :term:`address_match_list`. identifier, and/or HTTP configuration identifier, in addition to an
:term:`address_match_list`.
The :term:`address_match_list` in :any:`listen-on` specifies the IPv4 addresses The :term:`address_match_list` in :any:`listen-on` specifies the IPv4 addresses
on which the server will listen. (IPv6 addresses are ignored, with a on which the server will listen. (IPv6 addresses are ignored, with a
@@ -3081,6 +3082,52 @@ queries may be specified using the :any:`listen-on` and :any:`listen-on-v6` opti
If no :any:`listen-on-v6` is specified, the default is to listen for standard If no :any:`listen-on-v6` is specified, the default is to listen for standard
DNS queries on port 53 of all IPv6 interfaces. DNS queries on port 53 of all IPv6 interfaces.
When specified, the PROXYv2 support switch ``proxy`` allows
enabling the PROXYv2 protocol support. The PROXYv2 protocol
provides the means for passing connection information, such as a
client's source and destination addresses and ports, across
multiple layers of NAT or TCP/UDP proxies to back-end servers. The
addresses passed to by the PROXYv2 protocol are then used instead
of the peer and interface addresses provided by the operating
system.
The ``proxy`` switch can have the following values:
* ``plain`` - accept plain PROXYv2 headers. It is the only valid
option for transports that do not employ encryption. In the case
of transports that employ encryption, it instructs BIND that
PROXYv2 headers are sent without encryption before the TLS
handshake. In that case, only PROXYv2 headers are not encrypted.
* ``encrypted`` - accept encrypted PROXYv2 headers. In the case of
transports that employ encryption, it instructs BIND that PROXYv2
headers are sent encrypted immediately after the TLS
handshake. The option is valid only for the transports that employ
encryption.
You must consult your proxying front-end software documentation to
decide which value you need to use. If in doubt, use ``plain`` for
encrypted transports, especially for DNS-over-HTTPS (DoH), but
DNS-specific software is likely to need ``encrypted``.
It should be noted that when PROXYv2 is enabled on a listener, it
loses the ability to accept regular DNS queries without associated
PROXYv2 headers.
In some cases, PROXYv2 headers might not contain usable source and
destination addresses. In particular, that happens when the headers
use ``LOCAL`` command or the headers that use unspecified or
unsupported by BIND address types. If otherwise correct, such
headers are accepted by BIND and the real endpoint addresses are
used in these cases.
The PROXYv2 protocol is designed to be extensible and can carry
additional information in the form of type-length-values
(TLVs). Many of the types are defined in the protocol
specification, and for some of these, we do a reasonable amount of
validation in order to detect and reject ill-formed or hand-crafted
headers. Apart from that, this additional data, while accepted, is
not currently used by BIND for anything else.
If a TLS configuration is specified, :iscman:`named` will listen for DNS-over-TLS If a TLS configuration is specified, :iscman:`named` will listen for DNS-over-TLS
(DoT) connections, using the key and certificate specified in the (DoT) connections, using the key and certificate specified in the
referenced :any:`tls` statement. If the name ``ephemeral`` is used, referenced :any:`tls` statement. If the name ``ephemeral`` is used,
@@ -3110,6 +3157,9 @@ queries may be specified using the :any:`listen-on` and :any:`listen-on-v6` opti
listen-on port 1234 { !1.2.3.4; 1.2/16; }; listen-on port 1234 { !1.2.3.4; 1.2/16; };
listen-on port 8853 tls ephemeral { 4.3.2.1; }; listen-on port 8853 tls ephemeral { 4.3.2.1; };
listen-on port 8453 tls ephemeral http myserver { 8.7.6.5; }; listen-on port 8453 tls ephemeral http myserver { 8.7.6.5; };
listen-on port 5300 proxy plain { !1.2.3.4; 1.2/16; };
listen-on port 8953 proxy encrypted tls ephemeral { 4.3.2.1; };
listen-on port 8553 proxy plain tls ephemeral http myserver { 8.7.6.5; };
The first two lines instruct the name server to listen for standard DNS The first two lines instruct the name server to listen for standard DNS
queries on port 53 of the IP address 5.6.7.8 and on port 1234 of an address queries on port 53 of the IP address 5.6.7.8 and on port 1234 of an address
@@ -3126,9 +3176,12 @@ queries may be specified using the :any:`listen-on` and :any:`listen-on-v6` opti
listen-on-v6 { any; }; listen-on-v6 { any; };
listen-on-v6 port 1234 { !2001:db8::/32; any; }; listen-on-v6 port 1234 { !2001:db8::/32; any; };
listen-on port 8853 tls example-tls { 2001:db8::100; }; listen-on-v6 port 8853 tls example-tls { 2001:db8::100; };
listen-on port 8453 tls example-tls http default { 2001:db8::100; }; listen-on-v6 port 8453 tls example-tls http default { 2001:db8::100; };
listen-on port 8000 tls none http myserver { 2001:db8::100; }; listen-on-v6 port 8000 tls none http myserver { 2001:db8::100; };
listen-on-v6 port 53000 proxy plain { !2001:db8::/32; any; };
listen-on-v6 port 8953 proxy encrypted tls example-tls { 2001:db8::100; };
listen-on-v6 port 8553 proxy plain tls example-tls http default { 2001:db8::100; };
The first two lines instruct the name server to listen for standard DNS The first two lines instruct the name server to listen for standard DNS
queries on port 53 of any IPv6 addresses, and on port 1234 of IPv6 queries on port 53 of any IPv6 addresses, and on port 1234 of IPv6

View File

@@ -161,8 +161,8 @@ options {
keep-response-order { <address_match_element>; ... }; // obsolete keep-response-order { <address_match_element>; ... }; // obsolete
key-directory <quoted_string>; key-directory <quoted_string>;
lame-ttl <duration>; lame-ttl <duration>;
listen-on [ port <integer> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times listen-on [ port <integer> ] [ proxy <string> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times
listen-on-v6 [ port <integer> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times listen-on-v6 [ port <integer> ] [ proxy <string> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times
lmdb-mapsize <sizeval>; lmdb-mapsize <sizeval>;
managed-keys-directory <quoted_string>; managed-keys-directory <quoted_string>;
masterfile-format ( raw | text ); masterfile-format ( raw | text );

View File

@@ -701,7 +701,8 @@ cfg_acl_fromconfig(const cfg_obj_t *acl_data, const cfg_obj_t *cctx,
if (strcasecmp(cfg_obj_asstring(obj_transport), if (strcasecmp(cfg_obj_asstring(obj_transport),
"udp") == 0) "udp") == 0)
{ {
transports = isc_nm_udpsocket; transports = isc_nm_udpsocket |
isc_nm_proxyudpsocket;
encrypted = false; encrypted = false;
} else if (strcasecmp(cfg_obj_asstring(obj_transport), } else if (strcasecmp(cfg_obj_asstring(obj_transport),
"tcp") == 0) "tcp") == 0)
@@ -713,7 +714,8 @@ cfg_acl_fromconfig(const cfg_obj_t *acl_data, const cfg_obj_t *cctx,
{ {
/* Good ol' DNS over port 53 */ /* Good ol' DNS over port 53 */
transports = isc_nm_streamdnssocket | transports = isc_nm_streamdnssocket |
isc_nm_udpsocket; isc_nm_udpsocket |
isc_nm_proxyudpsocket;
encrypted = false; encrypted = false;
} else if (strcasecmp(cfg_obj_asstring(obj_transport), } else if (strcasecmp(cfg_obj_asstring(obj_transport),
"tls") == 0) "tls") == 0)

View File

@@ -1033,6 +1033,7 @@ check_listener(const cfg_obj_t *listener, const cfg_obj_t *config,
const cfg_obj_t *tlsobj = NULL, *httpobj = NULL; const cfg_obj_t *tlsobj = NULL, *httpobj = NULL;
const cfg_obj_t *portobj = NULL; const cfg_obj_t *portobj = NULL;
const cfg_obj_t *http_server = NULL; const cfg_obj_t *http_server = NULL;
const cfg_obj_t *proxyobj = NULL;
bool do_tls = false, no_tls = false; bool do_tls = false, no_tls = false;
dns_acl_t *acl = NULL; dns_acl_t *acl = NULL;
@@ -1097,6 +1098,36 @@ check_listener(const cfg_obj_t *listener, const cfg_obj_t *config,
} }
} }
proxyobj = cfg_tuple_get(ltup, "proxy");
if (proxyobj != NULL && cfg_obj_isstring(proxyobj)) {
const char *proxyval = cfg_obj_asstring(proxyobj);
if (proxyval == NULL ||
(strcasecmp(proxyval, "encrypted") != 0 &&
strcasecmp(proxyval, "plain") != 0))
{
cfg_obj_log(proxyobj, logctx, ISC_LOG_ERROR,
"'proxy' must have one of the following "
"values: 'plain', 'encrypted'");
if (result == ISC_R_SUCCESS) {
result = ISC_R_FAILURE;
}
}
if (proxyval != NULL &&
strcasecmp(proxyval, "encrypted") == 0 && !do_tls)
{
cfg_obj_log(proxyobj, logctx, ISC_LOG_ERROR,
"'proxy encrypted' can be used only when "
"encryption is enabled by setting 'tls' to "
"a defined value or to 'ephemeral'");
if (result == ISC_R_SUCCESS) {
result = ISC_R_FAILURE;
}
}
}
tresult = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), config, tresult = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), config,
logctx, actx, mctx, 0, &acl); logctx, actx, mctx, 0, &acl);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {

View File

@@ -150,6 +150,11 @@ static cfg_type_t cfg_type_zone;
static cfg_tuplefielddef_t listenon_tuple_fields[] = { static cfg_tuplefielddef_t listenon_tuple_fields[] = {
{ "port", &cfg_type_optional_port, 0 }, { "port", &cfg_type_optional_port, 0 },
/*
* Let's follow the protocols encapsulation order (lower->upper), at
* least roughly.
*/
{ "proxy", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
{ "tls", &cfg_type_astring, 0 }, { "tls", &cfg_type_astring, 0 },
#if HAVE_LIBNGHTTP2 #if HAVE_LIBNGHTTP2
{ "http", &cfg_type_astring, 0 }, { "http", &cfg_type_astring, 0 },

View File

@@ -29,6 +29,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <isc/net.h> #include <isc/net.h>
#include <isc/netmgr.h>
#include <isc/tls.h> #include <isc/tls.h>
#include <dns/types.h> #include <dns/types.h>
@@ -51,6 +52,7 @@ struct ns_listenelt {
size_t http_endpoints_number; size_t http_endpoints_number;
uint32_t http_max_clients; uint32_t http_max_clients;
uint32_t max_concurrent_streams; uint32_t max_concurrent_streams;
isc_nm_proxy_type_t proxy;
ISC_LINK(ns_listenelt_t) link; ISC_LINK(ns_listenelt_t) link;
}; };
@@ -82,7 +84,8 @@ isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl, ns_listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl,
const uint16_t family, bool tls, const uint16_t family, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, ns_listenelt_t **target); isc_tlsctx_cache_t *tlsctx_cache, isc_nm_proxy_type_t proxy,
ns_listenelt_t **target);
/*%< /*%<
* Create a listen-on list element. * Create a listen-on list element.
* *
@@ -96,7 +99,8 @@ isc_result_t
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, dns_acl_t *acl, ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, dns_acl_t *acl,
const uint16_t family, bool tls, const uint16_t family, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, char **endpoints, isc_tlsctx_cache_t *tlsctx_cache,
isc_nm_proxy_type_t proxy, char **endpoints,
size_t nendpoints, const uint32_t max_clients, size_t nendpoints, const uint32_t max_clients,
const uint32_t max_streams, ns_listenelt_t **target); const uint32_t max_streams, ns_listenelt_t **target);
/*%< /*%<

View File

@@ -471,25 +471,31 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
} }
static isc_result_t static isc_result_t
ns_interface_listenudp(ns_interface_t *ifp) { ns_interface_listenudp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) {
isc_result_t result; isc_result_t result;
/* Reserve space for an ns_client_t with the netmgr handle */ /* Reserve space for an ns_client_t with the netmgr handle */
result = isc_nm_listenudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, if (proxy == ISC_NM_PROXY_NONE) {
ns_client_request, ifp, result = isc_nm_listenudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL,
&ifp->udplistensocket); &ifp->addr, ns_client_request, ifp,
&ifp->udplistensocket);
} else {
INSIST(proxy == ISC_NM_PROXY_PLAIN);
result = isc_nm_listenproxyudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL,
&ifp->addr, ns_client_request,
ifp, &ifp->udplistensocket);
}
return (result); return (result);
} }
static isc_result_t static isc_result_t
ns_interface_listentcp(ns_interface_t *ifp) { ns_interface_listentcp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) {
isc_result_t result; isc_result_t result;
result = isc_nm_listenstreamdns( result = isc_nm_listenstreamdns(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request, ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog, ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota, NULL, ISC_NM_PROXY_NONE, &ifp->mgr->sctx->tcpquota, NULL, proxy, &ifp->tcplistensocket);
&ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
"creating TCP socket: %s", "creating TCP socket: %s",
@@ -516,13 +522,14 @@ ns_interface_listentcp(ns_interface_t *ifp) {
* TLS related options. * TLS related options.
*/ */
static isc_result_t static isc_result_t
ns_interface_listentls(ns_interface_t *ifp, isc_tlsctx_t *sslctx) { ns_interface_listentls(ns_interface_t *ifp, isc_nm_proxy_type_t proxy,
isc_tlsctx_t *sslctx) {
isc_result_t result; isc_result_t result;
result = isc_nm_listenstreamdns( result = isc_nm_listenstreamdns(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request, ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog, ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota, sslctx, ISC_NM_PROXY_NONE, &ifp->mgr->sctx->tcpquota, sslctx, proxy,
&ifp->tcplistensocket); &ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
@@ -566,9 +573,9 @@ load_http_endpoints(isc_nm_http_endpoints_t *epset, ns_interface_t *ifp,
#endif /* HAVE_LIBNGHTTP2 */ #endif /* HAVE_LIBNGHTTP2 */
static isc_result_t static isc_result_t
ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps, ns_interface_listenhttp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy,
size_t neps, uint32_t max_clients, isc_tlsctx_t *sslctx, char **eps, size_t neps,
uint32_t max_concurrent_streams) { uint32_t max_clients, uint32_t max_concurrent_streams) {
#if HAVE_LIBNGHTTP2 #if HAVE_LIBNGHTTP2
isc_result_t result = ISC_R_FAILURE; isc_result_t result = ISC_R_FAILURE;
isc_nmsocket_t *sock = NULL; isc_nmsocket_t *sock = NULL;
@@ -585,7 +592,7 @@ ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps,
result = isc_nm_listenhttp( result = isc_nm_listenhttp(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr,
ifp->mgr->backlog, quota, sslctx, epset, ifp->mgr->backlog, quota, sslctx, epset,
max_concurrent_streams, ISC_NM_PROXY_NONE, &sock); max_concurrent_streams, proxy, &sock);
} }
isc_nm_http_endpoints_detach(&epset); isc_nm_http_endpoints_detach(&epset);
@@ -629,6 +636,7 @@ ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps,
return (result); return (result);
#else #else
UNUSED(ifp); UNUSED(ifp);
UNUSED(proxy);
UNUSED(sslctx); UNUSED(sslctx);
UNUSED(eps); UNUSED(eps);
UNUSED(neps); UNUSED(neps);
@@ -660,7 +668,7 @@ interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
if (elt->is_http) { if (elt->is_http) {
result = ns_interface_listenhttp( result = ns_interface_listenhttp(
ifp, elt->sslctx, elt->http_endpoints, ifp, elt->proxy, elt->sslctx, elt->http_endpoints,
elt->http_endpoints_number, elt->http_max_clients, elt->http_endpoints_number, elt->http_max_clients,
elt->max_concurrent_streams); elt->max_concurrent_streams);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
@@ -671,7 +679,7 @@ interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
} }
if (elt->sslctx != NULL) { if (elt->sslctx != NULL) {
result = ns_interface_listentls(ifp, elt->sslctx); result = ns_interface_listentls(ifp, elt->proxy, elt->sslctx);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup_interface; goto cleanup_interface;
} }
@@ -679,7 +687,7 @@ interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
return (result); return (result);
} }
result = ns_interface_listenudp(ifp); result = ns_interface_listenudp(ifp, elt->proxy);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL)) { if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL)) {
*addr_in_use = true; *addr_in_use = true;
@@ -688,7 +696,7 @@ interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
} }
if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0)) { if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0)) {
result = ns_interface_listentcp(ifp); result = ns_interface_listentcp(ifp, elt->proxy);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if ((result == ISC_R_ADDRINUSE) && if ((result == ISC_R_ADDRINUSE) &&
(addr_in_use != NULL)) (addr_in_use != NULL))

View File

@@ -31,7 +31,8 @@ static isc_result_t
listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl, listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl,
const uint16_t family, const bool is_http, bool tls, const uint16_t family, const bool is_http, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, ns_listenelt_t **target) { isc_tlsctx_cache_t *tlsctx_cache, isc_nm_proxy_type_t proxy,
ns_listenelt_t **target) {
ns_listenelt_t *elt = NULL; ns_listenelt_t *elt = NULL;
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
isc_tlsctx_t *sslctx = NULL; isc_tlsctx_t *sslctx = NULL;
@@ -192,6 +193,7 @@ listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl,
elt->http_endpoints_number = 0; elt->http_endpoints_number = 0;
elt->http_max_clients = 0; elt->http_max_clients = 0;
elt->max_concurrent_streams = 0; elt->max_concurrent_streams = 0;
elt->proxy = proxy;
*target = elt; *target = elt;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
@@ -210,16 +212,18 @@ isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl, ns_listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl,
const uint16_t family, bool tls, const uint16_t family, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, ns_listenelt_t **target) { isc_tlsctx_cache_t *tlsctx_cache, isc_nm_proxy_type_t proxy,
ns_listenelt_t **target) {
return listenelt_create(mctx, port, acl, family, false, tls, tls_params, return listenelt_create(mctx, port, acl, family, false, tls, tls_params,
tlsctx_cache, target); tlsctx_cache, proxy, target);
} }
isc_result_t isc_result_t
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, dns_acl_t *acl, ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, dns_acl_t *acl,
const uint16_t family, bool tls, const uint16_t family, bool tls,
const ns_listen_tls_params_t *tls_params, const ns_listen_tls_params_t *tls_params,
isc_tlsctx_cache_t *tlsctx_cache, char **endpoints, isc_tlsctx_cache_t *tlsctx_cache,
isc_nm_proxy_type_t proxy, char **endpoints,
size_t nendpoints, const uint32_t max_clients, size_t nendpoints, const uint32_t max_clients,
const uint32_t max_streams, ns_listenelt_t **target) { const uint32_t max_streams, ns_listenelt_t **target) {
isc_result_t result; isc_result_t result;
@@ -229,7 +233,7 @@ ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, dns_acl_t *acl,
REQUIRE(nendpoints > 0); REQUIRE(nendpoints > 0);
result = listenelt_create(mctx, http_port, acl, family, true, tls, result = listenelt_create(mctx, http_port, acl, family, true, tls,
tls_params, tlsctx_cache, target); tls_params, tlsctx_cache, proxy, target);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
(*target)->is_http = true; (*target)->is_http = true;
(*target)->http_endpoints = endpoints; (*target)->http_endpoints = endpoints;
@@ -334,7 +338,7 @@ ns_listenlist_default(isc_mem_t *mctx, in_port_t port, bool enabled,
} }
result = ns_listenelt_create(mctx, port, acl, family, false, NULL, NULL, result = ns_listenelt_create(mctx, port, acl, family, false, NULL, NULL,
&elt); ISC_NM_PROXY_NONE, &elt);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup_acl; goto cleanup_acl;
} }