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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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)
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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 },
|
||||||
|
@@ -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);
|
||||||
/*%<
|
/*%<
|
||||||
|
@@ -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))
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user