[master] add DSCP support

3535.	[func]		Add support for setting Differentiated Services Code
			Point (DSCP) values in named.  Most configuration
			options which take a "port" option (e.g.,
			listen-on, forwarders, also-notify, masters,
			notify-source, etc) can now also take a "dscp"
			option specifying a code point for use with
			outgoing traffic, if supported by the underlying
			OS. [RT #27596]
This commit is contained in:
Evan Hunt 2013-03-22 12:27:54 -07:00
parent bbb3705e4c
commit 67adc03ef8
91 changed files with 3245 additions and 404 deletions

View file

@ -1,3 +1,12 @@
3536. [func] Add support for setting Differentiated Services Code
Point (DSCP) values in named. Most configuration
options which take a "port" option (e.g.,
listen-on, forwarders, also-notify, masters,
notify-source, etc) can now also take a "dscp"
option specifying a code point for use with
outgoing traffic, if supported by the underlying
OS. [RT #27596]
3535. [bug] Minor win32 cleanups. [RT #32962]
3534. [bug] Extra text after an embedded NULL was ignored when

View file

@ -827,6 +827,7 @@ client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
isc_netaddr_t netaddr;
int match;
unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE;
isc_dscp_t dispdscp = -1;
if (TCP_CLIENT(client)) {
socket = client->tcpsocket;
@ -852,6 +853,20 @@ client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
else
pktinfo = NULL;
if (client->dispatch != NULL) {
dispdscp = dns_dispatch_getdscp(client->dispatch);
if (dispdscp != -1)
client->dscp = dispdscp;
}
if (client->dscp == -1) {
client->sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
client->sendevent->dscp = 0;
} else {
client->sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
client->sendevent->dscp = client->dscp;
}
isc_buffer_usedregion(buffer, &r);
CTRACE("sendto");
@ -1533,6 +1548,13 @@ client_request(isc_task_t *task, isc_event_t *event) {
client->peeraddr = sevent->address;
client->peeraddr_valid = ISC_TRUE;
}
if ((sevent->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) {
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(90),
"received DSCP %d", sevent->dscp);
if (client->dscp == -1)
client->dscp = sevent->dscp;
}
if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) {
client->attributes |= NS_CLIENTATTR_PKTINFO;
client->pktinfo = sevent->pktinfo;
@ -2196,11 +2218,9 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
/* XXXRTH Hardwired constants */
client->sendevent = (isc_socketevent_t *)
isc_event_allocate(client->mctx, client,
ISC_SOCKEVENT_SENDDONE,
client_senddone, client,
sizeof(isc_socketevent_t));
client->sendevent = isc_socket_socketevent(client->mctx, client,
ISC_SOCKEVENT_SENDDONE,
client_senddone, client);
if (client->sendevent == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup_message;
@ -2212,11 +2232,9 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
goto cleanup_sendevent;
}
client->recvevent = (isc_socketevent_t *)
isc_event_allocate(client->mctx, client,
ISC_SOCKEVENT_RECVDONE,
client_request, client,
sizeof(isc_socketevent_t));
client->recvevent = isc_socket_socketevent(client->mctx, client,
ISC_SOCKEVENT_RECVDONE,
client_request, client);
if (client->recvevent == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup_recvbuf;
@ -2243,6 +2261,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
client->tcpbuf = NULL;
client->opt = NULL;
client->udpsize = 512;
client->dscp = -1;
client->extflags = 0;
client->ednsversion = -1;
client->next = NULL;
@ -2737,6 +2756,8 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
client->state = NS_CLIENTSTATE_READY;
INSIST(client->recursionquota == NULL);
client->dscp = ifp->dscp;
if (tcp) {
client->attributes |= NS_CLIENTATTR_TCP;
isc_socket_attach(ifp->tcpsocket,

View file

@ -64,6 +64,7 @@ options {\n\
session-keyalg hmac-sha256;\n\
deallocate-on-exit true;\n\
# directory <none>\n\
dscp 0;\n\
dump-file \"named_dump.db\";\n\
fake-iquery no;\n\
has-old-clients false;\n\
@ -279,7 +280,9 @@ ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) {
}
isc_result_t
ns_config_get(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) {
ns_config_get(cfg_obj_t const * const *maps, const char *name,
const cfg_obj_t **obj)
{
int i;
for (i = 0;; i++) {
@ -402,17 +405,20 @@ ns_config_getzonetype(const cfg_obj_t *zonetypeobj) {
isc_result_t
ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
in_port_t defport, isc_mem_t *mctx,
isc_sockaddr_t **addrsp, isc_uint32_t *countp)
isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
isc_uint32_t *countp)
{
int count, i = 0;
const cfg_obj_t *addrlist;
const cfg_obj_t *portobj;
const cfg_obj_t *portobj, *dscpobj;
const cfg_listelt_t *element;
isc_sockaddr_t *addrs;
in_port_t port;
isc_dscp_t dscp = -1, *dscps;
isc_result_t result;
INSIST(addrsp != NULL && *addrsp == NULL);
INSIST(dscpsp == NULL || *dscpsp == NULL);
INSIST(countp != NULL);
addrlist = cfg_tuple_get(list, "addresses");
@ -435,6 +441,23 @@ ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
return (result);
}
if (dscpsp != NULL) {
dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
if (dscps == NULL)
return (ISC_R_NOMEMORY);
dscpobj = cfg_tuple_get(list, "dscp");
if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
if (cfg_obj_asuint32(dscpobj) > 63) {
cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
"dscp value '%u' is out of range",
cfg_obj_asuint32(dscpobj));
return (ISC_R_RANGE);
}
dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
}
}
addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t));
if (addrs == NULL)
return (ISC_R_NOMEMORY);
@ -443,8 +466,17 @@ ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
element != NULL;
element = cfg_list_next(element), i++)
{
const cfg_obj_t *addr;
INSIST(i < count);
addrs[i] = *cfg_obj_assockaddr(cfg_listelt_value(element));
addr = cfg_listelt_value(element);
addrs[i] = *cfg_obj_assockaddr(addr);
if (dscpsp != NULL) {
isc_dscp_t innerdscp;
innerdscp = cfg_obj_getdscp(addr);
if (innerdscp == -1)
innerdscp = dscp;
dscps[i] = innerdscp;
}
if (isc_sockaddr_getport(&addrs[i]) == 0)
isc_sockaddr_setport(&addrs[i], port);
}
@ -453,17 +485,26 @@ ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
*addrsp = addrs;
*countp = count;
if (dscpsp != NULL)
*dscpsp = dscps;
return (ISC_R_SUCCESS);
}
void
ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
isc_uint32_t count)
isc_dscp_t **dscpsp, isc_uint32_t count)
{
INSIST(addrsp != NULL && *addrsp != NULL);
INSIST(dscpsp == NULL || *dscpsp != NULL);
isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
*addrsp = NULL;
if (dscpsp != NULL) {
isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
*dscpsp = NULL;
}
}
static isc_result_t
@ -497,32 +538,40 @@ get_masters_def(const cfg_obj_t *cctx, const char *name,
isc_result_t
ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
isc_mem_t *mctx, isc_sockaddr_t **addrsp,
dns_name_t ***keysp, isc_uint32_t *countp)
isc_dscp_t **dscpsp, dns_name_t ***keysp,
isc_uint32_t *countp)
{
isc_uint32_t addrcount = 0, keycount = 0, i = 0;
isc_uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
isc_uint32_t listcount = 0, l = 0, j;
isc_uint32_t stackcount = 0, pushed = 0;
isc_result_t result;
const cfg_listelt_t *element;
const cfg_obj_t *addrlist;
const cfg_obj_t *portobj;
const cfg_obj_t *dscpobj;
in_port_t port;
isc_dscp_t dscp;
dns_fixedname_t fname;
isc_sockaddr_t *addrs = NULL;
isc_dscp_t *dscps = NULL;
dns_name_t **keys = NULL;
struct { const char *name; } *lists = NULL;
struct {
const cfg_listelt_t *element;
in_port_t port;
isc_dscp_t dscp;
} *stack = NULL;
REQUIRE(addrsp != NULL && *addrsp == NULL);
REQUIRE(dscpsp != NULL && *dscpsp == NULL);
REQUIRE(keysp != NULL && *keysp == NULL);
REQUIRE(countp != NULL);
newlist:
addrlist = cfg_tuple_get(list, "addresses");
portobj = cfg_tuple_get(list, "port");
dscpobj = cfg_tuple_get(list, "dscp");
if (cfg_obj_isuint32(portobj)) {
isc_uint32_t val = cfg_obj_asuint32(portobj);
if (val > ISC_UINT16_MAX) {
@ -538,6 +587,20 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
goto cleanup;
}
if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
if (cfg_obj_asuint32(dscpobj) > 63) {
cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
"dscp value '%u' is out of range",
cfg_obj_asuint32(dscpobj));
return (ISC_R_RANGE);
}
dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
} else {
result = ns_config_getdscp(config, &dscp);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
result = ISC_R_NOMEMORY;
element = cfg_list_first(addrlist);
@ -618,6 +681,7 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
*/
stack[pushed].element = cfg_list_next(element);
stack[pushed].port = port;
stack[pushed].dscp = dscp;
pushed++;
goto newlist;
}
@ -639,6 +703,18 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
addrs = new;
addrcount = newlen;
newsize = newlen * sizeof(isc_dscp_t);
oldsize = dscpcount * sizeof(isc_dscp_t);
new = isc_mem_get(mctx, newsize);
if (new == NULL)
goto cleanup;
if (dscpcount != 0) {
memcpy(new, dscps, oldsize);
isc_mem_put(mctx, dscps, oldsize);
}
dscps = new;
dscpcount = newlen;
newsize = newlen * sizeof(dns_name_t *);
oldsize = keycount * sizeof(dns_name_t *);
new = isc_mem_get(mctx, newsize);
@ -655,6 +731,9 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
addrs[i] = *cfg_obj_assockaddr(addr);
if (isc_sockaddr_getport(&addrs[i]) == 0)
isc_sockaddr_setport(&addrs[i], port);
dscps[i] = cfg_obj_getdscp(addr);
if (dscps[i] == -1)
dscps[i] = dscp;
keys[i] = NULL;
i++; /* Increment here so that cleanup on error works. */
if (!cfg_obj_isstring(key))
@ -681,6 +760,7 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
pushed--;
element = stack[pushed].element;
port = stack[pushed].port;
dscp = stack[pushed].dscp;
goto resume;
}
if (i < addrcount) {
@ -700,6 +780,19 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
addrs = new;
addrcount = i;
newsize = i * sizeof(isc_dscp_t);
oldsize = dscpcount * sizeof(isc_dscp_t);
if (i != 0) {
new = isc_mem_get(mctx, newsize);
if (new == NULL)
goto cleanup;
memcpy(new, dscps, newsize);
} else
new = NULL;
isc_mem_put(mctx, dscps, oldsize);
dscps = new;
dscpcount = i;
newsize = i * sizeof(dns_name_t *);
oldsize = keycount * sizeof(dns_name_t *);
if (i != 0) {
@ -722,6 +815,7 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
INSIST(keycount == addrcount);
*addrsp = addrs;
*dscpsp = dscps;
*keysp = keys;
*countp = addrcount;
@ -730,6 +824,8 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
cleanup:
if (addrs != NULL)
isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t));
if (dscps != NULL)
isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t));
if (keys != NULL) {
for (j = 0; j < i; j++) {
if (keys[j] == NULL)
@ -749,14 +845,21 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
void
ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
dns_name_t ***keysp, isc_uint32_t count)
isc_dscp_t **dscpsp, dns_name_t ***keysp,
isc_uint32_t count)
{
unsigned int i;
dns_name_t **keys = *keysp;
dns_name_t **keys;
INSIST(addrsp != NULL && *addrsp != NULL);
REQUIRE(addrsp != NULL && *addrsp != NULL);
REQUIRE(dscpsp == NULL || *dscpsp != NULL);
REQUIRE(keysp != NULL && *keysp != NULL);
keys = *keysp;
isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
if (dscpsp != NULL)
isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
for (i = 0; i < count; i++) {
if (keys[i] == NULL)
continue;
@ -766,6 +869,8 @@ ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
}
isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *));
*addrsp = NULL;
if (dscpsp != NULL)
*dscpsp = NULL;
*keysp = NULL;
}
@ -796,6 +901,35 @@ ns_config_getport(const cfg_obj_t *config, in_port_t *portp) {
return (ISC_R_SUCCESS);
}
isc_result_t
ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) {
const cfg_obj_t *maps[2];
const cfg_obj_t *options = NULL;
const cfg_obj_t *dscpobj = NULL;
isc_result_t result;
int i;
(void)cfg_map_get(config, "options", &options);
i = 0;
if (options != NULL)
maps[i++] = options;
maps[i] = NULL;
result = ns_config_get(maps, "dscp", &dscpobj);
if (dscpobj == NULL) {
*dscpp = -1;
return (ISC_R_SUCCESS);
}
if (cfg_obj_asuint32(dscpobj) >= 64) {
cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
"dscp '%u' out of range",
cfg_obj_asuint32(dscpobj));
return (ISC_R_RANGE);
}
*dscpp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
return (ISC_R_SUCCESS);
}
struct keyalgorithms {
const char *str;
enum { hmacnone, hmacmd5, hmacsha1, hmacsha224,

View file

@ -141,6 +141,7 @@ struct ns_client {
isc_boolean_t peeraddr_valid;
isc_netaddr_t destaddr;
struct in6_pktinfo pktinfo;
isc_dscp_t dscp;
isc_event_t ctlevent;
#ifdef ALLOW_FILTER_AAAA
dns_aaaa_t filter_aaaa;

View file

@ -31,7 +31,8 @@ isc_result_t
ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf);
isc_result_t
ns_config_get(const cfg_obj_t **maps, const char* name, const cfg_obj_t **obj);
ns_config_get(cfg_obj_t const * const *maps, const char* name,
const cfg_obj_t **obj);
isc_result_t
ns_checknames_get(const cfg_obj_t **maps, const char* name,
@ -54,20 +55,23 @@ ns_config_getzonetype(const cfg_obj_t *zonetypeobj);
isc_result_t
ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
in_port_t defport, isc_mem_t *mctx,
isc_sockaddr_t **addrsp, isc_uint32_t *countp);
isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
isc_uint32_t *countp);
void
ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
isc_uint32_t count);
isc_dscp_t **dscpsp, isc_uint32_t count);
isc_result_t
ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
isc_mem_t *mctx, isc_sockaddr_t **addrsp,
dns_name_t ***keys, isc_uint32_t *countp);
isc_dscp_t **dscpp, dns_name_t ***keys,
isc_uint32_t *countp);
void
ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
dns_name_t ***keys, isc_uint32_t count);
isc_dscp_t **dscpsp, dns_name_t ***keys,
isc_uint32_t count);
isc_result_t
ns_config_getport(const cfg_obj_t *config, in_port_t *portp);
@ -79,4 +83,7 @@ isc_result_t
ns_config_getkeyalgorithm2(const char *str, dns_name_t **name,
unsigned int *typep, isc_uint16_t *digestbits);
isc_result_t
ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp);
#endif /* NAMED_CONFIG_H */

View file

@ -72,6 +72,7 @@ EXTERN const char * ns_g_product INIT(PRODUCT);
EXTERN const char * ns_g_srcid INIT(SRCID);
EXTERN const char * ns_g_configargs INIT(CONFIGARGS);
EXTERN in_port_t ns_g_port INIT(0);
EXTERN isc_dscp_t ns_g_dscp INIT(-1);
EXTERN in_port_t lwresd_g_listenport INIT(0);
EXTERN ns_server_t * ns_g_server INIT(NULL);

View file

@ -80,6 +80,7 @@ struct ns_interface {
dns_dispatch_t * udpdispatch[MAX_UDP_DISPATCH];
/*%< UDP dispatchers. */
isc_socket_t * tcpsocket; /*%< TCP socket. */
isc_dscp_t dscp; /*%< "listen-on" DSCP value */
int ntcptarget; /*%< Desired number of concurrent
TCP accepts */
int ntcpcurrent; /*%< Current ditto, locked */

View file

@ -46,6 +46,7 @@ typedef struct ns_listenlist ns_listenlist_t;
struct ns_listenelt {
isc_mem_t * mctx;
in_port_t port;
isc_dscp_t dscp; /* -1 = not set, 0..63 */
dns_acl_t * acl;
ISC_LINK(ns_listenelt_t) link;
};
@ -61,7 +62,7 @@ struct ns_listenlist {
***/
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
dns_acl_t *acl, ns_listenelt_t **target);
/*%
* Create a listen-on list element.
@ -92,7 +93,7 @@ ns_listenlist_detach(ns_listenlist_t **listp);
*/
isc_result_t
ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
isc_boolean_t enabled, ns_listenlist_t **target);
/*%
* Create a listen-on list with default contents, matching

View file

@ -234,6 +234,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
ifp->ntcpcurrent = 0;
ifp->nudpdispatch = 0;
ifp->dscp = -1;
ISC_LINK_INIT(ifp, link);
ns_interfacemgr_attach(mgr, &ifp->mgr);
@ -345,6 +347,10 @@ ns_interface_accepttcp(ns_interface_t *ifp) {
isc_result_totext(result));
goto tcp_bind_failure;
}
if (ifp->dscp != -1)
isc_socket_dscp(ifp->tcpsocket, ifp->dscp);
result = isc_socket_listen(ifp->tcpsocket, ns_g_listen);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
@ -381,7 +387,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) {
static isc_result_t
ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
const char *name, ns_interface_t **ifpret,
isc_boolean_t accept_tcp)
isc_boolean_t accept_tcp, isc_dscp_t dscp)
{
isc_result_t result;
ns_interface_t *ifp = NULL;
@ -391,6 +397,8 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
if (result != ISC_R_SUCCESS)
return (result);
ifp->dscp = dscp;
result = ns_interface_listenudp(ifp);
if (result != ISC_R_SUCCESS)
goto cleanup_interface;
@ -627,6 +635,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
ns_interface_t *ifp;
isc_boolean_t log_explicit = ISC_FALSE;
isc_boolean_t dolistenon;
char sabuf[ISC_SOCKADDR_FORMATSIZE];
if (ext_listen != NULL)
adjusting = ISC_TRUE;
@ -682,6 +691,18 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
ifp = find_matching_interface(mgr, &listen_addr);
if (ifp != NULL) {
ifp->generation = mgr->generation;
if (le->dscp != -1 && ifp->dscp == -1)
ifp->dscp = le->dscp;
else if (le->dscp != ifp->dscp) {
isc_sockaddr_format(&listen_addr,
sabuf,
sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_WARNING,
"%s: conflicting DSCP "
"values, using %d",
sabuf, ifp->dscp);
}
} else {
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_INFO,
@ -690,7 +711,8 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
le->port);
result = ns_interface_setup(mgr, &listen_addr,
"<any>", &ifp,
ISC_TRUE);
ISC_TRUE,
le->dscp);
if (result == ISC_R_SUCCESS)
ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
else
@ -843,9 +865,19 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
ifp = find_matching_interface(mgr, &listen_sockaddr);
if (ifp != NULL) {
ifp->generation = mgr->generation;
if (le->dscp != -1 && ifp->dscp == -1)
ifp->dscp = le->dscp;
else if (le->dscp != ifp->dscp) {
isc_sockaddr_format(&listen_addr,
sabuf,
sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_WARNING,
"%s: conflicting DSCP "
"values, using %d",
sabuf, ifp->dscp);
}
} else {
char sabuf[ISC_SOCKADDR_FORMATSIZE];
if (adjusting == ISC_FALSE &&
ipv6_wildcard == ISC_TRUE)
continue;
@ -875,12 +907,12 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
interface.name, sabuf);
result = ns_interface_setup(mgr,
&listen_sockaddr,
interface.name,
&ifp,
(adjusting == ISC_TRUE) ?
ISC_FALSE :
ISC_TRUE);
&listen_sockaddr,
interface.name,
&ifp,
(adjusting == ISC_TRUE) ?
ISC_FALSE : ISC_TRUE,
le->dscp);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS,

View file

@ -32,7 +32,7 @@ static void
destroy(ns_listenlist_t *list);
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
dns_acl_t *acl, ns_listenelt_t **target)
{
ns_listenelt_t *elt = NULL;
@ -43,6 +43,7 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
elt->mctx = mctx;
ISC_LINK_INIT(elt, link);
elt->port = port;
elt->dscp = dscp;
elt->acl = acl;
*target = elt;
return (ISC_R_SUCCESS);
@ -100,7 +101,7 @@ ns_listenlist_detach(ns_listenlist_t **listp) {
}
isc_result_t
ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
isc_boolean_t enabled, ns_listenlist_t **target)
{
isc_result_t result;
@ -116,7 +117,7 @@ ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
if (result != ISC_R_SUCCESS)
goto cleanup;
result = ns_listenelt_create(mctx, port, acl, &elt);
result = ns_listenelt_create(mctx, port, dscp, acl, &elt);
if (result != ISC_R_SUCCESS)
goto cleanup_acl;

View file

@ -812,11 +812,12 @@ ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) {
isc_uint32_t i;
CHECK(ns_config_getiplist(config, listenerslist,
port, mctx, &addrs, &count));
port, mctx, &addrs, NULL,
&count));
for (i = 0; i < count; i++)
CHECK(configure_listener(&addrs[i], lwresd,
mctx, &newlisteners));
ns_config_putiplist(mctx, &addrs, count);
ns_config_putiplist(mctx, &addrs, NULL, count);
}
ns_lwdmanager_detach(&lwresd);
}
@ -845,7 +846,7 @@ ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) {
ISC_LIST_APPENDLIST(listeners, newlisteners, link);
if (addrs != NULL)
ns_config_putiplist(mctx, &addrs, count);
ns_config_putiplist(mctx, &addrs, NULL, count);
if (lwresd != NULL)
ns_lwdmanager_detach(&lwresd);

View file

@ -97,6 +97,8 @@
#define BACKTRACE_MAXFRAME 128
#endif
extern int isc_dscp_check_value;
static isc_boolean_t want_stats = ISC_FALSE;
static char program_name[ISC_DIR_NAMEMAX] = "named";
static char absolute_conffile[ISC_DIR_PATHMAX];
@ -510,10 +512,15 @@ parse_command_line(int argc, char *argv[]) {
break;
case 'T': /* NOT DOCUMENTED */
/*
* force the server to behave (or misbehave) in
* specified ways for testing purposes.
*
* clienttest: make clients single shot with their
* own memory context.
* delay=xxxx: delay client responses by xxxx ms to
* simulate remote servers.
* dscp=x: check that dscp values are as
* expected and assert otherwise.
*/
if (!strcmp(isc_commandline_argument, "clienttest"))
ns_g_clienttest = ISC_TRUE;
@ -539,6 +546,9 @@ parse_command_line(int argc, char *argv[]) {
ns_g_nosyslog = ISC_TRUE;
else if (!strcmp(isc_commandline_argument, "nonearest"))
ns_g_nonearest = ISC_TRUE;
else if (!strncmp(isc_commandline_argument, "dscp=", 5))
isc_dscp_check_value =
atoi(isc_commandline_argument + 5);
else
fprintf(stderr, "unknown -T flag '%s\n",
isc_commandline_argument);

View file

@ -936,8 +936,8 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) {
* Get a dispatch appropriate for the resolver of a given view.
*/
static isc_result_t
get_view_querysource_dispatch(const cfg_obj_t **maps,
int af, dns_dispatch_t **dispatchp,
get_view_querysource_dispatch(const cfg_obj_t **maps, int af,
dns_dispatch_t **dispatchp, isc_dscp_t *dscpp,
isc_boolean_t is_firstview)
{
isc_result_t result = ISC_R_FAILURE;
@ -946,6 +946,7 @@ get_view_querysource_dispatch(const cfg_obj_t **maps,
unsigned int attrs, attrmask;
const cfg_obj_t *obj = NULL;
unsigned int maxdispatchbuffers;
isc_dscp_t dscp = -1;
switch (af) {
case AF_INET:
@ -963,6 +964,10 @@ get_view_querysource_dispatch(const cfg_obj_t **maps,
sa = *(cfg_obj_assockaddr(obj));
INSIST(isc_sockaddr_pf(&sa) == af);
dscp = cfg_obj_getdscp(obj);
if (dscp != -1 && dscpp != NULL)
*dscpp = dscp;
/*
* If we don't support this address family, we're done!
*/
@ -1206,6 +1211,9 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
if (obj != NULL) {
result = dns_peer_settransfersource(peer,
cfg_obj_assockaddr(obj));
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_peer_settransferdscp(peer, cfg_obj_getdscp(obj));
if (result != ISC_R_SUCCESS)
goto cleanup;
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
@ -1219,6 +1227,9 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
if (obj != NULL) {
result = dns_peer_setnotifysource(peer,
cfg_obj_assockaddr(obj));
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_peer_setnotifydscp(peer, cfg_obj_getdscp(obj));
if (result != ISC_R_SUCCESS)
goto cleanup;
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
@ -1232,6 +1243,9 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
if (obj != NULL) {
result = dns_peer_setquerysource(peer,
cfg_obj_assockaddr(obj));
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_peer_setquerydscp(peer, cfg_obj_getdscp(obj));
if (result != ISC_R_SUCCESS)
goto cleanup;
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
@ -2082,6 +2096,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
unsigned int query_timeout, ndisp;
struct cfg_context *nzctx;
isc_boolean_t old_rpz_ok = ISC_FALSE;
isc_dscp_t dscp4 = -1, dscp6 = -1;
REQUIRE(DNS_VIEW_VALID(view));
@ -2652,10 +2667,10 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
*
* XXXRTH Hardwired number of tasks.
*/
CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4,
CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4, &dscp4,
ISC_TF(ISC_LIST_PREV(view, link)
== NULL)));
CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6,
CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6, &dscp6,
ISC_TF(ISC_LIST_PREV(view, link)
== NULL)));
if (dispatch4 == NULL && dispatch6 == NULL) {
@ -2681,6 +2696,15 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
resopts, ns_g_dispatchmgr,
dispatch4, dispatch6));
if (dscp4 == -1)
dscp4 = ns_g_dscp;
if (dscp6 == -1)
dscp6 = ns_g_dscp;
if (dscp4 != -1)
dns_resolver_setquerydscp4(view->resolver, dscp4);
if (dscp6 != -1)
dns_resolver_setquerydscp6(view->resolver, dscp6);
/*
* Set the ADB cache size to 1/8th of the max-cache-size or
* MAX_ADB_SIZE_FOR_CACHESHARE when the cache is shared.
@ -3589,16 +3613,17 @@ static isc_result_t
configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype)
{
const cfg_obj_t *portobj;
const cfg_obj_t *portobj, *dscpobj;
const cfg_obj_t *faddresses;
const cfg_listelt_t *element;
dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
isc_sockaddrlist_t addresses;
isc_sockaddr_t *sa;
dns_forwarderlist_t fwdlist;
dns_forwarder_t *fwd;
isc_result_t result;
in_port_t port;
isc_dscp_t dscp = -1;
ISC_LIST_INIT(addresses);
ISC_LIST_INIT(fwdlist);
/*
* Determine which port to send forwarded requests to.
@ -3621,6 +3646,22 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
}
}
/*
* DSCP value for forwarded requests.
*/
dscpobj = cfg_tuple_get(forwarders, "dscp");
if (!cfg_obj_isuint32(dscpobj))
dscp = ns_g_dscp;
else {
if (cfg_obj_asuint32(dscpobj) > 63) {
cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
"dscp value '%u' is out of range",
cfg_obj_asuint32(dscpobj));
return (ISC_R_RANGE);
}
dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
}
faddresses = NULL;
if (forwarders != NULL)
faddresses = cfg_tuple_get(forwarders, "addresses");
@ -3630,19 +3671,22 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
element = cfg_list_next(element))
{
const cfg_obj_t *forwarder = cfg_listelt_value(element);
sa = isc_mem_get(view->mctx, sizeof(isc_sockaddr_t));
if (sa == NULL) {
fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t));
if (fwd == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
*sa = *cfg_obj_assockaddr(forwarder);
if (isc_sockaddr_getport(sa) == 0)
isc_sockaddr_setport(sa, port);
ISC_LINK_INIT(sa, link);
ISC_LIST_APPEND(addresses, sa, link);
fwd->addr = *cfg_obj_assockaddr(forwarder);
if (isc_sockaddr_getport(&fwd->addr) == 0)
isc_sockaddr_setport(&fwd->addr, port);
fwd->dscp = cfg_obj_getdscp(forwarder);
if (fwd->dscp == -1)
fwd->dscp = dscp;
ISC_LINK_INIT(fwd, link);
ISC_LIST_APPEND(fwdlist, fwd, link);
}
if (ISC_LIST_EMPTY(addresses)) {
if (ISC_LIST_EMPTY(fwdlist)) {
if (forwardtype != NULL)
cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING,
"no forwarders seen; disabling "
@ -3662,8 +3706,8 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
}
}
result = dns_fwdtable_add(view->fwdtable, origin, &addresses,
fwdpolicy);
result = dns_fwdtable_addfwd(view->fwdtable, origin, &fwdlist,
fwdpolicy);
if (result != ISC_R_SUCCESS) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(origin, namebuf, sizeof(namebuf));
@ -3677,10 +3721,10 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
cleanup:
while (!ISC_LIST_EMPTY(addresses)) {
sa = ISC_LIST_HEAD(addresses);
ISC_LIST_UNLINK(addresses, sa, link);
isc_mem_put(view->mctx, sa, sizeof(isc_sockaddr_t));
while (!ISC_LIST_EMPTY(fwdlist)) {
fwd = ISC_LIST_HEAD(fwdlist);
ISC_LIST_UNLINK(fwdlist, fwd, link);
isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t));
}
return (result);
@ -4275,7 +4319,7 @@ scan_interfaces(ns_server_t *server, isc_boolean_t verbose) {
static isc_result_t
add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
isc_boolean_t wcardport_ok)
isc_dscp_t dscp, isc_boolean_t wcardport_ok)
{
ns_listenelt_t *lelt = NULL;
dns_acl_t *src_acl = NULL;
@ -4300,7 +4344,7 @@ add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
goto clean;
result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr),
src_acl, &lelt);
dscp, src_acl, &lelt);
if (result != ISC_R_SUCCESS)
goto clean;
ISC_LIST_APPEND(list->elts, lelt, link);
@ -4328,6 +4372,7 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
dns_view_t *view;
dns_zone_t *zone, *next;
isc_sockaddr_t addr, *addrp;
isc_dscp_t dscp;
result = ns_listenlist_create(mctx, &list);
if (result != ISC_R_SUCCESS)
@ -4353,7 +4398,7 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
* query ports, and some of them may override an existing
* wildcard IPv6 port.
*/
result = add_listenelt(mctx, list, &addr, ISC_TRUE);
result = add_listenelt(mctx, list, &addr, dscp, ISC_TRUE);
if (result != ISC_R_SUCCESS)
goto fail;
}
@ -4383,12 +4428,14 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
continue;
addrp = dns_zone_getnotifysrc6(zone);
result = add_listenelt(mctx, list, addrp, ISC_FALSE);
dscp = dns_zone_getnotifysrc6dscp(zone);
result = add_listenelt(mctx, list, addrp, dscp, ISC_FALSE);
if (result != ISC_R_SUCCESS)
goto fail;
addrp = dns_zone_getxfrsource6(zone);
result = add_listenelt(mctx, list, addrp, ISC_FALSE);
dscp = dns_zone_getxfrsource6dscp(zone);
result = add_listenelt(mctx, list, addrp, dscp, ISC_FALSE);
if (result != ISC_R_SUCCESS)
goto fail;
}
@ -5241,6 +5288,11 @@ load_configuration(const char *filename, ns_server_t *server,
else
CHECKM(ns_config_getport(config, &listen_port), "port");
/*
* Determing the default DSCP code point.
*/
CHECKM(ns_config_getdscp(config, &ns_g_dscp), "dscp");
/*
* Find the listen queue depth.
*/
@ -5277,7 +5329,7 @@ load_configuration(const char *filename, ns_server_t *server,
* Not specified, use default.
*/
CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
ISC_TRUE, &listenon));
-1, ISC_TRUE, &listenon));
}
if (listenon != NULL) {
ns_interfacemgr_setlistenon4(server->interfacemgr,
@ -5304,7 +5356,7 @@ load_configuration(const char *filename, ns_server_t *server,
* Not specified, use default.
*/
CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
ISC_TRUE, &listenon));
-1, ISC_TRUE, &listenon));
}
if (listenon != NULL) {
ns_interfacemgr_setlistenon6(server->interfacemgr,
@ -6869,8 +6921,9 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
isc_mem_t *mctx, ns_listenelt_t **target)
{
isc_result_t result;
const cfg_obj_t *portobj;
const cfg_obj_t *portobj, *dscpobj;
in_port_t port;
isc_dscp_t dscp = -1;
ns_listenelt_t *delt = NULL;
REQUIRE(target != NULL && *target == NULL);
@ -6893,7 +6946,20 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
port = (in_port_t)cfg_obj_asuint32(portobj);
}
result = ns_listenelt_create(mctx, port, NULL, &delt);
dscpobj = cfg_tuple_get(listener, "dscp");
if (!cfg_obj_isuint32(dscpobj))
dscp = ns_g_dscp;
else {
if (cfg_obj_asuint32(dscpobj) > 63) {
cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
"dscp value '%u' is out of range",
cfg_obj_asuint32(dscpobj));
return (ISC_R_RANGE);
}
dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
}
result = ns_listenelt_create(mctx, port, dscp, NULL, &delt);
if (result != ISC_R_SUCCESS)
return (result);

View file

@ -807,6 +807,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const char *dupcheck;
dns_notifytype_t notifytype = dns_notifytype_yes;
isc_sockaddr_t *addrs;
isc_dscp_t *dscps;
dns_name_t **keynames;
isc_uint32_t count;
unsigned int dbargc;
@ -831,6 +832,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zonestat_level_t statlevel;
int seconds;
dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
isc_dscp_t dscp;
i = 0;
if (zconfig != NULL) {
@ -1103,17 +1105,20 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_uint32_t addrcount;
addrs = NULL;
keynames = NULL;
dscps = NULL;
RETERR(ns_config_getipandkeylist(config, obj, mctx,
&addrs, &keynames,
&addrs, &dscps,
&keynames,
&addrcount));
result = dns_zone_setalsonotifywithkeys(zone, addrs,
keynames,
result = dns_zone_setalsonotifydscpkeys(zone, addrs,
dscps, keynames,
addrcount);
if (addrcount != 0)
ns_config_putipandkeylist(mctx, &addrs,
ns_config_putipandkeylist(mctx, &addrs, &dscps,
&keynames, addrcount);
else
INSIST(addrs == NULL && keynames == NULL);
INSIST(addrs == NULL && dscps == NULL &&
keynames == NULL);
RETERR(result);
} else
RETERR(dns_zone_setalsonotify(zone, NULL, 0));
@ -1122,12 +1127,20 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
result = ns_config_get(maps, "notify-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj)));
dscp = cfg_obj_getdscp(obj);
if (dscp == -1)
dscp = ns_g_dscp;
RETERR(dns_zone_setnotifysrc4dscp(zone, dscp));
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
obj = NULL;
result = ns_config_get(maps, "notify-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj)));
dscp = cfg_obj_getdscp(obj);
if (dscp == -1)
dscp = ns_g_dscp;
RETERR(dns_zone_setnotifysrc6dscp(zone, dscp));
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
obj = NULL;
@ -1550,14 +1563,15 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
(void)cfg_map_get(zoptions, "masters", &obj);
if (obj != NULL) {
addrs = NULL;
dscps = NULL;
keynames = NULL;
RETERR(ns_config_getipandkeylist(config, obj, mctx,
&addrs, &keynames,
&count));
&addrs, &dscps,
&keynames, &count));
result = dns_zone_setmasterswithkeys(mayberaw, addrs,
keynames, count);
if (count != 0)
ns_config_putipandkeylist(mctx, &addrs,
ns_config_putipandkeylist(mctx, &addrs, &dscps,
&keynames, count);
else
INSIST(addrs == NULL && keynames == NULL);
@ -1609,6 +1623,10 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
RETERR(dns_zone_setxfrsource4(mayberaw,
cfg_obj_assockaddr(obj)));
dscp = cfg_obj_getdscp(obj);
if (dscp == -1)
dscp = ns_g_dscp;
RETERR(dns_zone_setxfrsource4dscp(mayberaw, dscp));
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
obj = NULL;
@ -1616,6 +1634,10 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
RETERR(dns_zone_setxfrsource6(mayberaw,
cfg_obj_assockaddr(obj)));
dscp = cfg_obj_getdscp(obj);
if (dscp == -1)
dscp = ns_g_dscp;
RETERR(dns_zone_setxfrsource6dscp(mayberaw, dscp));
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
obj = NULL;
@ -1623,12 +1645,20 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
RETERR(dns_zone_setaltxfrsource4(mayberaw,
cfg_obj_assockaddr(obj)));
dscp = cfg_obj_getdscp(obj);
if (dscp == -1)
dscp = ns_g_dscp;
RETERR(dns_zone_setaltxfrsource4dscp(mayberaw, dscp));
obj = NULL;
result = ns_config_get(maps, "alt-transfer-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
RETERR(dns_zone_setaltxfrsource6(mayberaw,
cfg_obj_assockaddr(obj)));
dscp = cfg_obj_getdscp(obj);
if (dscp == -1)
dscp = ns_g_dscp;
RETERR(dns_zone_setaltxfrsource6dscp(mayberaw, dscp));
obj = NULL;
(void)ns_config_get(maps, "use-alt-transfer-source", &obj);

View file

@ -204,15 +204,17 @@ create_view(void) {
attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr,
taskmgr, &any4, 512, 6, 1024,
17, 19, attrs, attrs, &disp4)
taskmgr, &any4,
512, 6, 1024, 17, 19,
attrs, attrs, &disp4)
== ISC_R_SUCCESS);
INSIST(disp4 != NULL);
attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP;
RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr,
taskmgr, &any6, 512, 6, 1024,
17, 19, attrs, attrs, &disp6)
taskmgr, &any6,
512, 6, 1024, 17, 19,
attrs, attrs, &disp6)
== ISC_R_SUCCESS);
INSIST(disp6 != NULL);

View file

@ -53,9 +53,9 @@ setup_create_dispatch_v4(void)
isc_sockaddr_t local_address;
isc_sockaddr_any(&local_address);
CHECK(dns_dispatch_getudp(dispatch_manager, socket_manager, task_manager,
&local_address, 4096, 100, 100, 100, 500,
0, 0, /* unsigned int attributes, unsigned int mask, */
CHECK(dns_dispatch_getudp(dispatch_manager, socket_manager,
task_manager, &local_address,
4096, 100, 100, 100, 500, 0, 0,
&dispatch_v4));
}
static void

View file

@ -35,6 +35,7 @@ options {
datasize 104857600;
deallocate-on-exit yes;
directory ".";
dscp 41;
dump-file "named_dumpdb";
fake-iquery yes;
files 1000;
@ -47,10 +48,10 @@ options {
listen-on port 90 {
"any";
};
listen-on port 100 {
listen-on port 100 dscp 33 {
127.0.0.1/32;
};
listen-on-v6 port 53 {
listen-on-v6 port 53 dscp 57 {
"none";
};
match-mapped-addresses yes;
@ -67,6 +68,7 @@ options {
serial-query-rate 100;
server-id none;
max-cache-size 20000000000000;
transfer-source 0.0.0.0 dscp 63;
zone-statistics none;
};
view "first" {
@ -77,6 +79,7 @@ view "first" {
type master;
file "xxx";
update-policy local;
notify-source 10.10.10.10 port 53 dscp 55;
};
dnssec-lookaside auto;
dnssec-validation auto;

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
options {
port 999999;
dscp 222;
listen-on port 100 dscp 444 {
127.0.0.1/32;
};
};
zone "example" {
type master;
file "example.db";
};

View file

@ -43,6 +43,12 @@ do
status=`expr $status + $ret`
done
echo "I: checking that named-checkconf catches range errors"
ret=0
$CHECKCONF range.conf > /dev/null 2>&1 && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: checking named-checkconf dnssec warnings"
ret=0
$CHECKCONF dnssec.1 2>&1 | grep 'validation yes.*enable no' > /dev/null || ret=1

View file

@ -60,7 +60,7 @@ ARPANAME=$TOP/bin/tools/arpaname
SUBDIRS="acl additional allow_query addzone autosign builtin
cacheclean checkconf @CHECKDS@ checknames checkzone @COVERAGE@
database dlv dlvauto dlz dlzexternal dlzredir dname dns64 dnssec
dsdigest ecdsa formerr forward glue gost ixfr inline limits
dsdigest dscp ecdsa formerr forward glue gost ixfr inline limits
logfileconfig lwresd masterfile masterformat metadata
notify nsupdate pending pkcs11 redirect resolver rndc rpz
rrl rrsetorder rsabigexponent sortlist smartsign staticstub

View file

@ -21,9 +21,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.4;
notify-source 10.53.0.4;
transfer-source 10.53.0.4;
query-source address 10.53.0.4 dscp 1;
notify-source 10.53.0.4 dscp 2;
transfer-source 10.53.0.4 dscp 3;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.4; };

View file

@ -21,9 +21,10 @@
controls { /* empty */ };
options {
query-source address 10.53.0.4;
notify-source 10.53.0.4;
transfer-source 10.53.0.4;
query-source address 10.53.0.4 dscp 4;
notify-source 10.53.0.4 dscp 5;
transfer-source 10.53.0.4 dscp 6;
dscp 16;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.4; };

View file

@ -0,0 +1,2 @@
rm -f */root.bk
rm -f dig.out.10.53.0.?

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 46;
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type master;
file "root.db";
};

View file

@ -0,0 +1,8 @@
$TTL 3600
. SOA ns1.nil-servers. marka.isc.org. 1 3600 1200 3600000 1200
. NS ns1.nil-servers.
. NS ns2.nil-servers.
ns1.nil-servers. A 10.53.0.1
ns2.nil-servers. A 10.53.0.2
xxx.example. A 10.53.0.1
xxx.tld. A 10.53.0.1

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,36 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 46;
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type slave;
file "root.bk";
masters { 10.53.0.1; };
};

View file

@ -0,0 +1,5 @@
$TTL 3600
. NS ns1.nil-servers.
. NS ns2.nil-servers.
ns1.nil-servers. A 10.53.0.1
ns2.nil-servers. A 10.53.0.2

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 46;
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
notify yes;
};
zone "." {
type hint;
file "hint.db";
};

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 47;
query-source dscp 46 address 10.53.0.4;
notify-source 10.53.0.4 dscp 46;
transfer-source 10.53.0.4 dscp 46;
port 5300;
pid-file "named.pid";
listen-on dscp 46 { 10.53.0.4; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type master;
file "root.db";
};

View file

@ -0,0 +1,8 @@
$TTL 3600
. SOA ns4.nil-servers. marka.isc.org. 1 3600 1200 3600000 1200
. NS ns4.nil-servers.
. NS ns5.nil-servers.
ns4.nil-servers. A 10.53.0.4
ns5.nil-servers. A 10.53.0.5
xxx.example. A 10.53.0.1
xxx.tld. A 10.53.0.1

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 47;
query-source dscp 46 address 10.53.0.5;
notify-source 10.53.0.5 dscp 46;
transfer-source 10.53.0.5 dscp 46;
alt-transfer-source 10.53.0.5 dscp 46;
port 5300;
pid-file "named.pid";
listen-on dscp 46 { 10.53.0.5; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type slave;
file "root.bk";
masters { 10.53.0.4; };
};

View file

@ -0,0 +1,5 @@
$TTL 3600
. NS ns4.nil-servers.
. NS ns5.nil-servers.
ns4.nil-servers. A 10.53.0.4
ns5.nil-servers. A 10.53.0.5

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 47;
query-source dscp 46 address 10.53.0.6;
notify-source 10.53.0.6 dscp 46;
transfer-source 10.53.0.6 dscp 46;
port 5300;
pid-file "named.pid";
listen-on dscp 46 { 10.53.0.6; };
listen-on-v6 { none; };
notify yes;
};
zone "." {
type hint;
file "hint.db";
};

View file

@ -0,0 +1 @@
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
dscp 47;
query-source dscp 46 address 10.53.0.7;
notify-source 10.53.0.7 dscp 47;
transfer-source 10.53.0.7 dscp 47;
alt-transfer-source 10.53.0.7 dscp 47;
port 5300;
pid-file "named.pid";
listen-on dscp 46 { 10.53.0.7; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type slave;
file "root.bk";
transfer-source 10.53.0.7 dscp 46;
notify-source 10.53.0.7 dscp 46;
alt-transfer-source 10.53.0.7 dscp 46;
masters { 10.53.0.4; };
};

View file

@ -0,0 +1,27 @@
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
DIGOPTS="+tcp +noadd +nosea +nostat +noquest"
status=0
#
# 10.53.0.1 10.53.0.2 10.53.0.3 have a global dscp setting;
# 10.53.0.4 10.53.0.5 10.53.0.6 have dscp set in option *-source clauses;
# 10.53.0.7 has dscp set in zone *-source clauses;
#
for server in 10.53.0.1 10.53.0.2 10.53.0.3 10.53.0.4 10.53.0.5 \
10.53.0.6 10.53.0.7
do
echo "I:testing root SOA lookup at $server"
for i in 0 1 2 3 4 5 6 7 8 9
do
ret=0
$DIG -p 5300 @$server $DIGOPTS soa . > dig.out.$server
grep "status: NOERROR" dig.out.$server > /dev/null || ret=1
test $ret = 0 && break
sleep 1
done
test $ret = 0 || { echo "I:failed"; status=`expr $status + $ret`; }
done
exit $status

View file

@ -20,9 +20,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
query-source address 10.53.0.1 dscp 1;
notify-source 10.53.0.1 dscp 22;
transfer-source 10.53.0.1 dscp 3;
port 5300;
pid-file "named.pid";
session-keyfile "session.key";

View file

@ -20,9 +20,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
query-source address 10.53.0.2 dscp 4;
notify-source 10.53.0.2 dscp 5;
transfer-source 10.53.0.2 dscp 6;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };

View file

@ -21,9 +21,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
query-source address 10.53.0.3 dscp 7;
notify-source 10.53.0.3 dscp 8;
transfer-source 10.53.0.3 dscp 9;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.3; };

View file

@ -20,9 +20,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
query-source address 10.53.0.1 dscp 1;
notify-source 10.53.0.1 dscp 2;
transfer-source 10.53.0.1 dscp 3;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };

View file

@ -21,9 +21,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.4;
notify-source 10.53.0.4;
transfer-source 10.53.0.4;
query-source address 10.53.0.4 dscp 4;
notify-source 10.53.0.4 dscp 5;
transfer-source 10.53.0.4 dscp 6;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.4; };

View file

@ -21,9 +21,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.5;
notify-source 10.53.0.5;
transfer-source 10.53.0.5;
query-source address 10.53.0.5 dscp 7;
notify-source 10.53.0.5 dscp 8;
transfer-source 10.53.0.5 dscp 9;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.5; };

View file

@ -21,9 +21,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.6;
notify-source 10.53.0.6;
transfer-source 10.53.0.6;
query-source address 10.53.0.6 dscp 10;
notify-source 10.53.0.6 dscp 11;
transfer-source 10.53.0.6 dscp 12;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.6; };

View file

@ -21,9 +21,9 @@
controls { /* empty */ };
options {
query-source address 10.53.0.7;
notify-source 10.53.0.7;
transfer-source 10.53.0.7;
query-source address 10.53.0.7 dscp 13;
notify-source 10.53.0.7 dscp 14;
transfer-source 10.53.0.7 dscp 15;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.7; };

View file

@ -3279,6 +3279,21 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para>
<varname>ip_dscp</varname>
</para>
</entry>
<entry colname="2">
<para>
A <varname>number</varname> between 0 and 63, used
to select a differentiated services code point (DSCP)
value for use with outgoing traffic on operating systems
that support DSCP.
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para>
@ -5170,8 +5185,8 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</para>
<programlisting><command>lwres</command> {
<optional> listen-on { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> listen-on { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> view <replaceable>view_name</replaceable>; </optional>
<optional> search { <replaceable>domain_name</replaceable> ; <optional> <replaceable>domain_name</replaceable> ; ... </optional> }; </optional>
<optional> ndots <replaceable>number</replaceable>; </optional>
@ -5238,7 +5253,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<title><command>masters</command> Statement Grammar</title>
<programlisting>
<command>masters</command> <replaceable>name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> |
<command>masters</command> <replaceable>name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> { ( <replaceable>masters_list</replaceable> |
<replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> };
</programlisting>
@ -5313,10 +5328,10 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> dnssec-must-be-secure <replaceable>domain yes_or_no</replaceable>; </optional>
<optional> dnssec-accept-expired <replaceable>yes_or_no</replaceable>; </optional>
<optional> forward ( <replaceable>only</replaceable> | <replaceable>first</replaceable> ); </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> dual-stack-servers <optional>port <replaceable>ip_port</replaceable></optional> {
( <replaceable>domain_name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> |
<replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ) ;
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> dual-stack-servers <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> {
( <replaceable>domain_name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> |
<replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional>) ;
... }; </optional>
<optional> check-names ( <replaceable>master</replaceable> | <replaceable>slave</replaceable> | <replaceable>response</replaceable> )
( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
@ -5350,16 +5365,21 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> avoid-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> use-v6-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> avoid-v6-udp-ports { <replaceable>port_list</replaceable> }; </optional>
<optional> listen-on <optional> port <replaceable>ip_port</replaceable> </optional> { <replaceable>address_match_list</replaceable> }; </optional>
<optional> listen-on-v6 <optional> port <replaceable>ip_port</replaceable> </optional> { <replaceable>address_match_list</replaceable> }; </optional>
<optional> listen-on <optional> port <replaceable>ip_port</replaceable> </optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> { <replaceable>address_match_list</replaceable> }; </optional>
<optional> listen-on-v6 <optional> port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional>
{ <replaceable>address_match_list</replaceable> }; </optional>
<optional> query-source ( ( <replaceable>ip4_addr</replaceable> | <replaceable>*</replaceable> )
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>
<optional> dscp <replaceable>ip_dscp</replaceable></optional> |
<optional> address ( <replaceable>ip4_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> )
<optional> dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> query-source-v6 ( ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> )
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>
<optional> dscp <replaceable>ip_dscp</replaceable></optional> |
<optional> address ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> )
<optional> dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> use-queryport-pool <replaceable>yes_or_no</replaceable>; </optional>
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
<optional> queryport-pool-updateinterval <replaceable>number</replaceable>; </optional>
@ -5377,19 +5397,18 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> transfers-in <replaceable>number</replaceable>; </optional>
<optional> transfers-out <replaceable>number</replaceable>; </optional>
<optional> transfers-per-ns <replaceable>number</replaceable>; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
<optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> use-alt-transfer-source <replaceable>yes_or_no</replaceable>; </optional>
<optional> notify-delay <replaceable>seconds</replaceable> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> notify-to-soa <replaceable>yes_or_no</replaceable> ; </optional>
<optional> also-notify { <replaceable>ip_addr</replaceable>
<optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>keyname</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>keyname</replaceable></optional> ; ... </optional> }; </optional>
<optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> <optional>key <replaceable>keyname</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> <optional>key <replaceable>keyname</replaceable></optional> ; ... </optional> }; </optional>
<optional> max-ixfr-log-size <replaceable>number</replaceable>; </optional>
<optional> max-journal-size <replaceable>size_spec</replaceable>; </optional>
<optional> coresize <replaceable>size_spec</replaceable> ; </optional>
@ -5420,6 +5439,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> min-retry-time <replaceable>number</replaceable> ; </optional>
<optional> max-retry-time <replaceable>number</replaceable> ; </optional>
<optional> port <replaceable>ip_port</replaceable>; </optional>
<optional> dscp <replaceable>ip_dscp</replaceable></optional> ;
<optional> additional-from-auth <replaceable>yes_or_no</replaceable> ; </optional>
<optional> additional-from-cache <replaceable>yes_or_no</replaceable> ; </optional>
<optional> random-device <replaceable>path_name</replaceable> ; </optional>
@ -10275,14 +10295,14 @@ ns.domain.com.rpz-nsdname CNAME .
<optional> transfers <replaceable>number</replaceable> ; </optional>
<optional> transfer-format <replaceable>( one-answer | many-answers )</replaceable> ; ]</optional>
<optional> keys <replaceable>{ string ; <optional> string ; <optional>...</optional></optional> }</replaceable> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> query-source <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> query-source-v6 <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> use-queryport-pool <replaceable>yes_or_no</replaceable>; </optional>
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
<optional> queryport-pool-updateinterval <replaceable>number</replaceable>; </optional>
@ -10930,8 +10950,8 @@ view "external" {
<optional> dnssec-dnskey-kskonly <replaceable>yes_or_no</replaceable>; </optional>
<optional> dnssec-loadkeys-interval <replaceable>number</replaceable>; </optional>
<optional> update-policy <replaceable>local</replaceable> | { <replaceable>update_policy_rule</replaceable> <optional>...</optional> }; </optional>
<optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
<optional> check-mx (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
<optional> check-wildcard <replaceable>yes_or_no</replaceable>; </optional>
@ -10942,7 +10962,7 @@ view "external" {
<optional> journal <replaceable>string</replaceable> ; </optional>
<optional> max-journal-size <replaceable>size_spec</replaceable>; </optional>
<optional> forward (<constant>only</constant>|<constant>first</constant>) ; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> ixfr-base <replaceable>string</replaceable> ; </optional>
<optional> ixfr-from-differences <replaceable>yes_or_no</replaceable>; </optional>
<optional> ixfr-tmp-file <replaceable>string</replaceable> ; </optional>
@ -10955,8 +10975,8 @@ view "external" {
<optional> notify-delay <replaceable>seconds</replaceable> ; </optional>
<optional> notify-to-soa <replaceable>yes_or_no</replaceable>; </optional>
<optional> pubkey <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> zone-statistics <replaceable>full</replaceable> | <replaceable>terse</replaceable> | <replaceable>none</replaceable>; </optional>
<optional> sig-validity-interval <replaceable>number</replaceable> <optional><replaceable>number</replaceable></optional> ; </optional>
<optional> sig-signing-nodes <replaceable>number</replaceable> ; </optional>
@ -10987,8 +11007,9 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> dnssec-loadkeys-interval <replaceable>number</replaceable>; </optional>
<optional> dnssec-secure-to-insecure <replaceable>yes_or_no</replaceable> ; </optional>
<optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
<optional> also-notify <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
<optional> also-notify <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
<optional>port <replaceable>ip_port</replaceable></optional>
<optional>dscp <replaceable>ip_dscp</replaceable></optional>
<optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
<optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
<optional> dialup <replaceable>dialup_option</replaceable> ; </optional>
@ -10997,13 +11018,14 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> journal <replaceable>string</replaceable> ; </optional>
<optional> max-journal-size <replaceable>size_spec</replaceable>; </optional>
<optional> forward (<constant>only</constant>|<constant>first</constant>) ; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> ixfr-base <replaceable>string</replaceable> ; </optional>
<optional> ixfr-from-differences <replaceable>yes_or_no</replaceable>; </optional>
<optional> ixfr-tmp-file <replaceable>string</replaceable> ; </optional>
<optional> maintain-ixfr-base <replaceable>yes_or_no</replaceable> ; </optional>
<optional> masters <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
<optional> masters <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
<optional>port <replaceable>ip_port</replaceable></optional>
<optional>dscp <replaceable>ip_dscp</replaceable></optional>
<optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
<optional> max-ixfr-log-size <replaceable>number</replaceable> ; </optional>
<optional> max-transfer-idle-in <replaceable>number</replaceable> ; </optional>
@ -11014,14 +11036,15 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> notify-delay <replaceable>seconds</replaceable> ; </optional>
<optional> notify-to-soa <replaceable>yes_or_no</replaceable>; </optional>
<optional> pubkey <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
<optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional>port <replaceable>ip_port</replaceable></optional>
<optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> use-alt-transfer-source <replaceable>yes_or_no</replaceable>; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> zone-statistics <replaceable>full</replaceable> | <replaceable>terse</replaceable> | <replaceable>none</replaceable>; </optional>
<optional> sig-validity-interval <replaceable>number</replaceable> <optional><replaceable>number</replaceable></optional> ; </optional>
<optional> sig-signing-nodes <replaceable>number</replaceable> ; </optional>
@ -11056,19 +11079,20 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> file <replaceable>string</replaceable> ; </optional>
<optional> masterfile-format (<constant>text</constant>|<constant>raw</constant>|<constant>map</constant>) ; </optional>
<optional> forward (<constant>only</constant>|<constant>first</constant>) ; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> masters <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> masters <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
<optional>port <replaceable>ip_port</replaceable></optional>
<optional>dscp <replaceable>ip_dscp</replaceable></optional>
<optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
<optional> max-transfer-idle-in <replaceable>number</replaceable> ; </optional>
<optional> max-transfer-time-in <replaceable>number</replaceable> ; </optional>
<optional> pubkey <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
<optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
<optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; </optional>
<optional> use-alt-transfer-source <replaceable>yes_or_no</replaceable>; </optional>
<optional> zone-statistics <replaceable>yes_or_no</replaceable> ; </optional>
<optional> database <replaceable>string</replaceable> ; </optional>
@ -11090,7 +11114,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
type forward;
<optional> forward (<constant>only</constant>|<constant>first</constant>) ; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>dscp <replaceable>ip_dscp</replaceable></optional> ; ... </optional> }; </optional>
<optional> delegation-only <replaceable>yes_or_no</replaceable> ; </optional>
};

133
doc/design/dscp Normal file
View file

@ -0,0 +1,133 @@
Differentiate Services Code Point Support
$Id: dscp,v 1.1.2.1 2012/02/24 05:20:36 marka Exp $
Differentiate Services Code Point (DSCP) is implemented in IPv4 using the
TOS octet and in IPv6 using the TCLASS octet.
RFC 3542 defines the api to manipulate the TCLASS octet as part of
the advanced socket API. TCLASS is settable on both a socket and
packet basis (setsockopt/sendmsg) and the sent value can be retrieved
using recvmsg over UDP. Retrieval is undefined for TCP.
The Advanced socket API was not incorporated into the POSIX socket
API for IPv6 and may not be completely implemented in any OS.
For TOS setsockopt() supports setting of the field on a persocket
basis. TOS may also be set on a per packet basis on some OS using
sendmsg. If it is not supported the sendmsg call reports a error.
Support can only be determined by attempted to send a packet with
the option set. Retrieval of the sent TOS value is retrievable on
Linux. This can be determined at compile time.
DSCP values need to be compatible with TOS values as it is a re-use
of the field.
LIBISC:
We will need to be able to probe for the level of DSCP support. We
need to know if we can set it at the socket level, packet level and
if we can retrieve the DSCP value sent. This needs to be done
independently for IPv4 and IPv6.
#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */
#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */
#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */
#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */
#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */
#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */
#define ISC_NET_DSCPALL 0x3f /* All valid flags */
unsigned int
isc_net_probedscp(void);
/*%<
* Probe the level of DSCP support.
*/
We also need to be able to set DSCP values on a per socket basis, per packet
basis and to retrieve dscp values from received packet.
Setting dscp on a per socket basis shall be done using isc_socket_dscp.
void
isc_socket_dscp(isc_socket_t *sock, unsigned int dscp);
/*%<
* Requires:
*\li 'sock' is a valid socket.
*/
/*@}*/
isc_socketevent shall be extended to support the sending of and retrieval
of DSCP values. If ISC_SOCKEVENTATTR_DSCP is set then isc_socket_sendto2
shall set the DSCP value. isc_socket_recv shall set ISC_SOCKEVENTATTR_DSCP
and the dscp element if the OS returns the value via recvmsg.
#define ISC_SOCKEVENTATTR_DSCP 0x00040000U /* public */
struct isc_socketevent {
ISC_EVENT_COMMON(isc_socketevent_t);
isc_result_t result; /*%< OK, EOF, whatever else */
unsigned int minimum; /*%< minimum i/o for event */
unsigned int n; /*%< bytes read or written */
unsigned int offset; /*%< offset into buffer list */
isc_region_t region; /*%< for single-buffer i/o */
isc_bufferlist_t bufferlist; /*%< list of buffers */
isc_sockaddr_t address; /*%< source address */
isc_time_t timestamp; /*%< timestamp of packet recv */
struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */
isc_uint32_t attributes; /*%< see below */
isc_eventdestructor_t destroy; /*%< original destructor */
unsigned int dscp; /*%< UDP dscp value */
};
A convience function will be provided to allocate and intialize the structure.
isc_socketevent_t *
isc_socket_socketevent(isc_socket_t *sock0, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
NAMED/LIBDNS:
Named needs to be able to set the DSCP value of sent traffic. We should
be able to set DSCP for all TCP connections.
For UDP we should have a default DSCP value for when we can't set this on
a per packet basis with the ability to override for specific destinations.
options/view/server;
tcp-dscp <value>;
udp-dscp <value>;
http://bogpeople.com/networking/dscp.shtml list a set of TOS compatible
values (below).
DSCP Name DS Field Value IP Precedence
Binary Decimal
CS0 000 000 0 0
CS1 001 000 8 1
AF11 001 010 10 1
AF12 001 100 12 1
AF13 001 110 14 1
CS2 010 000 16 2
AF21 010 010 18 2
AF22 010 100 20 2
AF23 010 110 22 2
CS3 011 000 24 3
AF31 011 010 26 3
AF32 011 100 28 3
AF33 011 110 30 3
CS4 100 000 32 4
AF41 100 010 34 4
AF42 100 100 36 4
AF43 100 110 38 4
CS5 101 000 40 5
EF 101 110 46 5
CS6 110 000 48 6
CS7 111 000 56 7
CS Class Selector (RFC 2474)
AFxy Assured Forwarding (x=class, y=drop precedence) (RFC2597)
EF Expedited Forwarding (RFC 3246)
value should be one of these or a numeric 0..63. The default value is 0.

View file

@ -38,8 +38,8 @@ logging {
};
lwres {
listen-on [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
[ port <integer> ]; ... };
listen-on [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
ndots <integer>;
search { <string>; ... };
view <string> <optional_class>;
@ -48,8 +48,9 @@ lwres {
managed-keys { <string> <string> <integer> <integer> <integer>
<quoted_string>; ... };
masters <string> [ port <integer> ] { ( <masters> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
masters <string> [ port <integer> ] [ dscp <integer> ] { ( <masters> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] )
[ key <string> ]; ... };
options {
acache-cleaning-interval <integer>;
@ -68,12 +69,13 @@ options {
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
allow-v6-synthesis { <address_match_element>; ... }; // obsolete
also-notify [ port <integer> ] { ( <masters> | <ipv4_address> [
port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
also-notify [ port <integer> ] [ dscp <integer> ] { ( <masters> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
* ) ];
* ) ] [ dscp <integer> ];
attach-cache <string>;
auth-nxdomain <boolean>; // default changed
auto-dnssec ( allow | maintain | off );
@ -123,9 +125,11 @@ options {
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
dscp <integer>;
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ); ... };
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
<integer> ] [ dscp <integer> ] ); ... };
dump-file <quoted_string>;
edns-udp-size <integer>;
empty-contact <string>;
@ -134,13 +138,13 @@ options {
fake-iquery <boolean>; // obsolete
fetch-glue <boolean>; // obsolete
files <size>;
filter-aaaa { <address_match_element>; ... }; // not configured
filter-aaaa-on-v4 <filter_aaaa>; // not configured
filter-aaaa-on-v6 <filter_aaaa>; // not configured
filter-aaaa { <address_match_element>; ... };
filter-aaaa-on-v4 <filter_aaaa>;
filter-aaaa-on-v6 <filter_aaaa>;
flush-zones-on-shutdown <boolean>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
[ port <integer> ]; ... };
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
has-old-clients <boolean>; // obsolete
heartbeat-interval <integer>;
host-statistics <boolean>; // not implemented
@ -151,8 +155,10 @@ options {
ixfr-from-differences <ixfrdiff>;
key-directory <quoted_string>;
lame-ttl <integer>;
listen-on [ port <integer> ] { <address_match_element>; ... };
listen-on-v6 [ port <integer> ] { <address_match_element>; ... };
listen-on [ port <integer> ] [ dscp <integer> ] {
<address_match_element>; ... };
listen-on-v6 [ port <integer> ] [ dscp <integer> ] {
<address_match_element>; ... };
maintain-ixfr-base <boolean>; // obsolete
managed-keys-directory <quoted_string>;
masterfile-format ( text | raw | map );
@ -183,8 +189,10 @@ options {
named-xfer <quoted_string>; // obsolete
notify <notifytype>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ]
[ dscp <integer> ];
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
pid-file ( <quoted_string> | none );
@ -256,8 +264,10 @@ options {
tkey-gssapi-keytab <quoted_string>;
topology { <address_match_element>; ... }; // not implemented
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
transfers-in <integer>;
transfers-out <integer>;
transfers-per-ns <integer>;
@ -282,16 +292,20 @@ server <netprefix> {
edns-udp-size <integer>;
keys <server_key>;
max-udp-size <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ]
[ dscp <integer> ];
provide-ixfr <boolean>;
query-source <querysource4>;
query-source-v6 <querysource6>;
request-ixfr <boolean>;
support-ixfr <boolean>; // obsolete
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
transfers <integer>;
};
@ -319,12 +333,13 @@ view <string> <optional_class> {
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
allow-v6-synthesis { <address_match_element>; ... }; // obsolete
also-notify [ port <integer> ] { ( <masters> | <ipv4_address> [
port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
also-notify [ port <integer> ] [ dscp <integer> ] { ( <masters> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
* ) ];
* ) ] [ dscp <integer> ];
attach-cache <string>;
auth-nxdomain <boolean>; // default changed
auto-dnssec ( allow | maintain | off );
@ -372,19 +387,20 @@ view <string> <optional_class> {
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ); ... };
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
<integer> ] [ dscp <integer> ] ); ... };
edns-udp-size <integer>;
empty-contact <string>;
empty-server <string>;
empty-zones-enable <boolean>;
fetch-glue <boolean>; // obsolete
filter-aaaa { <address_match_element>; ... }; // not configured
filter-aaaa-on-v4 <filter_aaaa>; // not configured
filter-aaaa-on-v6 <filter_aaaa>; // not configured
filter-aaaa { <address_match_element>; ... };
filter-aaaa-on-v4 <filter_aaaa>;
filter-aaaa-on-v6 <filter_aaaa>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
[ port <integer> ]; ... };
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
inline-signing <boolean>;
ixfr-from-differences <ixfrdiff>;
key <string> {
@ -421,8 +437,10 @@ view <string> <optional_class> {
multi-master <boolean>;
notify <notifytype>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ]
[ dscp <integer> ];
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
preferred-glue <string>;
@ -471,9 +489,9 @@ view <string> <optional_class> {
keys <server_key>;
max-udp-size <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | *
) ];
) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer>
| * ) ];
| * ) ] [ dscp <integer> ];
provide-ixfr <boolean>;
query-source <querysource4>;
query-source-v6 <querysource6>;
@ -481,9 +499,9 @@ view <string> <optional_class> {
support-ixfr <boolean>; // obsolete
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) [ port ( <integer> |
* ) ];
* ) ] [ dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port (
<integer> | * ) ];
<integer> | * ) ] [ dscp <integer> ];
transfers <integer>;
};
sig-signing-nodes <integer>;
@ -494,8 +512,10 @@ view <string> <optional_class> {
suppress-initial-notify <boolean>; // not yet implemented
topology { <address_match_element>; ... }; // not implemented
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
trusted-keys { <string> <integer> <integer> <integer>
<quoted_string>; ... };
try-tcp-refresh <boolean>;
@ -511,13 +531,14 @@ view <string> <optional_class> {
allow-transfer { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <masters> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [
port <integer> ] ) [ key <string> ]; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { (
<masters> | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ) [ key <string> ];
... };
alt-transfer-source ( <ipv4_address> | * ) [ port (
<integer> | * ) ];
<integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port (
<integer> | * ) ];
<integer> | * ) ] [ dscp <integer> ];
auto-dnssec ( allow | maintain | off );
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
@ -537,8 +558,9 @@ view <string> <optional_class> {
dnssec-update-mode ( maintain | no-resign );
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> |
<ipv6_address> ) [ port <integer> ]; ... };
forwarders [ port <integer> ] [ dscp <integer> ] { (
<ipv4_address> | <ipv6_address> ) [ port <integer> ] [
dscp <integer> ]; ... };
inline-signing <boolean>;
ixfr-base <quoted_string>; // obsolete
ixfr-from-differences <boolean>;
@ -547,9 +569,9 @@ view <string> <optional_class> {
key-directory <quoted_string>;
maintain-ixfr-base <boolean>; // obsolete
masterfile-format ( text | raw | map );
masters [ port <integer> ] { ( <masters> | <ipv4_address> [
port <integer> ] | <ipv6_address> [ port <integer> ] )
[ key <string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <masters>
| <ipv4_address> [ port <integer> ] | <ipv6_address> [
port <integer> ] ) [ key <string> ]; ... };
max-ixfr-log-size <size>; // obsolete
max-journal-size <size_no_default>;
max-refresh-time <integer>;
@ -564,9 +586,9 @@ view <string> <optional_class> {
notify <notifytype>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | *
) ];
) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer>
| * ) ];
| * ) ] [ dscp <integer> ];
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
pubkey <integer> <integer> <integer>
@ -581,9 +603,9 @@ view <string> <optional_class> {
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ];
transfer-source ( <ipv4_address> | * ) [ port ( <integer> |
* ) ];
* ) ] [ dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port (
<integer> | * ) ];
<integer> | * ) ] [ dscp <integer> ];
try-tcp-refresh <boolean>;
type ( master | slave | stub | static-stub | hint | forward
| delegation-only | redirect );
@ -607,12 +629,13 @@ zone <string> <optional_class> {
allow-transfer { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <masters> | <ipv4_address> [
port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
also-notify [ port <integer> ] [ dscp <integer> ] { ( <masters> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
* ) ];
* ) ] [ dscp <integer> ];
auto-dnssec ( allow | maintain | off );
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
@ -632,8 +655,8 @@ zone <string> <optional_class> {
dnssec-update-mode ( maintain | no-resign );
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
[ port <integer> ]; ... };
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
inline-signing <boolean>;
ixfr-base <quoted_string>; // obsolete
ixfr-from-differences <boolean>;
@ -642,9 +665,9 @@ zone <string> <optional_class> {
key-directory <quoted_string>;
maintain-ixfr-base <boolean>; // obsolete
masterfile-format ( text | raw | map );
masters [ port <integer> ] { ( <masters> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key
<string> ]; ... };
masters [ port <integer> ] [ dscp <integer> ] { ( <masters> |
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
<integer> ] ) [ key <string> ]; ... };
max-ixfr-log-size <size>; // obsolete
max-journal-size <size_no_default>;
max-refresh-time <integer>;
@ -658,8 +681,10 @@ zone <string> <optional_class> {
multi-master <boolean>;
notify <notifytype>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ]
[ dscp <integer> ];
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
pubkey <integer> <integer> <integer> <quoted_string>; // obsolete
@ -672,8 +697,10 @@ zone <string> <optional_class> {
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ];
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [
dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
try-tcp-refresh <boolean>;
type ( master | slave | stub | static-stub | hint | forward |
delegation-only | redirect );

View file

@ -747,6 +747,28 @@ typedef enum {
optlevel_zone
} optlevel_t;
static isc_result_t
check_dscp(const cfg_obj_t *options, isc_log_t *logctx) {
isc_result_t result = ISC_R_SUCCESS;
const cfg_obj_t *obj = NULL;
/*
* Check that DSCP setting is within range
*/
obj = NULL;
(void)cfg_map_get(options, "dscp", &obj);
if (obj != NULL) {
isc_uint32_t dscp = cfg_obj_asuint32(obj);
if (dscp >= 64) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"'dscp' out of range (0-63)");
result = ISC_R_FAILURE;
}
}
return (result);
}
static isc_result_t
check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
optlevel_t optlevel)
@ -1128,6 +1150,10 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
result = ISC_R_FAILURE;
}
tresult = check_dscp(options, logctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
return (result);
}

View file

@ -1946,6 +1946,7 @@ new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
ai->srtt = entry->srtt;
ai->flags = entry->flags;
ai->entry = entry;
ai->dscp = -1;
ISC_LINK_INIT(ai, publink);
return (ai);

View file

@ -228,6 +228,7 @@ struct dns_dispatch {
isc_socket_t *socket; /*%< isc socket attached to */
isc_sockaddr_t local; /*%< local address */
in_port_t localport; /*%< local UDP port */
isc_dscp_t dscp; /*%< "listen-on" DSCP value */
unsigned int maxrequests; /*%< max requests */
isc_event_t *ctlevent;
@ -2624,6 +2625,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL);
disp->port_table = NULL;
disp->portpool = NULL;
disp->dscp = -1;
result = isc_mutex_init(&disp->lock);
if (result != ISC_R_SUCCESS)
@ -3863,6 +3865,18 @@ dns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
*dsetp = NULL;
}
void
dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp) {
REQUIRE(VALID_DISPATCH(disp));
disp->dscp = dscp;
}
isc_dscp_t
dns_dispatch_getdscp(dns_dispatch_t *disp) {
REQUIRE(VALID_DISPATCH(disp));
return (disp->dscp);
}
#if 0
void
dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) {

View file

@ -84,12 +84,12 @@ dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) {
}
isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy)
dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name,
dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t fwdpolicy)
{
isc_result_t result;
dns_forwarders_t *forwarders;
isc_sockaddr_t *sa, *nsa;
dns_forwarder_t *fwd, *nfwd;
REQUIRE(VALID_FWDTABLE(fwdtable));
@ -97,19 +97,19 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
if (forwarders == NULL)
return (ISC_R_NOMEMORY);
ISC_LIST_INIT(forwarders->addrs);
for (sa = ISC_LIST_HEAD(*addrs);
sa != NULL;
sa = ISC_LIST_NEXT(sa, link))
ISC_LIST_INIT(forwarders->fwdrs);
for (fwd = ISC_LIST_HEAD(*fwdrs);
fwd != NULL;
fwd = ISC_LIST_NEXT(fwd, link))
{
nsa = isc_mem_get(fwdtable->mctx, sizeof(isc_sockaddr_t));
if (nsa == NULL) {
nfwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
if (nfwd == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
*nsa = *sa;
ISC_LINK_INIT(nsa, link);
ISC_LIST_APPEND(forwarders->addrs, nsa, link);
*nfwd = *fwd;
ISC_LINK_INIT(nfwd, link);
ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
@ -123,10 +123,61 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
return (ISC_R_SUCCESS);
cleanup:
while (!ISC_LIST_EMPTY(forwarders->addrs)) {
sa = ISC_LIST_HEAD(forwarders->addrs);
ISC_LIST_UNLINK(forwarders->addrs, sa, link);
isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t));
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
isc_mem_put(fwdtable->mctx, fwd, sizeof(isc_sockaddr_t));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
return (result);
}
isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy)
{
isc_result_t result;
dns_forwarders_t *forwarders;
dns_forwarder_t *fwd;
isc_sockaddr_t *sa;
REQUIRE(VALID_FWDTABLE(fwdtable));
forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t));
if (forwarders == NULL)
return (ISC_R_NOMEMORY);
ISC_LIST_INIT(forwarders->fwdrs);
for (sa = ISC_LIST_HEAD(*addrs);
sa != NULL;
sa = ISC_LIST_NEXT(sa, link))
{
fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
if (fwd == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
fwd->addr = *sa;
fwd->dscp = -1;
ISC_LINK_INIT(fwd, link);
ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
result = dns_rbt_addname(fwdtable->table, name, forwarders);
RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
if (result != ISC_R_SUCCESS)
goto cleanup;
return (ISC_R_SUCCESS);
cleanup:
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
return (result);
@ -202,14 +253,14 @@ static void
auto_detach(void *data, void *arg) {
dns_forwarders_t *forwarders = data;
dns_fwdtable_t *fwdtable = arg;
isc_sockaddr_t *sa;
dns_forwarder_t *fwd;
UNUSED(arg);
while (!ISC_LIST_EMPTY(forwarders->addrs)) {
sa = ISC_LIST_HEAD(forwarders->addrs);
ISC_LIST_UNLINK(forwarders->addrs, sa, link);
isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t));
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
}

View file

@ -214,7 +214,9 @@ struct dns_adbaddrinfo {
unsigned int magic; /*%< private */
isc_sockaddr_t sockaddr; /*%< [rw] */
unsigned int srtt; /*%< [rw] microseconds */
unsigned int srtt; /*%< [rw] microsecs */
isc_dscp_t dscp;
unsigned int flags; /*%< [rw] */
dns_adbentry_t *entry; /*%< private */
ISC_LINK(dns_adbaddrinfo_t) publink;

View file

@ -558,6 +558,18 @@ dns_dispatchset_destroy(dns_dispatchset_t **dsetp);
*\li dset is valid
*/
void
dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp);
isc_dscp_t
dns_dispatch_getdscp(dns_dispatch_t *disp);
/*%<
* Set/get the DSCP value to be used when sending responses to clients,
* as defined in the "listen-on" or "listen-on-v6" statements.
*
* Requires:
*\li disp is valid.
*/
ISC_LANG_ENDDECLS
#endif /* DNS_DISPATCH_H */

View file

@ -29,8 +29,16 @@
ISC_LANG_BEGINDECLS
struct dns_forwarder {
isc_sockaddr_t addr;
isc_dscp_t dscp;
ISC_LINK(dns_forwarder_t) link;
};
typedef ISC_LIST(struct dns_forwarder) dns_forwarderlist_t;
struct dns_forwarders {
isc_sockaddrlist_t addrs;
dns_forwarderlist_t fwdrs;
dns_fwdpolicy_t fwdpolicy;
};
@ -49,17 +57,22 @@ dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep);
*/
isc_result_t
dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name,
dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t policy);
isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy);
/*%<
* Adds an entry to the forwarding table. The entry associates
* a domain with a list of forwarders and a forwarding policy. The
* addrs list is copied if not empty, so the caller should free its copy.
* addrs/fwdrs list is copied if not empty, so the caller should free
* its copy.
*
* Requires:
* \li fwdtable is a valid forwarding table.
* \li name is a valid name
* \li addrs is a valid list of sockaddrs, which may be empty.
* \li addrs/fwdrs is a valid list of isc_sockaddr/dns_forwarder
* structures, which may be empty.
*
* Returns:
* \li #ISC_R_SUCCESS

View file

@ -76,8 +76,11 @@ struct dns_peer {
isc_boolean_t request_nsid;
dns_name_t *key;
isc_sockaddr_t *transfer_source;
isc_dscp_t transfer_dscp;
isc_sockaddr_t *notify_source;
isc_dscp_t notify_dscp;
isc_sockaddr_t *query_source;
isc_dscp_t query_dscp;
isc_uint16_t udpsize; /* receive size */
isc_uint16_t maxudp; /* transmit size */
@ -214,6 +217,23 @@ dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source);
isc_result_t
dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source);
isc_result_t
dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp);
isc_result_t
dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp);
isc_result_t
dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp);
isc_result_t
dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp);
isc_result_t
dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp);
isc_result_t
dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp);
ISC_LANG_ENDDECLS
#endif /* DNS_PEER_H */

View file

@ -195,7 +195,7 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
*\li requestp != NULL && *requestp == NULL
*/
/*% See dns_request_createvia3() */
/*% See dns_request_createvia4() */
isc_result_t
dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
@ -204,7 +204,7 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_taskaction_t action, void *arg,
dns_request_t **requestp);
/*% See dns_request_createvia3() */
/*% See dns_request_createvia4() */
isc_result_t
dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
@ -213,6 +213,7 @@ dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp);
/*% See dns_request_createvia4() */
isc_result_t
dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
@ -221,6 +222,15 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
unsigned int udpretries, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_request_t **requestp);
isc_result_t
dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
isc_dscp_t dscp, unsigned int options,
dns_tsigkey_t *key, unsigned int timeout,
unsigned int udptimeout, unsigned int udpretries,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp);
/*%<
* Create and send a request.
*
@ -254,7 +264,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
*\li requestp != NULL && *requestp == NULL
*/
/*% See dns_request_createraw3() */
/*% See dns_request_createraw4() */
isc_result_t
dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
@ -262,7 +272,7 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp);
/*% See dns_request_createraw3() */
/*% See dns_request_createraw4() */
isc_result_t
dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
@ -271,6 +281,7 @@ dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_taskaction_t action, void *arg,
dns_request_t **requestp);
/*% See dns_request_createraw4() */
isc_result_t
dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
@ -278,6 +289,15 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
unsigned int udptimeout, unsigned int udpretries,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp);
isc_result_t
dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
isc_dscp_t dscp, unsigned int options,
unsigned int timeout, unsigned int udptimeout,
unsigned int udpretries, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_request_t **requestp);
/*!<
* \brief Create and send a request.
*

View file

@ -598,6 +598,23 @@ dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp);
* \li resolver to be valid.
*/
void
dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp);
isc_dscp_t
dns_resolver_getquerydscp4(dns_resolver_t *resolver);
void
dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp);
isc_dscp_t
dns_resolver_getquerydscp6(dns_resolver_t *resolver);
/*%
* Get and set the DSCP values for the resolver's IPv4 and IPV6 query
* sources.
*
* Requires:
* \li resolver to be valid.
*/
ISC_LANG_ENDDECLS
#endif /* DNS_RESOLVER_H */

View file

@ -80,6 +80,7 @@ typedef struct dns_dumpctx dns_dumpctx_t;
typedef struct dns_fetch dns_fetch_t;
typedef struct dns_fixedname dns_fixedname_t;
typedef struct dns_forwarders dns_forwarders_t;
typedef struct dns_forwarder dns_forwarder_t;
typedef struct dns_fwdtable dns_fwdtable_t;
typedef struct dns_iptable dns_iptable_t;
typedef isc_uint32_t dns_iterations_t;

View file

@ -67,6 +67,14 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
isc_task_t *task, dns_xfrindone_t done,
dns_xfrin_ctx_t **xfrp);
isc_result_t
dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype,
isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
isc_task_t *task, dns_xfrindone_t done,
dns_xfrin_ctx_t **xfrp);
/*%<
* Attempt to start an incoming zone transfer of 'zone'
* from 'masteraddr', creating a dns_xfrin_ctx_t object to

View file

@ -597,7 +597,11 @@ dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
isc_uint32_t count);
isc_result_t
dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
dns_name_t **keynames, isc_uint32_t count);
dns_name_t **keynames, isc_uint32_t count);
isc_result_t
dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
const isc_dscp_t *dscps, dns_name_t **keynames,
isc_uint32_t count);
/*%<
* Set the list of additional servers to be notified when
* a zone changes. To clear the list use 'count = 0'.
@ -730,6 +734,32 @@ dns_zone_getaltxfrsource4(dns_zone_t *zone);
*\li 'zone' to be a valid zone.
*/
isc_result_t
dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp);
isc_result_t
dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp);
/*%<
* Set the DSCP value associated with the transfer/alt-transfer source.
*
* Require:
*\li 'zone' to be a valid zone.
*
* Returns:
*\li #ISC_R_SUCCESS
*/
isc_dscp_t
dns_zone_getxfrsource4dscp(dns_zone_t *zone);
isc_dscp_t
dns_zone_getaltxfrsource4dscp(dns_zone_t *zone);
/*%/
* Get the DSCP value associated with the transfer/alt-transfer source.
*
* Require:
*\li 'zone' to be a valid zone.
*/
isc_result_t
dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource);
isc_result_t
@ -758,6 +788,31 @@ dns_zone_getaltxfrsource6(dns_zone_t *zone);
*\li 'zone' to be a valid zone.
*/
isc_dscp_t
dns_zone_getxfrsource6dscp(dns_zone_t *zone);
isc_dscp_t
dns_zone_getaltxfrsource6dscp(dns_zone_t *zone);
/*%/
* Get the DSCP value associated with the transfer/alt-transfer source.
*
* Require:
*\li 'zone' to be a valid zone.
*/
isc_result_t
dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp);
isc_result_t
dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp);
/*%<
* Set the DSCP value associated with the transfer/alt-transfer source.
*
* Require:
*\li 'zone' to be a valid zone.
*
* Returns:
*\li #ISC_R_SUCCESS
*/
isc_result_t
dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
/*%<
@ -781,6 +836,36 @@ dns_zone_getnotifysrc4(dns_zone_t *zone);
*\li 'zone' to be a valid zone.
*/
isc_dscp_t
dns_zone_getnotifysrc4dscp(dns_zone_t *zone);
/*%/
* Get the DCSP value associated with the notify source.
*
* Require:
*\li 'zone' to be a valid zone.
*/
isc_result_t
dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp);
/*%<
* Set the DSCP value associated with the notify source.
*
* Require:
*\li 'zone' to be a valid zone.
*
* Returns:
*\li #ISC_R_SUCCESS
*/
isc_dscp_t
dns_zone_getnotifysrc4dscp(dns_zone_t *zone);
/*%/
* Get the DSCP value associated with the notify source.
*
* Require:
*\li 'zone' to be a valid zone.
*/
isc_result_t
dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
/*%<
@ -804,6 +889,36 @@ dns_zone_getnotifysrc6(dns_zone_t *zone);
*\li 'zone' to be a valid zone.
*/
isc_dscp_t
dns_zone_getnotifysrc6dscp(dns_zone_t *zone);
/*%/
* Get the DCSP value associated with the notify source.
*
* Require:
*\li 'zone' to be a valid zone.
*/
isc_result_t
dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp);
/*%<
* Set the DSCP value associated with the notify source.
*
* Require:
*\li 'zone' to be a valid zone.
*
* Returns:
*\li #ISC_R_SUCCESS
*/
isc_dscp_t
dns_zone_getnotifysrc6dscp(dns_zone_t *zone);
/*%/
* Get the DSCP value associated with the notify source.
*
* Require:
*\li 'zone' to be a valid zone.
*/
void
dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl);
/*%<

View file

@ -710,3 +710,57 @@ dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp) {
return (ISC_R_NOTFOUND);
}
}
isc_result_t
dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp) {
REQUIRE(DNS_PEER_VALID(peer));
REQUIRE(dscp < 64);
peer->notify_dscp = dscp;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp) {
REQUIRE(DNS_PEER_VALID(peer));
REQUIRE(dscpp != NULL);
*dscpp = peer->notify_dscp;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp) {
REQUIRE(DNS_PEER_VALID(peer));
REQUIRE(dscp < 64);
peer->transfer_dscp = dscp;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp) {
REQUIRE(DNS_PEER_VALID(peer));
REQUIRE(dscpp != NULL);
*dscpp = peer->transfer_dscp;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp) {
REQUIRE(DNS_PEER_VALID(peer));
REQUIRE(dscp < 64);
peer->query_dscp = dscp;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp) {
REQUIRE(DNS_PEER_VALID(peer));
REQUIRE(dscpp != NULL);
*dscpp = peer->query_dscp;
return (ISC_R_SUCCESS);
}

View file

@ -89,6 +89,7 @@ struct dns_request {
isc_boolean_t canceling; /* ctlevent outstanding */
isc_sockaddr_t destaddr;
unsigned int udpcount;
isc_dscp_t dscp;
};
#define DNS_REQUEST_F_CONNECTING 0x0001
@ -427,6 +428,7 @@ static inline isc_result_t
req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
isc_region_t r;
isc_socket_t *socket;
isc_socketevent_t *sendevent;
isc_result_t result;
req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request);
@ -439,8 +441,19 @@ req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
* as we do in resolver.c, but we prefer implementation simplicity
* at this moment.
*/
result = isc_socket_sendto(socket, &r, task, req_senddone,
request, address, NULL);
sendevent = isc_socket_socketevent(request->mctx, socket,
ISC_SOCKEVENT_SENDDONE,
req_senddone, request);
if (request->dscp == -1) {
sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
sendevent->dscp = 0;
} else {
sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
sendevent->dscp = request->dscp;
}
result = isc_socket_sendto2(socket, &r, task, address, NULL,
sendevent, 0);
if (result == ISC_R_SUCCESS)
request->flags |= DNS_REQUEST_F_SENDING;
return (result);
@ -471,6 +484,7 @@ new_request(isc_mem_t *mctx, dns_request_t **requestp)
request->requestmgr = NULL;
request->tsig = NULL;
request->tsigkey = NULL;
request->dscp = -1;
ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL,
DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL,
NULL, NULL);
@ -510,7 +524,8 @@ isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) {
static isc_result_t
create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
isc_sockaddr_t *destaddr, isc_dscp_t dscp,
dns_dispatch_t **dispatchp)
{
isc_result_t result;
isc_socket_t *socket = NULL;
@ -536,6 +551,7 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
if (result != ISC_R_SUCCESS)
goto cleanup;
#endif
attrs = 0;
attrs |= DNS_DISPATCHATTR_TCP;
attrs |= DNS_DISPATCHATTR_PRIVATE;
@ -544,6 +560,8 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
else
attrs |= DNS_DISPATCHATTR_IPV6;
attrs |= DNS_DISPATCHATTR_MAKEQUERY;
isc_socket_dscp(socket, dscp);
result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
socket, requestmgr->taskmgr,
4096, 2, 1, 1, 3, attrs,
@ -609,12 +627,12 @@ find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
static isc_result_t
get_dispatch(isc_boolean_t tcp, dns_requestmgr_t *requestmgr,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
dns_dispatch_t **dispatchp)
isc_dscp_t dscp, dns_dispatch_t **dispatchp)
{
isc_result_t result;
if (tcp)
result = create_tcp_dispatch(requestmgr, srcaddr,
destaddr, dispatchp);
destaddr, dscp, dispatchp);
else
result = find_udp_dispatch(requestmgr, srcaddr,
destaddr, dispatchp);
@ -646,8 +664,8 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
return(dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
options, timeout, 0, 0, task, action,
return(dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr,
0, options, timeout, 0, 0, task, action,
arg, requestp));
}
@ -664,8 +682,8 @@ dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
if (udptimeout != 0)
udpretries = timeout / udptimeout;
return (dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
options, timeout, udptimeout,
return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr,
0, options, timeout, udptimeout,
udpretries, task, action, arg,
requestp));
}
@ -677,6 +695,21 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
unsigned int udptimeout, unsigned int udpretries,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr,
0, options, timeout, udptimeout,
udpretries, task, action, arg,
requestp));
}
isc_result_t
dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
isc_dscp_t dscp, unsigned int options,
unsigned int timeout, unsigned int udptimeout,
unsigned int udpretries, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
dns_request_t *request = NULL;
isc_task_t *tclone = NULL;
@ -715,6 +748,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
udptimeout = 1;
}
request->udpcount = udpretries;
request->dscp = dscp;
/*
* Create timer now. We will set it below once.
@ -746,7 +780,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512)
tcp = ISC_TRUE;
result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
result = get_dispatch(tcp, requestmgr, srcaddr, destaddr, dscp,
&request->dispatch);
if (result != ISC_R_SUCCESS)
goto cleanup;
@ -833,8 +867,8 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
return (dns_request_createvia3(requestmgr, message, NULL, address,
options, key, timeout, 0, 0, task,
return (dns_request_createvia4(requestmgr, message, NULL, address,
0, options, key, timeout, 0, 0, task,
action, arg, requestp));
}
@ -846,8 +880,8 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
return(dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
options, key, timeout, 0, 0, task,
return(dns_request_createvia4(requestmgr, message, srcaddr, destaddr,
0, options, key, timeout, 0, 0, task,
action, arg, requestp));
}
@ -863,8 +897,8 @@ dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
if (udptimeout != 0)
udpretries = timeout / udptimeout;
return (dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
options, key, timeout, udptimeout,
return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr,
0, options, key, timeout, udptimeout,
udpretries, task, action, arg,
requestp));
}
@ -877,6 +911,21 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
unsigned int udpretries, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr,
0, options, key, timeout, udptimeout,
udpretries, task, action, arg,
requestp));
}
isc_result_t
dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message,
isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
isc_dscp_t dscp, unsigned int options,
dns_tsigkey_t *key, unsigned int timeout,
unsigned int udptimeout, unsigned int udpretries,
isc_task_t *task, isc_taskaction_t action, void *arg,
dns_request_t **requestp)
{
dns_request_t *request = NULL;
isc_task_t *tclone = NULL;
@ -917,6 +966,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
udptimeout = 1;
}
request->udpcount = udpretries;
request->dscp = dscp;
/*
* Create timer now. We will set it below once.
@ -943,7 +993,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
use_tcp:
tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0);
result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
result = get_dispatch(tcp, requestmgr, srcaddr, destaddr, dscp,
&request->dispatch);
if (result != ISC_R_SUCCESS)
goto cleanup;

View file

@ -161,6 +161,7 @@ typedef struct query {
isc_buffer_t *tsig;
dns_tsigkey_t *tsigkey;
isc_socketevent_t sendevent;
isc_dscp_t dscp;
unsigned int options;
unsigned int attributes;
unsigned int sends;
@ -226,7 +227,7 @@ struct fetchctx {
dns_adbfind_t * altfind;
dns_adbaddrinfolist_t forwaddrs;
dns_adbaddrinfolist_t altaddrs;
isc_sockaddrlist_t forwarders;
dns_forwarderlist_t forwarders;
dns_fwdpolicy_t fwdpolicy;
isc_sockaddrlist_t bad;
isc_sockaddrlist_t edns;
@ -397,6 +398,8 @@ struct dns_resolver {
dns_dispatchset_t * dispatches4;
isc_boolean_t exclusivev4;
dns_dispatchset_t * dispatches6;
isc_dscp_t querydscp4;
isc_dscp_t querydscp6;
isc_boolean_t exclusivev6;
unsigned int nbuckets;
fctxbucket_t * buckets;
@ -1402,6 +1405,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
isc_sockaddr_t addr;
isc_boolean_t have_addr = ISC_FALSE;
unsigned int srtt;
isc_dscp_t dscp = -1;
FCTXTRACE("query");
@ -1436,6 +1440,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
query->attributes = 0;
query->sends = 0;
query->connects = 0;
query->dscp = addrinfo->dscp;
/*
* Note that the caller MUST guarantee that 'addrinfo' will remain
* valid until this query is canceled.
@ -1462,9 +1467,13 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
result = dns_peer_getquerysource(peer, &addr);
if (result == ISC_R_SUCCESS)
have_addr = ISC_TRUE;
result = dns_peer_getquerydscp(peer, &dscp);
if (result == ISC_R_SUCCESS)
query->dscp = dscp;
}
}
dscp = -1;
if ((query->options & DNS_FETCHOPT_TCP) != 0) {
int pf;
@ -1475,11 +1484,13 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
result = dns_dispatch_getlocaladdress(
res->dispatches4->dispatches[0],
&addr);
dscp = dns_resolver_getquerydscp4(fctx->res);
break;
case PF_INET6:
result = dns_dispatch_getlocaladdress(
res->dispatches6->dispatches[0],
&addr);
dscp = dns_resolver_getquerydscp6(fctx->res);
break;
default:
result = ISC_R_NOTIMPLEMENTED;
@ -1489,6 +1500,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
goto cleanup_query;
}
isc_sockaddr_setport(&addr, 0);
if (query->dscp == -1)
query->dscp = dscp;
result = isc_socket_create(res->socketmgr, pf,
isc_sockettype_tcp,
@ -1501,7 +1514,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
if (result != ISC_R_SUCCESS)
goto cleanup_socket;
#endif
/*
* A dispatch will be created once the connect succeeds.
*/
@ -1512,9 +1524,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
switch (isc_sockaddr_pf(&addr)) {
case AF_INET:
attrs |= DNS_DISPATCHATTR_IPV4;
dscp = dns_resolver_getquerydscp4(fctx->res);
break;
case AF_INET6:
attrs |= DNS_DISPATCHATTR_IPV6;
dscp = dns_resolver_getquerydscp6(fctx->res);
break;
default:
result = ISC_R_NOTIMPLEMENTED;
@ -1539,18 +1553,23 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
dns_resolver_dispatchv4(res),
&query->dispatch);
query->exclusivesocket = res->exclusivev4;
dscp = dns_resolver_getquerydscp4(fctx->res);
break;
case PF_INET6:
dns_dispatch_attach(
dns_resolver_dispatchv6(res),
&query->dispatch);
query->exclusivesocket = res->exclusivev6;
dscp = dns_resolver_getquerydscp6(fctx->res);
break;
default:
result = ISC_R_NOTIMPLEMENTED;
goto cleanup_query;
}
}
if (query->dscp == -1)
query->dscp = dscp;
/*
* We should always have a valid dispatcher here. If we
* don't support a protocol family, then its dispatcher
@ -1574,6 +1593,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
*
* XXXRTH Should we attach to the socket?
*/
if (query->dscp != -1)
isc_socket_dscp(query->tcpsocket, query->dscp);
result = isc_socket_connect(query->tcpsocket,
&addrinfo->sockaddr, task,
resquery_connected, query);
@ -2027,9 +2048,21 @@ resquery_send(resquery_t *query) {
* XXXRTH Make sure we don't send to ourselves! We should probably
* prune out these addresses when we get them from the ADB.
*/
memset(&query->sendevent, 0, sizeof(query->sendevent));
ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL,
ISC_SOCKEVENT_SENDDONE, resquery_senddone, query,
NULL, NULL, NULL);
if (query->dscp == -1) {
query->sendevent.attributes &= ~ISC_SOCKEVENTATTR_DSCP;
query->sendevent.dscp = 0;
} else {
query->sendevent.attributes |= ISC_SOCKEVENTATTR_DSCP;
query->sendevent.dscp = query->dscp;
if ((query->options & DNS_FETCHOPT_TCP) != 0)
isc_socket_dscp(socket, query->dscp);
}
result = isc_socket_sendto2(socket, &r, task, address, NULL,
&query->sendevent, 0);
if (result != ISC_R_SUCCESS) {
@ -2609,7 +2642,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
dns_resolver_t *res;
isc_stdtime_t now;
unsigned int stdoptions = 0;
isc_sockaddr_t *sa;
dns_forwarder_t *fwd;
dns_adbaddrinfo_t *ai;
isc_boolean_t all_bad;
dns_rdata_ns_t ns;
@ -2640,8 +2673,8 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
* selective forwarders specified in the view; otherwise use the
* resolver's forwarders (if any).
*/
sa = ISC_LIST_HEAD(fctx->forwarders);
if (sa == NULL) {
fwd = ISC_LIST_HEAD(fctx->forwarders);
if (fwd == NULL) {
dns_forwarders_t *forwarders = NULL;
dns_name_t *name = &fctx->name;
dns_name_t suffix;
@ -2666,7 +2699,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
domain, &forwarders);
if (result == ISC_R_SUCCESS) {
sa = ISC_LIST_HEAD(forwarders->addrs);
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
if (fctx->fwdpolicy == dns_fwdpolicy_only &&
isstrictsubdomain(domain, &fctx->domain)) {
@ -2680,20 +2713,20 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
}
}
while (sa != NULL) {
if ((isc_sockaddr_pf(sa) == AF_INET &&
while (fwd != NULL) {
if ((isc_sockaddr_pf(&fwd->addr) == AF_INET &&
fctx->res->dispatches4 == NULL) ||
(isc_sockaddr_pf(sa) == AF_INET6 &&
(isc_sockaddr_pf(&fwd->addr) == AF_INET6 &&
fctx->res->dispatches6 == NULL)) {
sa = ISC_LIST_NEXT(sa, link);
fwd = ISC_LIST_NEXT(fwd, link);
continue;
}
ai = NULL;
result = dns_adb_findaddrinfo(fctx->adb,
sa, &ai, 0); /* XXXMLG */
result = dns_adb_findaddrinfo(fctx->adb, &fwd->addr, &ai, 0);
if (result == ISC_R_SUCCESS) {
dns_adbaddrinfo_t *cur;
ai->flags |= FCTX_ADDRINFO_FORWARDER;
ai->dscp = fwd->dscp;
cur = ISC_LIST_HEAD(fctx->forwaddrs);
while (cur != NULL && cur->srtt < ai->srtt)
cur = ISC_LIST_NEXT(cur, publink);
@ -2703,7 +2736,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
else
ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
}
sa = ISC_LIST_NEXT(sa, link);
fwd = ISC_LIST_NEXT(fwd, link);
}
/*
@ -2852,8 +2885,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
}
static inline void
possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr)
{
possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) {
isc_netaddr_t na;
char buf[ISC_NETADDR_FORMATSIZE];
isc_sockaddr_t *sa;
@ -9129,3 +9161,30 @@ dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) {
resolver->query_timeout = seconds;
}
void
dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp) {
REQUIRE(VALID_RESOLVER(resolver));
resolver->querydscp4 = dscp;
}
isc_dscp_t
dns_resolver_getquerydscp4(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
return (resolver->querydscp4);
}
void
dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp) {
REQUIRE(VALID_RESOLVER(resolver));
resolver->querydscp6 = dscp;
}
isc_dscp_t
dns_resolver_getquerydscp6(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
return (resolver->querydscp6);
}

View file

@ -180,12 +180,14 @@ dns_dispatch_cancel
dns_dispatch_changeattributes
dns_dispatch_createtcp
dns_dispatch_detach
dns_dispatch_getdscp
dns_dispatch_getlocaladdress
dns_dispatch_getsocket
dns_dispatch_getudp
dns_dispatch_getudp_dup
dns_dispatch_importrecv
dns_dispatch_removeresponse
dns_dispatch_setdscp
dns_dispatch_starttcp
dns_dispatchmgr_create
dns_dispatchmgr_destroy
@ -456,11 +458,17 @@ dns_peer_detach
dns_peer_getbogus
dns_peer_getkey
dns_peer_getmaxudp
dns_peer_getnotifysource
dns_peer_getnotifydscp
dns_peer_getprovideixfr
dns_peer_getquerysource
dns_peer_getquerydscp
dns_peer_getrequestixfr
dns_peer_getsupportedns
dns_peer_gettransferformat
dns_peer_gettransfers
dns_peer_gettransfersource
dns_peer_gettransferdscp
dns_peer_new
dns_peer_newprefix
dns_peer_setbogus
@ -468,14 +476,17 @@ dns_peer_setkey
dns_peer_setkeybycharp
dns_peer_setmaxudp
dns_peer_setnotifysource
dns_peer_setnotifydscp
dns_peer_setprovideixfr
dns_peer_setquerysource
dns_peer_setquerydscp
dns_peer_setrequestixfr
dns_peer_setrequestnsid
dns_peer_setsupportedns
dns_peer_settransferformat
dns_peer_settransfers
dns_peer_settransfersource
dns_peer_settransferdscp
dns_peer_setudpsize
dns_peerlist_addpeer
dns_peerlist_attach
@ -825,6 +836,8 @@ dns_zone_forwardupdate
dns_zone_fulldumptostream
dns_zone_get_rpz_num
dns_zone_getadded
dns_zone_getaltxfrsource4dscp
dns_zone_getaltxfrsource6dscp
dns_zone_getchecknames
dns_zone_getclass
dns_zone_getdb
@ -843,7 +856,9 @@ dns_zone_getmctx
dns_zone_getmgr
dns_zone_getnotifyacl
dns_zone_getnotifysrc4
dns_zone_getnotifysrc4dscp
dns_zone_getnotifysrc6
dns_zone_getnotifysrc6dscp
dns_zone_getoptions
dns_zone_getorigin
dns_zone_getprivatetype
@ -867,7 +882,9 @@ dns_zone_getupdatedisabled
dns_zone_getview
dns_zone_getxfracl
dns_zone_getxfrsource4
dns_zone_getxfrsource4dscp
dns_zone_getxfrsource6
dns_zone_getxfrsource6dscp
dns_zone_getzeronosoattl
dns_zone_iattach
dns_zone_idetach
@ -896,7 +913,9 @@ dns_zone_setadded
dns_zone_setalsonotify
dns_zone_setalsonotifywithkeys
dns_zone_setaltxfrsource4
dns_zone_setaltxfrsource4dscp
dns_zone_setaltxfrsource6
dns_zone_setaltxfrsource6dscp
dns_zone_setcheckmx
dns_zone_setchecknames
dns_zone_setcheckns
@ -928,7 +947,9 @@ dns_zone_setnodes
dns_zone_setnotifyacl
dns_zone_setnotifydelay
dns_zone_setnotifysrc4
dns_zone_setnotifysrc4dscp
dns_zone_setnotifysrc6
dns_zone_setnotifysrc6dscp
dns_zone_setnotifytype
dns_zone_setnsec3param
dns_zone_setoption
@ -955,7 +976,9 @@ dns_zone_setupdatedisabled
dns_zone_setview
dns_zone_setxfracl
dns_zone_setxfrsource4
dns_zone_setxfrsource4dscp
dns_zone_setxfrsource6
dns_zone_setxfrsource6dscp
dns_zone_setzeronosoattl
dns_zone_signwithkey
dns_zone_synckeyzone

View file

@ -121,6 +121,7 @@ struct dns_xfrin_ctx {
* may differ due to IXFR->AXFR fallback.
*/
dns_rdatatype_t reqtype;
isc_dscp_t dscp;
isc_sockaddr_t masteraddr;
isc_sockaddr_t sourceaddr;
@ -192,6 +193,7 @@ xfrin_create(isc_mem_t *mctx,
dns_rdatatype_t reqtype,
isc_sockaddr_t *masteraddr,
isc_sockaddr_t *sourceaddr,
isc_dscp_t dscp,
dns_tsigkey_t *tsigkey,
dns_xfrin_ctx_t **xfrp);
@ -606,20 +608,23 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
{
isc_sockaddr_t sourceaddr;
isc_dscp_t dscp;
switch (isc_sockaddr_pf(masteraddr)) {
case PF_INET:
sourceaddr = *dns_zone_getxfrsource4(zone);
dscp = dns_zone_getxfrsource4dscp(zone);
break;
case PF_INET6:
sourceaddr = *dns_zone_getxfrsource6(zone);
dscp = dns_zone_getxfrsource6dscp(zone);
break;
default:
INSIST(0);
}
return(dns_xfrin_create2(zone, xfrtype, masteraddr, &sourceaddr,
tsigkey, mctx, timermgr, socketmgr,
return(dns_xfrin_create3(zone, xfrtype, masteraddr, &sourceaddr,
dscp, tsigkey, mctx, timermgr, socketmgr,
task, done, xfrp));
}
@ -630,6 +635,19 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
isc_task_t *task, dns_xfrindone_t done,
dns_xfrin_ctx_t **xfrp)
{
return (dns_xfrin_create3(zone, xfrtype, masteraddr, sourceaddr, -1,
tsigkey, mctx, timermgr, socketmgr, task,
done, xfrp));
}
isc_result_t
dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype,
isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
isc_task_t *task, dns_xfrindone_t done,
dns_xfrin_ctx_t **xfrp)
{
dns_name_t *zonename = dns_zone_getorigin(zone);
dns_xfrin_ctx_t *xfr = NULL;
@ -645,7 +663,7 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
dns_zone_getclass(zone), xfrtype, masteraddr,
sourceaddr, tsigkey, &xfr));
sourceaddr, dscp, tsigkey, &xfr));
CHECK(xfrin_start(xfr));
@ -768,6 +786,7 @@ xfrin_create(isc_mem_t *mctx,
dns_rdatatype_t reqtype,
isc_sockaddr_t *masteraddr,
isc_sockaddr_t *sourceaddr,
isc_dscp_t dscp,
dns_tsigkey_t *tsigkey,
dns_xfrin_ctx_t **xfrp)
{
@ -800,6 +819,7 @@ xfrin_create(isc_mem_t *mctx,
xfr->checkid = ISC_TRUE;
xfr->id = (isc_uint16_t)(tmp & 0xffff);
xfr->reqtype = reqtype;
xfr->dscp = dscp;
/* sockaddr */
xfr->socket = NULL;
@ -891,6 +911,7 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
ISC_SOCKET_REUSEADDRESS));
#endif
isc_socket_dscp(xfr->socket, xfr->dscp);
CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
xfrin_connect_done, xfr));
xfr->connects++;

View file

@ -243,6 +243,7 @@ struct dns_zone {
isc_uint32_t minretry;
isc_sockaddr_t *masters;
isc_dscp_t *masterdscps;
dns_name_t **masterkeynames;
isc_boolean_t *mastersok;
unsigned int masterscnt;
@ -251,6 +252,7 @@ struct dns_zone {
dns_notifytype_t notifytype;
isc_sockaddr_t *notify;
dns_name_t **notifykeynames;
isc_dscp_t *notifydscp;
unsigned int notifycnt;
isc_sockaddr_t notifyfrom;
isc_task_t *task;
@ -262,6 +264,12 @@ struct dns_zone {
isc_sockaddr_t altxfrsource4;
isc_sockaddr_t altxfrsource6;
isc_sockaddr_t sourceaddr;
isc_dscp_t notifysrc4dscp;
isc_dscp_t notifysrc6dscp;
isc_dscp_t xfrsource4dscp;
isc_dscp_t xfrsource6dscp;
isc_dscp_t altxfrsource4dscp;
isc_dscp_t altxfrsource6dscp;
dns_xfrin_ctx_t *xfr; /* task locked */
dns_tsigkey_t *tsigkey; /* key used for xfr */
/* Access Control Lists */
@ -512,6 +520,7 @@ struct dns_notify {
dns_name_t ns;
isc_sockaddr_t dst;
dns_tsigkey_t *key;
isc_dscp_t dscp;
ISC_LINK(dns_notify_t) link;
};
@ -869,12 +878,14 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->maxretry = DNS_ZONE_MAXRETRY;
zone->minretry = DNS_ZONE_MINRETRY;
zone->masters = NULL;
zone->masterdscps = NULL;
zone->masterkeynames = NULL;
zone->mastersok = NULL;
zone->masterscnt = 0;
zone->curmaster = 0;
zone->notify = NULL;
zone->notifykeynames = NULL;
zone->notifydscp = NULL;
zone->notifytype = dns_notifytype_yes;
zone->notifycnt = 0;
zone->task = NULL;
@ -904,6 +915,12 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
isc_sockaddr_any6(&zone->xfrsource6);
isc_sockaddr_any(&zone->altxfrsource4);
isc_sockaddr_any6(&zone->altxfrsource6);
zone->notifysrc4dscp = -1;
zone->notifysrc6dscp = -1;
zone->xfrsource4dscp = -1;
zone->xfrsource6dscp = -1;
zone->altxfrsource4dscp = -1;
zone->altxfrsource6dscp = -1;
zone->xfr = NULL;
zone->tsigkey = NULL;
zone->maxxfrin = MAX_XFER_TIME;
@ -4778,6 +4795,23 @@ dns_zone_getxfrsource4(dns_zone_t *zone) {
return (&zone->xfrsource4);
}
isc_result_t
dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->xfrsource4dscp = dscp;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_dscp_t
dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->xfrsource4dscp);
}
isc_result_t
dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
REQUIRE(DNS_ZONE_VALID(zone));
@ -4795,6 +4829,23 @@ dns_zone_getxfrsource6(dns_zone_t *zone) {
return (&zone->xfrsource6);
}
isc_dscp_t
dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->xfrsource6dscp);
}
isc_result_t
dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->xfrsource6dscp = dscp;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_zone_setaltxfrsource4(dns_zone_t *zone,
const isc_sockaddr_t *altxfrsource)
@ -4814,6 +4865,23 @@ dns_zone_getaltxfrsource4(dns_zone_t *zone) {
return (&zone->altxfrsource4);
}
isc_result_t
dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->altxfrsource4dscp = dscp;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_dscp_t
dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->altxfrsource4dscp);
}
isc_result_t
dns_zone_setaltxfrsource6(dns_zone_t *zone,
const isc_sockaddr_t *altxfrsource)
@ -4833,6 +4901,23 @@ dns_zone_getaltxfrsource6(dns_zone_t *zone) {
return (&zone->altxfrsource6);
}
isc_result_t
dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->altxfrsource6dscp = dscp;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_dscp_t
dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->altxfrsource6dscp);
}
isc_result_t
dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
REQUIRE(DNS_ZONE_VALID(zone));
@ -4850,6 +4935,23 @@ dns_zone_getnotifysrc4(dns_zone_t *zone) {
return (&zone->notifysrc4);
}
isc_result_t
dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->notifysrc4dscp = dscp;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_dscp_t
dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->notifysrc4dscp);
}
isc_result_t
dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
REQUIRE(DNS_ZONE_VALID(zone));
@ -4899,25 +5001,33 @@ same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
}
static void
clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
unsigned int *countp, isc_mem_t *mctx)
clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
dns_name_t ***keynamesp, unsigned int *countp,
isc_mem_t *mctx)
{
unsigned int count;
isc_sockaddr_t *addrs;
isc_dscp_t *dscps;
dns_name_t **keynames;
REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL);
REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
keynamesp != NULL);
count = *countp;
*countp = 0;
addrs = *addrsp;
*addrsp = NULL;
dscps = *dscpsp;
*dscpsp = NULL;
keynames = *keynamesp;
*keynamesp = NULL;
if (addrs != NULL)
isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
if (dscps != NULL)
isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
if (keynames != NULL) {
unsigned int i;
for (i = 0; i < count; i++) {
@ -4935,15 +5045,18 @@ clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
static isc_result_t
set_addrkeylist(unsigned int count,
const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
const isc_dscp_t *dscp, isc_dscp_t **newdscpp,
dns_name_t **names, dns_name_t ***newnamesp,
isc_mem_t *mctx)
{
isc_result_t result;
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscp = NULL;
dns_name_t **newnames = NULL;
unsigned int i;
REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
REQUIRE(newdscpp != NULL && *newdscpp == NULL);
REQUIRE(newnamesp != NULL && *newnamesp == NULL);
newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
@ -4951,10 +5064,22 @@ set_addrkeylist(unsigned int count,
return (ISC_R_NOMEMORY);
memcpy(newaddrs, addrs, count * sizeof(*newaddrs));
newnames = NULL;
if (dscp != NULL) {
newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
if (newdscp == NULL) {
isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
return (ISC_R_NOMEMORY);
}
memcpy(newdscp, dscp, count * sizeof(*newdscp));
} else
newdscp = NULL;
if (names != NULL) {
newnames = isc_mem_get(mctx, count * sizeof(*newnames));
if (newnames == NULL) {
if (newdscp != NULL)
isc_mem_put(mctx, newdscp,
count * sizeof(*newdscp));
isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
return (ISC_R_NOMEMORY);
}
@ -4978,32 +5103,64 @@ set_addrkeylist(unsigned int count,
mctx);
isc_mem_put(mctx, newaddrs,
count * sizeof(*newaddrs));
isc_mem_put(mctx, newdscp,
count * sizeof(*newdscp));
isc_mem_put(mctx, newnames,
count * sizeof(*newnames));
return (ISC_R_NOMEMORY);
}
}
}
}
} else
newnames = NULL;
*newdscpp = newdscp;
*newaddrsp = newaddrs;
*newnamesp = newnames;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->notifysrc6dscp = dscp;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_dscp_t
dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->notifysrc6dscp);
}
isc_result_t
dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
isc_uint32_t count)
{
return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count));
return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
count));
}
isc_result_t
dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
dns_name_t **keynames, isc_uint32_t count)
{
return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
count));
}
isc_result_t
dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
const isc_dscp_t *dscps, dns_name_t **keynames,
isc_uint32_t count)
{
isc_result_t result;
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscps = NULL;
dns_name_t **newnames = NULL;
REQUIRE(DNS_ZONE_VALID(zone));
@ -5018,8 +5175,9 @@ dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
same_keynames(zone->notifykeynames, keynames, count))
goto unlock;
clear_addresskeylist(&zone->notify, &zone->notifykeynames,
&zone->notifycnt, zone->mctx);
clear_addresskeylist(&zone->notify, &zone->notifydscp,
&zone->notifykeynames, &zone->notifycnt,
zone->mctx);
if (count == 0)
goto unlock;
@ -5027,7 +5185,7 @@ dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
/*
* Set up the notify and notifykey lists
*/
result = set_addrkeylist(count, notify, &newaddrs,
result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
keynames, &newnames, zone->mctx);
if (result != ISC_R_SUCCESS)
goto unlock;
@ -5036,6 +5194,7 @@ dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
* Everything is ok so attach to the zone.
*/
zone->notify = newaddrs;
zone->notifydscp = newdscps;
zone->notifykeynames = newnames;
zone->notifycnt = count;
unlock:
@ -5061,6 +5220,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone,
{
isc_result_t result = ISC_R_SUCCESS;
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscps = NULL;
dns_name_t **newnames = NULL;
isc_boolean_t *newok;
unsigned int i;
@ -5095,8 +5255,9 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone,
zone->masterscnt * sizeof(isc_boolean_t));
zone->mastersok = NULL;
}
clear_addresskeylist(&zone->masters, &zone->masterkeynames,
&zone->masterscnt, zone->mctx);
clear_addresskeylist(&zone->masters, &zone->masterdscps,
&zone->masterkeynames, &zone->masterscnt,
zone->mctx);
/*
* If count == 0, don't allocate any space for masters, mastersok or
* keynames so internally, those pointers are NULL if count == 0
@ -5119,8 +5280,9 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone,
/*
* Now set up the masters and masterkey lists
*/
result = set_addrkeylist(count, masters, &newaddrs,
result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
keynames, &newnames, zone->mctx);
INSIST(newdscps == NULL);
if (result != ISC_R_SUCCESS) {
isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
goto unlock;
@ -5132,6 +5294,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone,
zone->curmaster = 0;
zone->mastersok = newok;
zone->masters = newaddrs;
zone->masterdscps = newdscps;
zone->masterkeynames = newnames;
zone->masterscnt = count;
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
@ -9626,6 +9789,8 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
isc_sockaddr_t src;
int timeout;
isc_boolean_t have_notifysource = ISC_FALSE;
isc_boolean_t have_notifydscp = ISC_FALSE;
isc_dscp_t dscp = -1;
notify = event->ev_arg;
REQUIRE(DNS_NOTIFY_VALID(notify));
@ -9692,16 +9857,23 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
result = dns_peer_getnotifysource(peer, &src);
if (result == ISC_R_SUCCESS)
have_notifysource = ISC_TRUE;
dns_peer_getnotifydscp(peer, &dscp);
if (dscp != -1)
have_notifydscp = ISC_TRUE;
}
}
switch (isc_sockaddr_pf(&notify->dst)) {
case PF_INET:
if (!have_notifysource)
src = notify->zone->notifysrc4;
if (!have_notifydscp)
dscp = notify->zone->notifysrc4dscp;
break;
case PF_INET6:
if (!have_notifysource)
src = notify->zone->notifysrc6;
if (!have_notifydscp)
dscp = notify->zone->notifysrc6dscp;
break;
default:
result = ISC_R_NOTIMPLEMENTED;
@ -9710,9 +9882,9 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
timeout = 15;
if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
timeout = 30;
result = dns_request_createvia2(notify->zone->view->requestmgr,
message, &src, &notify->dst, 0, key,
timeout * 3, timeout,
result = dns_request_createvia4(notify->zone->view->requestmgr,
message, &src, &notify->dst, dscp,
0, key, timeout * 3, timeout, 0,
notify->zone->task, notify_done,
notify, &notify->request);
if (result == ISC_R_SUCCESS) {
@ -10897,8 +11069,9 @@ soa_query(isc_task_t *task, isc_event_t *event) {
isc_uint32_t options;
isc_boolean_t cancel = ISC_TRUE;
int timeout;
isc_boolean_t have_xfrsource, reqnsid;
isc_boolean_t have_xfrsource, have_xfrdscp, reqnsid;
isc_uint16_t udpsize = SEND_BUFFER_SIZE;
isc_dscp_t dscp = -1;
REQUIRE(DNS_ZONE_VALID(zone));
@ -10957,7 +11130,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
}
}
have_xfrsource = ISC_FALSE;
have_xfrsource = have_xfrdscp = ISC_FALSE;
reqnsid = zone->view->requestnsid;
if (zone->view->peers != NULL) {
dns_peer_t *peer = NULL;
@ -10972,6 +11145,9 @@ soa_query(isc_task_t *task, isc_event_t *event) {
&zone->sourceaddr);
if (result == ISC_R_SUCCESS)
have_xfrsource = ISC_TRUE;
dns_peer_gettransferdscp(peer, &dscp);
if (dscp != -1)
have_xfrdscp = ISC_TRUE;
if (zone->view->resolver != NULL)
udpsize =
dns_resolver_getudpsize(zone->view->resolver);
@ -10987,8 +11163,13 @@ soa_query(isc_task_t *task, isc_event_t *event) {
&zone->xfrsource4))
goto skip_master;
zone->sourceaddr = zone->altxfrsource4;
} else if (!have_xfrsource)
if (!have_xfrdscp)
dscp = zone->altxfrsource4dscp;
} else if (!have_xfrsource) {
zone->sourceaddr = zone->xfrsource4;
if (!have_xfrdscp)
dscp = zone->xfrsource4dscp;
}
break;
case PF_INET6:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
@ -10996,8 +11177,13 @@ soa_query(isc_task_t *task, isc_event_t *event) {
&zone->xfrsource6))
goto skip_master;
zone->sourceaddr = zone->altxfrsource6;
} else if (!have_xfrsource)
if (!have_xfrdscp)
dscp = zone->altxfrsource6dscp;
} else if (!have_xfrsource) {
zone->sourceaddr = zone->xfrsource6;
if (!have_xfrdscp)
dscp = zone->xfrsource6dscp;
}
break;
default:
result = ISC_R_NOTIMPLEMENTED;
@ -11019,11 +11205,11 @@ soa_query(isc_task_t *task, isc_event_t *event) {
timeout = 15;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
timeout = 30;
result = dns_request_createvia2(zone->view->requestmgr, message,
result = dns_request_createvia4(zone->view->requestmgr, message,
&zone->sourceaddr, &zone->masteraddr,
options, key, timeout * 3, timeout,
zone->task, refresh_callback, zone,
&zone->request);
dscp, options, key, timeout * 3,
timeout, 0, zone->task,
refresh_callback, zone, &zone->request);
if (result != ISC_R_SUCCESS) {
zone_idetach(&dummy);
zone_debuglog(zone, me, 1,
@ -11077,8 +11263,10 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
dns_tsigkey_t *key = NULL;
dns_dbnode_t *node = NULL;
int timeout;
isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
isc_uint16_t udpsize = SEND_BUFFER_SIZE;
isc_boolean_t have_xfrsource = ISC_FALSE, have_xfrdscp = ISC_FALSE;
isc_boolean_t reqnsid;
isc_uint16_t udpsize = SEND_BUFFER_SIZE;
isc_dscp_t dscp = -1;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(LOCKED_ZONE(zone));
@ -11209,6 +11397,9 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
&zone->sourceaddr);
if (result == ISC_R_SUCCESS)
have_xfrsource = ISC_TRUE;
result = dns_peer_gettransferdscp(peer, &dscp);
if (dscp != -1)
have_xfrdscp = ISC_TRUE;
if (zone->view->resolver != NULL)
udpsize =
dns_resolver_getudpsize(zone->view->resolver);
@ -11230,16 +11421,26 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
*/
switch (isc_sockaddr_pf(&zone->masteraddr)) {
case PF_INET:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
zone->sourceaddr = zone->altxfrsource4;
else if (!have_xfrsource)
if (!have_xfrdscp)
dscp = zone->altxfrsource4dscp;
} else if (!have_xfrsource) {
zone->sourceaddr = zone->xfrsource4;
if (!have_xfrdscp)
dscp = zone->xfrsource4dscp;
}
break;
case PF_INET6:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
zone->sourceaddr = zone->altxfrsource6;
else if (!have_xfrsource)
if (!have_xfrdscp)
dscp = zone->altxfrsource6dscp;
} else if (!have_xfrsource) {
zone->sourceaddr = zone->xfrsource6;
if (!have_xfrdscp)
dscp = zone->xfrsource6dscp;
}
break;
default:
result = ISC_R_NOTIMPLEMENTED;
@ -11249,11 +11450,11 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
timeout = 15;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
timeout = 30;
result = dns_request_createvia2(zone->view->requestmgr, message,
result = dns_request_createvia4(zone->view->requestmgr, message,
&zone->sourceaddr, &zone->masteraddr,
DNS_REQUESTOPT_TCP, key, timeout * 3,
timeout, zone->task, stub_callback,
stub, &zone->request);
dscp, DNS_REQUESTOPT_TCP, key,
timeout * 3, timeout, 0, zone->task,
stub_callback, stub, &zone->request);
if (result != ISC_R_SUCCESS) {
zone_debuglog(zone, me, 1,
"dns_request_createvia() failed: %s",
@ -13668,6 +13869,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
isc_sockaddr_t masteraddr;
isc_time_t now;
const char *soa_before = "";
isc_dscp_t dscp = -1;
UNUSED(task);
@ -13744,6 +13946,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
* Determine if we should attempt to sign the request with TSIG.
*/
result = ISC_R_NOTFOUND;
/*
* First, look for a tsig key in the master statement, then
* try for a server key.
@ -13764,13 +13967,28 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
isc_result_totext(result));
}
if (zone->masterdscps != NULL)
dscp = zone->masterdscps[zone->curmaster];
LOCK_ZONE(zone);
masteraddr = zone->masteraddr;
sourceaddr = zone->sourceaddr;
switch (isc_sockaddr_pf(&masteraddr)) {
case PF_INET:
if (dscp == -1)
dscp = zone->xfrsource4dscp;
break;
case PF_INET6:
if (dscp == -1)
dscp = zone->xfrsource6dscp;
break;
default:
INSIST(0);
};
UNLOCK_ZONE(zone);
INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
zone->tsigkey, zone->mctx,
result = dns_xfrin_create3(zone, xfrtype, &masteraddr, &sourceaddr,
dscp, zone->tsigkey, zone->mctx,
zone->zmgr->timermgr, zone->zmgr->socketmgr,
zone->task, zone_xfrdone, &zone->xfr);
if (result == ISC_R_SUCCESS) {
@ -13826,6 +14044,7 @@ static isc_result_t
sendtomaster(dns_forward_t *forward) {
isc_result_t result;
isc_sockaddr_t src;
isc_dscp_t dscp = -1;
LOCK_ZONE(forward->zone);
@ -13849,21 +14068,23 @@ sendtomaster(dns_forward_t *forward) {
switch (isc_sockaddr_pf(&forward->addr)) {
case PF_INET:
src = forward->zone->xfrsource4;
dscp = forward->zone->xfrsource4dscp;
break;
case PF_INET6:
src = forward->zone->xfrsource6;
dscp = forward->zone->xfrsource6dscp;
break;
default:
result = ISC_R_NOTIMPLEMENTED;
goto unlock;
}
result = dns_request_createraw(forward->zone->view->requestmgr,
forward->msgbuf,
&src, &forward->addr,
DNS_REQUESTOPT_TCP, 15 /* XXX */,
forward->zone->task,
forward_callback, forward,
&forward->request);
result = dns_request_createraw4(forward->zone->view->requestmgr,
forward->msgbuf,
&src, &forward->addr, dscp,
DNS_REQUESTOPT_TCP, 15 /* XXX */,
0, 0, forward->zone->task,
forward_callback, forward,
&forward->request);
if (result == ISC_R_SUCCESS) {
if (!ISC_LINK_LINKED(forward, link))
ISC_LIST_APPEND(forward->zone->forwards, forward, link);

View file

@ -124,6 +124,7 @@
#define isc_socket_gettype isc__socket_gettype
#define isc_socket_isbound isc__socket_isbound
#define isc_socket_ipv6only isc__socket_ipv6only
#define isc_socket_dscp isc__socket_dscp
#define isc_socket_setname isc__socket_setname
#define isc_socketmgr_getmaxsockets isc__socketmgr_getmaxsockets
#define isc_socketmgr_setstats isc__socketmgr_setstats

View file

@ -177,6 +177,7 @@ struct isc_socketevent {
struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */
isc_uint32_t attributes; /*%< see below */
isc_eventdestructor_t destroy; /*%< original destructor */
unsigned int dscp; /*%< UDP dscp value */
};
typedef struct isc_socket_newconnev isc_socket_newconnev_t;
@ -203,6 +204,7 @@ struct isc_socket_connev {
* _TIMESTAMP: The timestamp member is valid.
* _PKTINFO: The pktinfo member is valid.
* _MULTICAST: The UDP packet was received via a multicast transmission.
* _DSCP: The UDP DSCP value is valid.
*/
#define ISC_SOCKEVENTATTR_ATTACHED 0x80000000U /* internal */
#define ISC_SOCKEVENTATTR_TRUNC 0x00800000U /* public */
@ -210,6 +212,7 @@ struct isc_socket_connev {
#define ISC_SOCKEVENTATTR_TIMESTAMP 0x00200000U /* public */
#define ISC_SOCKEVENTATTR_PKTINFO 0x00100000U /* public */
#define ISC_SOCKEVENTATTR_MULTICAST 0x00080000U /* public */
#define ISC_SOCKEVENTATTR_DSCP 0x00040000U /* public */
/*@}*/
#define ISC_SOCKEVENT_ANYEVENT (0)
@ -314,6 +317,7 @@ typedef struct isc_socketmethods {
isc_result_t (*dup)(isc_socket_t *socket,
isc_socket_t **socketp);
int (*getfd)(isc_socket_t *socket);
void (*dscp)(isc_socket_t *socket, isc_dscp_t dscp);
} isc_socketmethods_t;
/*%
@ -1073,6 +1077,24 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
*/
/*@}*/
void
isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp);
/*%<
* Sets the Differentiated Services Code Point (DSCP) field for packets
* transmitted on this socket. If 'dscp' is -1, return immediately.
*
* Requires:
*\li 'sock' is a valid socket.
*/
isc_socketevent_t *
isc_socket_socketevent(isc_mem_t *mctx, void *sender,
isc_eventtype_t eventtype, isc_taskaction_t action,
const void *arg);
/*%<
* Get a isc_socketevent_t to be used with isc_socket_sendto2(), etc.
*/
void
isc_socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active);

View file

@ -50,6 +50,7 @@ typedef struct isc_buffer isc_buffer_t; /*%< Buffer */
typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
typedef struct isc_constregion isc_constregion_t; /*%< Const region */
typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
typedef isc_int16_t isc_dscp_t; /*%< Diffserv code point */
typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
typedef struct isc_event isc_event_t; /*%< Event */

View file

@ -202,6 +202,13 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
sock->methods->ipv6only(sock, yes);
}
void
isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp) {
REQUIRE(ISCAPI_SOCKET_VALID(sock));
sock->methods->dscp(sock, dscp);
}
isc_sockettype_t
isc_socket_gettype(isc_socket_t *sock) {
REQUIRE(ISCAPI_SOCKET_VALID(sock));

View file

@ -37,13 +37,13 @@ LIBS = @LIBS@ @ATFLIBS@
OBJS = isctest.@O@
SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \
sockaddr_test.c symtab_test.c task_test.c queue_test.c \
parse_test.c pool_test.c regex_test.c
parse_test.c pool_test.c regex_test.c socket_test.c
SUBDIRS =
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
sockaddr_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \
queue_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \
regex_test@EXEEXT@
regex_test@EXEEXT@ socket_test@EXEEXT@
@BIND9_MAKE_RULES@

View file

@ -91,7 +91,7 @@ create_managers() {
CHECK(isc_socketmgr_create(mctx, &socketmgr));
return (ISC_R_SUCCESS);
cleanup:
cleanup:
cleanup_managers();
return (result);
}

View file

@ -30,17 +30,38 @@
#include "../task_p.h"
#include "isctest.h"
static isc_boolean_t recv_dscp;
static unsigned int recv_dscp_value;
/*
* Helper functions
*/
typedef struct {
isc_boolean_t done;
isc_result_t result;
isc_socket_t *socket;
} completion_t;
static void
completion_init(completion_t *completion) {
completion->done = ISC_FALSE;
completion->socket = NULL;
}
static void
accept_done(isc_task_t *task, isc_event_t *event) {
isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
completion_t *completion = event->ev_arg;
UNUSED(task);
completion->result = nevent->result;
completion->done = ISC_TRUE;
if (completion->result == ISC_R_SUCCESS)
completion->socket = nevent->newsocket;
isc_event_free(&event);
}
static void
@ -53,6 +74,11 @@ event_done(isc_task_t *task, isc_event_t *event) {
dev = (isc_socketevent_t *) event;
completion->result = dev->result;
completion->done = ISC_TRUE;
if ((dev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) {
recv_dscp = ISC_TRUE;
recv_dscp_value = dev->dscp;;
} else
recv_dscp = ISC_FALSE;
isc_event_free(&event);
}
@ -71,6 +97,49 @@ waitfor(completion_t *completion) {
return (ISC_R_FAILURE);
}
#if 0
static isc_result_t
waitfor(completion_t *completion) {
int i = 0;
while (!completion->done && i++ < 5000) {
waitbody();
}
if (completion->done)
return (ISC_R_SUCCESS);
return (ISC_R_FAILURE);
}
#endif
static void
waitbody() {
#ifndef ISC_PLATFORM_USETHREADS
struct timeval tv;
isc_socketwait_t *swait = NULL;
while (isc__taskmgr_ready(taskmgr))
isc__taskmgr_dispatch(taskmgr);
if (socketmgr != NULL) {
tv.tv_sec = 0;
tv.tv_usec = 1000 ;
if (isc__socketmgr_waitevents(socketmgr, &tv, &swait) > 0)
isc__socketmgr_dispatch(socketmgr, swait);
} else
#endif
isc_test_nap(1000);
}
static isc_result_t
waitfor2(completion_t *c1, completion_t *c2) {
int i = 0;
while (!(c1->done && c2->done) && i++ < 5000) {
waitbody();
}
if (c1->done && c2->done)
return (ISC_R_SUCCESS);
return (ISC_R_FAILURE);
}
/*
* Individual unit tests
*/
@ -243,13 +312,454 @@ ATF_TC_BODY(udp_dup, tc) {
isc_test_end();
}
/* Test TCP sendto/recv (IPv4) */
ATF_TC(udp_dscp_v4);
ATF_TC_HEAD(udp_dscp_v4, tc) {
atf_tc_set_md_var(tc, "descr", "UDP DSCP IPV4");
}
ATF_TC_BODY(udp_dscp_v4, tc) {
isc_result_t result;
isc_sockaddr_t addr1, addr2;
struct in_addr in;
isc_socket_t *s1 = NULL, *s2 = NULL;
isc_task_t *task = NULL;
char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
completion_t completion;
isc_region_t r;
isc_socketevent_t *socketevent;
UNUSED(tc);
result = isc_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/*
* Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to
* each other.
*/
in.s_addr = inet_addr("127.0.0.1");
isc_sockaddr_fromin(&addr1, &in, 5444);
isc_sockaddr_fromin(&addr2, &in, 5445);
result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_task_create(taskmgr, 0, &task);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
strcpy(sendbuf, "Hello");
r.base = (void *) sendbuf;
r.length = strlen(sendbuf) + 1;
completion_init(&completion);
socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
event_done, &completion);
ATF_REQUIRE(socketevent != NULL);
if ((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0) {
socketevent->dscp = 056; /* EF */
socketevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
} else if ((isc_net_probedscp() & ISC_NET_DSCPSETV4) != 0) {
isc_socket_dscp(s1, 056); /* EF */
socketevent->dscp = 0;
socketevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
}
recv_dscp = ISC_FALSE;
recv_dscp_value = 0;
result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
r.base = (void *) recvbuf;
r.length = BUFSIZ;
completion_init(&completion);
result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
ATF_CHECK_STREQ(recvbuf, "Hello");
if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) {
ATF_CHECK(recv_dscp);
ATF_CHECK_EQ(recv_dscp_value, 056);
} else
ATF_CHECK(!recv_dscp);
isc_task_detach(&task);
isc_socket_detach(&s1);
isc_socket_detach(&s2);
isc_test_end();
}
/* Test TCP sendto/recv (IPv4) */
ATF_TC(udp_dscp_v6);
ATF_TC_HEAD(udp_dscp_v6, tc) {
atf_tc_set_md_var(tc, "descr", "udp dscp ipv6");
}
ATF_TC_BODY(udp_dscp_v6, tc) {
isc_result_t result;
isc_sockaddr_t addr1, addr2;
struct in6_addr in6;
isc_socket_t *s1 = NULL, *s2 = NULL;
isc_task_t *task = NULL;
char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
completion_t completion;
isc_region_t r;
isc_socketevent_t *socketevent;
UNUSED(tc);
result = isc_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/*
* Create two sockets: ::1/5444 and ::1/5445, talking to
* each other.
*/
inet_pton(AF_INET6, "::1", &in6.s6_addr);
isc_sockaddr_fromin6(&addr1, &in6, 5444);
isc_sockaddr_fromin6(&addr2, &in6, 5445);
result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp,
&s1);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp,
&s2);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
result = isc_task_create(taskmgr, 0, &task);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
isc_result_totext(result));
strcpy(sendbuf, "Hello");
r.base = (void *) sendbuf;
r.length = strlen(sendbuf) + 1;
completion_init(&completion);
socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
event_done, &completion);
ATF_REQUIRE(socketevent != NULL);
if ((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0) {
socketevent->dscp = 056; /* EF */
socketevent->attributes = ISC_SOCKEVENTATTR_DSCP;
} else if ((isc_net_probedscp() & ISC_NET_DSCPSETV6) != 0)
isc_socket_dscp(s1, 056); /* EF */
recv_dscp = ISC_FALSE;
recv_dscp_value = 0;
result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
r.base = (void *) recvbuf;
r.length = BUFSIZ;
completion_init(&completion);
result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
ATF_CHECK_STREQ(recvbuf, "Hello");
if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) {
ATF_CHECK(recv_dscp);
ATF_CHECK_EQ(recv_dscp_value, 056);
} else
ATF_CHECK(!recv_dscp);
isc_task_detach(&task);
isc_socket_detach(&s1);
isc_socket_detach(&s2);
isc_test_end();
}
/* Test TCP sendto/recv (IPv4) */
ATF_TC(tcp_dscp_v4);
ATF_TC_HEAD(tcp_dscp_v4, tc) {
atf_tc_set_md_var(tc, "descr", "tcp dscp ipv4");
}
ATF_TC_BODY(tcp_dscp_v4, tc) {
isc_result_t result;
isc_sockaddr_t addr1;
struct in_addr in;
isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
isc_task_t *task = NULL;
char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
completion_t completion, completion2;
isc_region_t r;
UNUSED(tc);
result = isc_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/*
* Create two sockets: 127.0.0.1/5444, talking to each other.
*/
in.s_addr = inet_addr("127.0.0.1");
isc_sockaddr_fromin(&addr1, &in, 5444);
result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s1);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_socket_listen(s1, 3);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
completion_init(&completion2);
result = isc_socket_accept(s1, task, accept_done, &completion2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
completion_init(&completion);
result = isc_socket_connect(s2, &addr1, task, event_done, &completion);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
waitfor2(&completion, &completion2);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
ATF_CHECK(completion2.done);
ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS);
s3 = completion2.socket;
isc_socket_dscp(s2, 056); /* EF */
strcpy(sendbuf, "Hello");
r.base = (void *) sendbuf;
r.length = strlen(sendbuf) + 1;
recv_dscp = ISC_FALSE;
recv_dscp_value = 0;
completion_init(&completion);
result = isc_socket_sendto(s2, &r, task, event_done, &completion,
NULL, NULL);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
r.base = (void *) recvbuf;
r.length = BUFSIZ;
completion_init(&completion);
result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
ATF_CHECK_STREQ(recvbuf, "Hello");
if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) {
if (recv_dscp)
ATF_CHECK_EQ(recv_dscp_value, 056);
} else
ATF_CHECK(!recv_dscp);
isc_task_detach(&task);
isc_socket_detach(&s1);
isc_socket_detach(&s2);
isc_socket_detach(&s3);
isc_test_end();
}
/* Test TCP sendto/recv (IPv6) */
ATF_TC(tcp_dscp_v6);
ATF_TC_HEAD(tcp_dscp_v6, tc) {
atf_tc_set_md_var(tc, "descr", "tcp dscp ipv6");
}
ATF_TC_BODY(tcp_dscp_v6, tc) {
isc_result_t result;
isc_sockaddr_t addr1;
struct in6_addr in6;
isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
isc_task_t *task = NULL;
char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
completion_t completion, completion2;
isc_region_t r;
UNUSED(tc);
result = isc_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/*
* Create two sockets: ::1/5444, talking to each other.
*/
inet_pton(AF_INET6, "::1", &in6.s6_addr);
isc_sockaddr_fromin6(&addr1, &in6, 5444);
result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp,
&s1);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_socket_listen(s1, 3);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp,
&s2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
completion_init(&completion2);
result = isc_socket_accept(s1, task, accept_done, &completion2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
completion_init(&completion);
result = isc_socket_connect(s2, &addr1, task, event_done, &completion);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
waitfor2(&completion, &completion2);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
ATF_CHECK(completion2.done);
ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS);
s3 = completion2.socket;
isc_socket_dscp(s2, 056); /* EF */
strcpy(sendbuf, "Hello");
r.base = (void *) sendbuf;
r.length = strlen(sendbuf) + 1;
recv_dscp = ISC_FALSE;
recv_dscp_value = 0;
completion_init(&completion);
result = isc_socket_sendto(s2, &r, task, event_done, &completion,
NULL, NULL);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
r.base = (void *) recvbuf;
r.length = BUFSIZ;
completion_init(&completion);
result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
waitfor(&completion);
ATF_CHECK(completion.done);
ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
ATF_CHECK_STREQ(recvbuf, "Hello");
if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) {
/*
* IPV6_RECVTCLASS is undefined for TCP however
* if we do get it should be the the value we set.
*/
if (recv_dscp)
ATF_CHECK_EQ(recv_dscp_value, 056);
} else
ATF_CHECK(!recv_dscp);
isc_task_detach(&task);
isc_socket_detach(&s1);
isc_socket_detach(&s2);
isc_socket_detach(&s3);
isc_test_end();
}
ATF_TC(net_probedscp);
ATF_TC_HEAD(net_probedscp, tc) {
atf_tc_set_md_var(tc, "descr", "probe dscp capabilities");
}
ATF_TC_BODY(net_probedscp, tc) {
unsigned int n;
UNUSED(tc);
n = isc_net_probedscp();
ATF_CHECK((n & ~ISC_NET_DSCPALL) == 0);
/* ISC_NET_DSCPSETV4 MUST be set if any is set. */
if (n & (ISC_NET_DSCPSETV4|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4))
ATF_CHECK_MSG((n & ISC_NET_DSCPSETV4) != 0,
"IPv4:%s%s%s\n",
(n & ISC_NET_DSCPSETV4) ? " set" : " none",
(n & ISC_NET_DSCPPKTV4) ? " packet" : "",
(n & ISC_NET_DSCPRECVV4) ? " receive" : "");
/* ISC_NET_DSCPSETV6 MUST be set if any is set. */
if (n & (ISC_NET_DSCPSETV6|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4))
ATF_CHECK_MSG((n & ISC_NET_DSCPSETV6) != 0,
"IPv6:%s%s%s\n",
(n & ISC_NET_DSCPSETV6) ? " set" : " none",
(n & ISC_NET_DSCPPKTV6) ? " packet" : "",
(n & ISC_NET_DSCPRECVV6) ? " receive" : "");
#if 0
fprintf(stdout, "IPv4:%s%s%s\n",
(n & ISC_NET_DSCPSETV4) ? " set" : "none",
(n & ISC_NET_DSCPPKTV4) ? " packet" : "",
(n & ISC_NET_DSCPRECVV4) ? " receive" : "");
printf(stdout, "IPv6:%s%s%s\n",
(n & ISC_NET_DSCPSETV6) ? " set" : "none",
(n & ISC_NET_DSCPPKTV6) ? " packet" : "",
(n & ISC_NET_DSCPRECVV6) ? " receive" : "");
#endif
}
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
ATF_TP_ADD_TC(tp, udp_sendto);
ATF_TP_ADD_TC(tp, udp_dup);
ATF_TP_ADD_TC(tp, tcp_dscp_v4);
ATF_TP_ADD_TC(tp, tcp_dscp_v6);
ATF_TP_ADD_TC(tp, udp_dscp_v4);
ATF_TP_ADD_TC(tp, udp_dscp_v6);
ATF_TP_ADD_TC(tp, net_probedscp);
return (atf_no_error());
}

View file

@ -324,6 +324,21 @@ isc_net_probeunix(void);
* Returns whether UNIX domain sockets are supported.
*/
#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */
#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */
#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */
#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */
#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */
#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */
#define ISC_NET_DSCPALL 0x3f /* All valid flags */
unsigned int
isc_net_probedscp(void);
/*%<
* Probe the level of DSCP support.
*/
isc_result_t
isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
/*%<

View file

@ -34,11 +34,16 @@
#include <isc/log.h>
#include <isc/msgs.h>
#include <isc/net.h>
#include <isc/netdb.h>
#include <isc/once.h>
#include <isc/strerror.h>
#include <isc/string.h>
#include <isc/util.h>
#ifndef ISC_SOCKADDR_LEN_T
#define ISC_SOCKADDR_LEN_T unsigned int
#endif
/*%
* Definitions about UDP port range specification. This is a total mess of
* portability variants: some use sysctl (but the sysctl names vary), some use
@ -111,12 +116,14 @@ static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
#endif /* ISC_PLATFORM_HAVEIPV6 */
static isc_once_t once = ISC_ONCE_INIT;
static isc_once_t once_dscp = ISC_ONCE_INIT;
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
static isc_result_t ipv6_result = ISC_R_NOTFOUND;
static isc_result_t unix_result = ISC_R_NOTFOUND;
static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
static unsigned int dscp_result = 0;
static isc_result_t
try_proto(int domain) {
@ -397,6 +404,259 @@ isc_net_probe_ipv6pktinfo(void) {
return (ipv6pktinfo_result);
}
static inline ISC_SOCKADDR_LEN_T
cmsg_len(ISC_SOCKADDR_LEN_T len) {
#ifdef CMSG_LEN
return (CMSG_LEN(len));
#else
ISC_SOCKADDR_LEN_T hdrlen;
/*
* Cast NULL so that any pointer arithmetic performed by CMSG_DATA
* is correct.
*/
hdrlen = (ISC_SOCKADDR_LEN_T)CMSG_DATA(((struct cmsghdr *)NULL));
return (hdrlen + len);
#endif
}
static inline ISC_SOCKADDR_LEN_T
cmsg_space(ISC_SOCKADDR_LEN_T len) {
#ifdef CMSG_SPACE
return (CMSG_SPACE(len));
#else
struct msghdr msg;
struct cmsghdr *cmsgp;
/*
* XXX: The buffer length is an ad-hoc value, but should be enough
* in a practical sense.
*/
char dummybuf[sizeof(struct cmsghdr) + 1024];
memset(&msg, 0, sizeof(msg));
msg.msg_control = dummybuf;
msg.msg_controllen = sizeof(dummybuf);
cmsgp = (struct cmsghdr *)dummybuf;
cmsgp->cmsg_len = cmsg_len(len);
cmsgp = CMSG_NXTHDR(&msg, cmsgp);
if (cmsgp != NULL)
return ((char *)cmsgp - (char *)msg.msg_control);
else
return (0);
#endif
}
#ifdef ISC_NET_BSD44MSGHDR
static isc_boolean_t
cmsgsend(int s, int level, int type, struct addrinfo *res) {
char strbuf[ISC_STRERRORSIZE];
struct sockaddr_storage ss;
ISC_SOCKADDR_LEN_T len = sizeof(ss);
struct msghdr msg;
union {
struct cmsghdr h;
unsigned char b[256];
} control;
struct cmsghdr *cmsgp;
int dscp = 46;
struct iovec iovec = { &iovec, sizeof(iovec) };
if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"bind: %s", strbuf);
return (ISC_FALSE);
}
if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"getsockname: %s", strbuf);
return (ISC_FALSE);
}
memset(&msg, 0, sizeof(msg));
msg.msg_name = (struct sockaddr *)&ss;
msg.msg_namelen = len;
msg.msg_iov = &iovec;
msg.msg_iovlen = 1;
msg.msg_control = (void*)&control;
msg.msg_controllen = cmsg_space(sizeof(int));
msg.msg_flags = 0;
cmsgp = msg.msg_control;
cmsgp->cmsg_level = level;
cmsgp->cmsg_type = type;
if (cmsgp->cmsg_type == IP_TOS) {
cmsgp->cmsg_len = cmsg_len(sizeof(char));
*(unsigned char*)CMSG_DATA(cmsgp) = dscp;
} else {
cmsgp->cmsg_len = cmsg_len(sizeof(dscp));
memcpy(CMSG_DATA(cmsgp), &dscp, sizeof(dscp));
}
if (sendmsg(s, &msg, 0) < 0) {
int debug = ISC_LOG_DEBUG(10);
#ifdef ENOPROTOOPT
if (errno != ENOPROTOOPT && errno != EINVAL)
debug = ISC_LOG_NOTICE;
#endif
isc__strerror(errno, strbuf, sizeof(strbuf));
if (debug != ISC_LOG_NOTICE) {
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"sendmsg: %s", strbuf);
} else {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"sendmsg() %s: %s",
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
return (ISC_FALSE);
}
return (ISC_TRUE);
}
#endif
static void
try_dscp_v4(void) {
#ifdef IP_TOS
char strbuf[ISC_STRERRORSIZE];
struct addrinfo hints, *res0;
int s, dscp = 0, n;
#ifdef IP_RECVTOS
int on = 1;
#endif
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE;
n = getaddrinfo("127.0.0.1", NULL, &hints, &res0);
if (n != 0 || res0 == NULL) {
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"getaddrinfo(127.0.0.1): %s", gai_strerror(n));
return;
}
s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol);
if (s == -1) {
isc__strerror(errno, strbuf, sizeof(strbuf));
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"socket: %s", strbuf);
freeaddrinfo(res0);
close(s);
return;
}
if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == 0)
dscp_result |= ISC_NET_DSCPSETV4;
#ifdef IP_RECVTOS
on = 1;
if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on)) == 0)
dscp_result |= ISC_NET_DSCPRECVV4;
#endif
#ifdef ISC_NET_BSD44MSGHDR
#ifndef ISC_CMSG_IP_TOS
#ifdef __APPLE__
#define ISC_CMSG_IP_TOS 0 /* As of 10.8.2. */
#else
#define ISC_CMSG_IP_TOS 1
#endif
#endif
#if ISC_CMSG_IP_TOS
if (cmsgsend(s, IPPROTO_IP, IP_TOS, res0))
dscp_result |= ISC_NET_DSCPPKTV4;
#endif
#endif
freeaddrinfo(res0);
close(s);
#endif
}
static void
try_dscp_v6(void) {
#ifdef ISC_PLATFORM_HAVEIPV6
#ifdef WANT_IPV6
#ifdef IPV6_TCLASS
char strbuf[ISC_STRERRORSIZE];
struct addrinfo hints, *res0;
int s, dscp = 0, n;
#if defined(IPV6_RECVTCLASS)
int on = 1;
#endif
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE;
n = getaddrinfo("::1", NULL, &hints, &res0);
if (n != 0 || res0 == NULL) {
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"getaddrinfo(::1): %s", gai_strerror(n));
return;
}
s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol);
if (s == -1) {
isc__strerror(errno, strbuf, sizeof(strbuf));
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10),
"socket: %s", strbuf);
freeaddrinfo(res0);
return;
}
if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &dscp, sizeof(dscp)) == 0)
dscp_result |= ISC_NET_DSCPSETV6;
#ifdef IPV6_RECVTCLASS
on = 1;
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, sizeof(on)) == 0)
dscp_result |= ISC_NET_DSCPRECVV6;
#endif
#ifdef ISC_NET_BSD44MSGHDR
if (cmsgsend(s, IPPROTO_IPV6, IPV6_TCLASS, res0))
dscp_result |= ISC_NET_DSCPPKTV6;
#endif
freeaddrinfo(res0);
close(s);
#endif
#endif
#endif
}
static void
try_dscp() {
try_dscp_v4();
try_dscp_v6();
}
static void
initialize_dscp() {
RUNTIME_CHECK(isc_once_do(&once_dscp, try_dscp) == ISC_R_SUCCESS);
}
unsigned int
isc_net_probedscp(void) {
initialize_dscp();
return (dscp_result);
}
#if defined(USE_SYSCTL_PORTRANGE)
#if defined(HAVE_SYSCTLBYNAME)
static isc_result_t

View file

@ -127,6 +127,13 @@ struct isc_socketwait {
#endif /* USE_KQUEUE */
#endif /* !USE_WATCHER_THREAD */
/*
* Set by the -T dscp option on the command line. If set to a value
* other than -1, we check to make sure DSCP values match it, and
* assert if not.
*/
int isc_dscp_check_value = -1;
/*%
* Maximum number of allowable open sockets. This is also the maximum
* allowable socket file descriptor.
@ -352,6 +359,7 @@ struct isc__socket {
isc_sockfdwatch_t fdwatchcb;
int fdwatchflags;
isc_task_t *fdwatchtask;
int dscp;
};
#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g')
@ -455,6 +463,7 @@ static void build_msghdr_recv(isc__socket_t *, isc_socketevent_t *,
#ifdef USE_WATCHER_THREAD
static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager);
#endif
static void setdscp(isc__socket_t *sock, isc_dscp_t dscp);
/*%
* The following can be either static or public, depending on build environment.
@ -511,6 +520,11 @@ isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region,
isc_task_t *task,
isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
isc_socketevent_t *event, unsigned int flags);
isc_socketevent_t *
isc_socket_socketevent(isc_mem_t *mctx, void *sender,
isc_eventtype_t eventtype, isc_taskaction_t action,
const void *arg);
ISC_SOCKETFUNC_SCOPE void
isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active);
ISC_SOCKETFUNC_SCOPE isc_result_t
@ -542,6 +556,8 @@ ISC_SOCKETFUNC_SCOPE isc_boolean_t
isc__socket_isbound(isc_socket_t *sock);
ISC_SOCKETFUNC_SCOPE void
isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
ISC_SOCKETFUNC_SCOPE void
isc__socket_dscp(isc_socket_t *sock, isc_dscp_t dscp);
#ifdef BIND9
#ifdef HAVE_LIBXML2
ISC_SOCKETFUNC_SCOPE void
@ -590,7 +606,8 @@ static struct {
isc__socket_ipv6only,
isc__socket_fdwatchpoke,
isc__socket_dup,
isc__socket_getfd
isc__socket_getfd,
isc__socket_dscp
}
#ifndef BIND9
,
@ -1308,6 +1325,25 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
}
#endif
#ifdef IPV6_TCLASS
if (cmsgp->cmsg_level == IPPROTO_IPV6
&& cmsgp->cmsg_type == IPV6_TCLASS) {
dev->dscp = *(int *)CMSG_DATA(cmsgp);
dev->dscp >>= 2;
dev->attributes |= ISC_SOCKEVENTATTR_DSCP;
goto next;
}
#endif
#ifdef IP_TOS
if (cmsgp->cmsg_level == IPPROTO_IP
&& cmsgp->cmsg_type == IP_TOS) {
dev->dscp = (int) *(uint8_t *)CMSG_DATA(cmsgp);
dev->dscp >>= 2;
dev->attributes |= ISC_SOCKEVENTATTR_DSCP;
goto next;
}
#endif
next:
cmsgp = CMSG_NXTHDR(msg, cmsgp);
}
@ -1337,6 +1373,9 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
isc_region_t used;
size_t write_count;
size_t skip_count;
#ifdef ISC_NET_BSD44MSGHDR
struct cmsghdr *cmsgp;
#endif
memset(msg, 0, sizeof(*msg));
@ -1409,7 +1448,6 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
#if defined(IPV6_USE_MIN_MTU)
int use_min_mtu = 1; /* -1, 0, 1 */
#endif
struct cmsghdr *cmsgp;
struct in6_pktinfo *pktinfop;
socket_log(sock, NULL, TRACE,
@ -1444,6 +1482,83 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
memcpy(CMSG_DATA(cmsgp), &use_min_mtu, sizeof(use_min_mtu));
#endif
}
#ifdef BIND9
if (isc_dscp_check_value != -1) {
if (sock->type == isc_sockettype_udp)
INSIST((int)dev->dscp == isc_dscp_check_value);
if (sock->type == isc_sockettype_tcp)
INSIST(sock->dscp == isc_dscp_check_value);
}
if ((sock->type == isc_sockettype_udp)
&& ((dev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0)) {
int dscp = (dev->dscp << 2) & 0xff;
#ifdef IP_TOS
if (sock->pf == AF_INET &&
((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0))
{
cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf +
msg->msg_controllen);
msg->msg_control = (void *)sock->sendcmsgbuf;
msg->msg_controllen += cmsg_space(sizeof(dscp));
INSIST(msg->msg_controllen <= sock->sendcmsgbuflen);
cmsgp->cmsg_level = IPPROTO_IP;
cmsgp->cmsg_type = IP_TOS;
cmsgp->cmsg_len = cmsg_len(sizeof(char));
*(unsigned char*)CMSG_DATA(cmsgp) = dscp;
} else if (sock->pf == AF_INET) {
if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS,
(void *)&dscp, sizeof(int)) < 0)
{
char strbuf[ISC_STRERRORSIZE];
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IP_TOS, %.02x)"
" %s: %s",
sock->fd, dscp >> 2,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
}
#endif
#ifdef IPPROTO_IPV6
if (sock->pf == AF_INET6 &&
((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0))
{
cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf +
msg->msg_controllen);
msg->msg_control = (void *)sock->sendcmsgbuf;
msg->msg_controllen += cmsg_space(sizeof(dscp));
INSIST(msg->msg_controllen <= sock->sendcmsgbuflen);
cmsgp->cmsg_level = IPPROTO_IPV6;
cmsgp->cmsg_type = IPV6_TCLASS;
cmsgp->cmsg_len = cmsg_len(sizeof(dscp));
memcpy(CMSG_DATA(cmsgp), &dscp, sizeof(dscp));
} else if (sock->pf == AF_INET6) {
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS,
(void *)&dscp, sizeof(int)) < 0) {
char strbuf[ISC_STRERRORSIZE];
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_TCLASS, "
"%.02x) %s: %s",
sock->fd, dscp >> 2,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
}
#endif
}
#endif
#endif /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */
#else /* ISC_NET_BSD44MSGHDR */
msg->msg_accrights = NULL;
@ -1573,10 +1688,8 @@ build_msghdr_recv(isc__socket_t *sock, isc_socketevent_t *dev,
msg->msg_controllen = 0;
msg->msg_flags = 0;
#if defined(USE_CMSG)
if (sock->type == isc_sockettype_udp) {
msg->msg_control = sock->recvcmsgbuf;
msg->msg_controllen = sock->recvcmsgbuflen;
}
msg->msg_control = sock->recvcmsgbuf;
msg->msg_controllen = sock->recvcmsgbuflen;
#endif /* USE_CMSG */
#else /* ISC_NET_BSD44MSGHDR */
msg->msg_accrights = NULL;
@ -1612,14 +1725,14 @@ destroy_socketevent(isc_event_t *event) {
}
static isc_socketevent_t *
allocate_socketevent(isc__socket_t *sock, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
allocate_socketevent(isc_mem_t *mctx, void *sender,
isc_eventtype_t eventtype, isc_taskaction_t action,
const void *arg)
{
isc_socketevent_t *ev;
ev = (isc_socketevent_t *)isc_event_allocate(sock->manager->mctx,
sock, eventtype,
action, arg,
ev = (isc_socketevent_t *)isc_event_allocate(mctx, sender,
eventtype, action, arg,
sizeof(*ev));
if (ev == NULL)
@ -1634,6 +1747,7 @@ allocate_socketevent(isc__socket_t *sock, isc_eventtype_t eventtype,
ev->attributes = 0;
ev->destroy = ev->ev_destroy;
ev->ev_destroy = destroy_socketevent;
ev->dscp = 0;
return (ev);
}
@ -1801,8 +1915,7 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
* If there are control messages attached, run through them and pull
* out the interesting bits.
*/
if (sock->type == isc_sockettype_udp)
process_cmsg(sock, &msghdr, dev);
process_cmsg(sock, &msghdr, dev);
/*
* update the buffers (if any) and the i/o count
@ -2095,6 +2208,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
sock->manager = manager;
sock->type = type;
sock->fd = -1;
sock->dscp = -1;
sock->dupped = 0;
sock->statsindex = NULL;
@ -2112,6 +2226,9 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
#endif
#if defined(USE_CMSG) && defined(SO_TIMESTAMP)
cmsgbuflen += cmsg_space(sizeof(struct timeval));
#endif
#if defined(USE_CMSG) && (defined(IPV6_TCLASS) || defined(IP_TOS))
cmsgbuflen += cmsg_space(sizeof(int));
#endif
sock->recvcmsgbuflen = cmsgbuflen;
if (sock->recvcmsgbuflen != 0U) {
@ -2132,6 +2249,9 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
*/
cmsgbuflen += cmsg_space(sizeof(int));
#endif
#endif
#if defined(USE_CMSG) && (defined(IP_TOS) || defined(IPV6_TCLASS))
cmsgbuflen += cmsg_space(sizeof(int));
#endif
sock->sendcmsgbuflen = cmsgbuflen;
if (sock->sendcmsgbuflen != 0U) {
@ -2589,6 +2709,32 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
}
#endif
}
#ifdef IPV6_RECVTCLASS
if ((sock->pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVTCLASS,
(void *)&on, sizeof(on)) < 0)) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_RECVTCLASS) "
"%s: %s", sock->fd,
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"),
strbuf);
}
#endif
#ifdef IP_RECVTOS
if ((sock->pf == AF_INET)
&& (setsockopt(sock->fd, IPPROTO_IP, IP_RECVTOS,
(void *)&on, sizeof(on)) < 0)) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IP_RECVTOS) "
"%s: %s", sock->fd,
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"),
strbuf);
}
#endif
#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
setup_done:
@ -3339,6 +3485,12 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
*/
use_min_mtu(NEWCONNSOCK(dev));
/*
* Ensure DSCP settings are inherited across accept.
*/
if (sock->dscp != -1)
setdscp(NEWCONNSOCK(dev), sock->dscp);
/*
* Save away the remote address
*/
@ -4617,7 +4769,8 @@ isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist,
INSIST(sock->bound);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_RECVDONE, action, arg);
if (dev == NULL)
return (ISC_R_NOMEMORY);
@ -4663,7 +4816,8 @@ isc__socket_recv(isc_socket_t *sock0, isc_region_t *region,
INSIST(sock->bound);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_RECVDONE, action, arg);
if (dev == NULL)
return (ISC_R_NOMEMORY);
@ -4822,7 +4976,8 @@ isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region,
INSIST(sock->bound);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_SENDDONE, action, arg);
if (dev == NULL)
return (ISC_R_NOMEMORY);
@ -4862,7 +5017,8 @@ isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist,
iocount = isc_bufferlist_usedcount(buflist);
REQUIRE(iocount > 0);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_SENDDONE, action, arg);
if (dev == NULL)
return (ISC_R_NOMEMORY);
@ -4897,7 +5053,7 @@ isc__socket_sendto2(isc_socket_t *sock0, isc_region_t *region,
event->region = *region;
event->n = 0;
event->offset = 0;
event->attributes = 0;
event->attributes &= ~ISC_SOCKEVENTATTR_ATTACHED;
return (socket_send(sock, event, task, address, pktinfo, flags));
}
@ -5811,6 +5967,84 @@ isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) {
#endif
}
static void
setdscp(isc__socket_t *sock, isc_dscp_t dscp) {
sock->dscp = dscp;
#if defined(IP_TOS) || defined(IPV6_TCLASS)
dscp <<= 2;
#endif
#ifdef IP_TOS
if (sock->pf == AF_INET) {
if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS,
(void *)&dscp, sizeof(int)) < 0) {
char strbuf[ISC_STRERRORSIZE];
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IP_TOS, %.02x) "
"%s: %s", sock->fd, dscp >> 2,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
}
#endif
#ifdef IPV6_TCLASS
if (sock->pf == AF_INET6) {
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS,
(void *)&dscp, sizeof(int)) < 0) {
char strbuf[ISC_STRERRORSIZE];
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_TCLASS, %.02x) "
"%s: %s", sock->fd, dscp >> 2,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
}
#endif
}
ISC_SOCKETFUNC_SCOPE void
isc__socket_dscp(isc_socket_t *sock0, isc_dscp_t dscp) {
isc__socket_t *sock = (isc__socket_t *)sock0;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(dscp < 0x40);
#if !defined(IP_TOS) && !defined(IPV6_TCLASS)
UNUSED(dscp);
#else
if (dscp < 0)
return;
if (isc_dscp_check_value != -1)
INSIST(dscp == isc_dscp_check_value);
#endif
#ifdef notyet
REQUIRE(!sock->dupped);
#endif
setdscp(sock, dscp);
}
isc_socketevent_t *
isc_socket_socketevent(isc_mem_t *mctx, void *sender,
isc_eventtype_t eventtype, isc_taskaction_t action,
const void *arg)
{
return (allocate_socketevent(mctx, sender, eventtype, action, arg));
}
#ifndef USE_WATCHER_THREAD
/*
* In our assumed scenario, we can simply use a single static object.

View file

@ -269,6 +269,20 @@ isc_net_probeunix(void);
* ISC_R_NOTFOUND
*/
#define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */
#define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */
#define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */
#define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */
#define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */
#define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */
#define ISC_NET_DSCPALL 0x3f /* All valid flags */
unsigned int
isc_net_probedscp(void);
/*%<
* Probe the level of DSCP support.
*/
isc_result_t
isc_net_probe_ipv6only(void);
/*

View file

@ -110,6 +110,7 @@ isc__socket_sendto2
isc__socket_sendtov
isc__socket_sendv
isc__socket_setname
isc__socket_socketevent
isc__socketmgr_create
isc__socketmgr_create2
isc__socketmgr_destroy
@ -387,6 +388,7 @@ isc_net_getudpportrange
isc_net_ntop
isc_net_probe_ipv6only
isc_net_probe_ipv6pktinfo
isc_net_probedscp
isc_net_probeipv4
isc_net_probeipv6
isc_net_probeunix
@ -517,6 +519,7 @@ isc_sockaddr_pf
isc_sockaddr_setport
isc_sockaddr_totext
isc_sockaddr_v6fromin
isc_socket_dscp
isc_socketmgr_renderxml
isc_stats_attach
isc_stats_create

View file

@ -331,3 +331,8 @@ isc_net_enableipv6(void) {
if (ipv6_result == ISC_R_DISABLED)
ipv6_result = ISC_R_SUCCESS;
}
unsigned int
isc_net_probedscp() {
return (0);
}

View file

@ -1061,13 +1061,13 @@ destroy_socketevent(isc_event_t *event) {
}
static isc_socketevent_t *
allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
allocate_socketevent(isc_mem_t *mctx, isc_socket_t *sock,
isc_eventtype_t eventtype, isc_taskaction_t action,
const void *arg)
{
isc_socketevent_t *ev;
ev = (isc_socketevent_t *)isc_event_allocate(sock->manager->mctx,
sock, eventtype,
ev = (isc_socketevent_t *)isc_event_allocate(mctx, sock, eventtype,
action, arg,
sizeof(*ev));
if (ev == NULL)
@ -2840,7 +2840,8 @@ isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
INSIST(sock->bound);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_RECVDONE, action, arg);
if (dev == NULL) {
UNLOCK(&sock->lock);
return (ISC_R_NOMEMORY);
@ -2901,7 +2902,8 @@ isc__socket_recv(isc_socket_t *sock, isc_region_t *region,
INSIST(sock->bound);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_RECVDONE, action, arg);
if (dev == NULL) {
UNLOCK(&sock->lock);
return (ISC_R_NOMEMORY);
@ -3064,7 +3066,8 @@ isc__socket_sendto(isc_socket_t *sock, isc_region_t *region,
INSIST(sock->bound);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_SENDDONE, action, arg);
if (dev == NULL) {
UNLOCK(&sock->lock);
return (ISC_R_NOMEMORY);
@ -3118,7 +3121,8 @@ isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
iocount = isc_bufferlist_usedcount(buflist);
REQUIRE(iocount > 0);
dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg);
dev = allocate_socketevent(manager->mctx, sock,
ISC_SOCKEVENT_SENDDONE, action, arg);
if (dev == NULL) {
UNLOCK(&sock->lock);
return (ISC_R_NOMEMORY);
@ -3803,6 +3807,34 @@ isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
#endif
}
void
isc__socket_dscp(isc_socket_t *sock, unsigned int dscp) {
#if !defined(IP_TOS) && !defined(IPV6_TCLASS)
UNUSED(dscp);
#else
if (dscp < 0)
return;
dscp <<= 2;
dscp &= 0xff;
#endif
REQUIRE(VALID_SOCKET(sock));
#ifdef IP_TOS
if (sock->pf == AF_INET) {
(void)setsockopt(sock->fd, IPPROTO_IP, IP_TOS,
(char *)&dscp, sizeof(dscp));
}
#endif
#ifdef IPV6_TCLASS
if (sock->pf == AF_INET6) {
(void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS,
(char *)&dscp, sizeof(dscp));
}
#endif
}
void
isc__socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active) {
UNUSED(addr);
@ -3864,6 +3896,14 @@ isc___socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) {
UNUSED(maxudp);
}
isc_socketevent_t *
isc__socket_socketevent(isc_mem_t *mctx, void *sender,
isc_eventtype_t eventtype, isc_taskaction_t action,
const void *arg)
{
return (allocate_socketevent(mctx, sender, eventtype, action, arg));
}
#ifdef HAVE_LIBXML2
static const char *

View file

@ -303,6 +303,20 @@ cfg_obj_assockaddr(const cfg_obj_t *obj);
* if necessary.
*/
isc_dscp_t
cfg_obj_getdscp(const cfg_obj_t *obj);
/*%<
* Returns the DSCP value of a configuration object representing a
* socket address.
*
* Requires:
* \li 'obj' points to a valid configuration object of a
* socket address type.
*
* Returns:
* \li DSCP value associated with a sockaddr, or -1.
*/
isc_boolean_t
cfg_obj_isnetprefix(const cfg_obj_t *obj);
/*%<

View file

@ -157,6 +157,10 @@ struct cfg_obj {
cfg_list_t list;
cfg_obj_t ** tuple;
isc_sockaddr_t sockaddr;
struct {
isc_sockaddr_t sockaddr;
isc_dscp_t dscp;
} sockaddrdscp;
cfg_netprefix_t netprefix;
} value;
isc_refcount_t references; /*%< reference counter */
@ -237,6 +241,7 @@ struct cfg_parser {
#define CFG_ADDR_V4PREFIXOK 0x00000002
#define CFG_ADDR_V6OK 0x00000004
#define CFG_ADDR_WILDOK 0x00000008
#define CFG_ADDR_DSCPOK 0x00000010
#define CFG_ADDR_MASK (CFG_ADDR_V6OK|CFG_ADDR_V4OK)
/*@}*/
@ -267,6 +272,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
@ -325,6 +331,9 @@ cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
isc_result_t
cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
isc_result_t
cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp);
isc_result_t
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

View file

@ -97,6 +97,7 @@ static cfg_type_t cfg_type_acl;
static cfg_type_t cfg_type_addrmatchelt;
static cfg_type_t cfg_type_bracketed_aml;
static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
static cfg_type_t cfg_type_bracketed_dscpsockaddrlist;
static cfg_type_t cfg_type_bracketed_sockaddrlist;
static cfg_type_t cfg_type_bracketed_sockaddrnameportlist;
static cfg_type_t cfg_type_controls;
@ -118,6 +119,7 @@ static cfg_type_t cfg_type_optional_class;
static cfg_type_t cfg_type_optional_facility;
static cfg_type_t cfg_type_optional_keyref;
static cfg_type_t cfg_type_optional_port;
static cfg_type_t cfg_type_optional_dscp;
static cfg_type_t cfg_type_options;
static cfg_type_t cfg_type_portiplist;
static cfg_type_t cfg_type_querysource4;
@ -181,11 +183,15 @@ static cfg_type_t cfg_type_tkey_dhkey = {
static cfg_tuplefielddef_t listenon_fields[] = {
{ "port", &cfg_type_optional_port, 0 },
{ "dscp", &cfg_type_optional_dscp, 0 },
{ "acl", &cfg_type_bracketed_aml, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_listenon = {
"listenon", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, listenon_fields };
"listenon", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
&cfg_rep_tuple, listenon_fields
};
/*% acl */
@ -202,6 +208,7 @@ static cfg_type_t cfg_type_acl = {
static cfg_tuplefielddef_t masters_fields[] = {
{ "name", &cfg_type_astring, 0 },
{ "port", &cfg_type_optional_port, 0 },
{ "dscp", &cfg_type_optional_dscp, 0 },
{ "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
{ NULL, NULL, 0 }
};
@ -234,6 +241,7 @@ static cfg_type_t cfg_type_bracketed_namesockaddrkeylist = {
static cfg_tuplefielddef_t namesockaddrkeylist_fields[] = {
{ "port", &cfg_type_optional_port, 0 },
{ "dscp", &cfg_type_optional_dscp, 0 },
{ "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
{ NULL, NULL, 0 }
};
@ -248,7 +256,8 @@ static cfg_type_t cfg_type_namesockaddrkeylist = {
*/
static cfg_tuplefielddef_t portiplist_fields[] = {
{ "port", &cfg_type_optional_port, 0 },
{ "addresses", &cfg_type_bracketed_sockaddrlist, 0 },
{ "dscp", &cfg_type_optional_dscp, 0 },
{ "addresses", &cfg_type_bracketed_dscpsockaddrlist, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_portiplist = {
@ -547,13 +556,20 @@ static cfg_tuplefielddef_t checknames_fields[] = {
};
static cfg_type_t cfg_type_checknames = {
"checknames", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
checknames_fields
"checknames", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
&cfg_rep_tuple, checknames_fields
};
static cfg_type_t cfg_type_bracketed_dscpsockaddrlist = {
"bracketed_sockaddrlist", cfg_parse_bracketed_list,
cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list,
&cfg_type_sockaddrdscp
};
static cfg_type_t cfg_type_bracketed_sockaddrlist = {
"bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
&cfg_rep_list, &cfg_type_sockaddr
"bracketed_sockaddrlist", cfg_parse_bracketed_list,
cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list,
&cfg_type_sockaddr
};
static const char *autodnssec_enums[] = { "allow", "maintain", "off", NULL };
@ -592,8 +608,15 @@ static cfg_type_t cfg_type_zonestat = {
};
static cfg_type_t cfg_type_rrsetorder = {
"rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
&cfg_rep_list, &cfg_type_rrsetorderingelement
"rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list,
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_rrsetorderingelement
};
static keyword_type_t dscp_kw = { "dscp", &cfg_type_uint32 };
static cfg_type_t cfg_type_optional_dscp = {
"optional_dscp", parse_optional_keyvalue, print_keyvalue,
doc_optional_keyvalue, &cfg_rep_uint32, &dscp_kw
};
static keyword_type_t port_kw = { "port", &cfg_type_uint32 };
@ -934,6 +957,7 @@ options_clauses[] = {
{ "session-keyalg", &cfg_type_astring, 0 },
{ "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
{ "dscp", &cfg_type_uint32, 0 },
{ "dump-file", &cfg_type_qstring, 0 },
{ "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "files", &cfg_type_size, 0 },
@ -2033,7 +2057,9 @@ parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
}
static isc_result_t
parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
return (parse_maybe_optional_keyvalue(pctx, type, ISC_TRUE, ret));
}
@ -2379,9 +2405,11 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
isc_result_t result;
cfg_obj_t *obj = NULL;
isc_netaddr_t netaddr;
in_port_t port;
in_port_t port = 0;
isc_dscp_t dscp = -1;
unsigned int have_address = 0;
unsigned int have_port = 0;
unsigned int have_dscp = 0;
const unsigned int *flagp = type->of;
if ((*flagp & CFG_ADDR_V4OK) != 0)
@ -2391,8 +2419,6 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
else
INSIST(0);
port = 0;
for (;;) {
CHECK(cfg_peektoken(pctx, 0));
if (pctx->token.type == isc_tokentype_string) {
@ -2412,11 +2438,20 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
CFG_ADDR_WILDOK,
&port));
have_port++;
} else if (have_port == 0 && have_address == 0) {
} else if (strcasecmp(TOKEN_STRING(pctx), "dscp") == 0)
{
/* read "dscp" */
CHECK(cfg_gettoken(pctx, 0));
CHECK(cfg_parse_dscp(pctx, &dscp));
have_dscp++;
} else if (have_port == 0 && have_dscp == 0 &&
have_address == 0)
{
return (cfg_parse_sockaddr(pctx, type, ret));
} else {
cfg_parser_error(pctx, CFG_LOG_NEAR,
"expected 'address' or 'port'");
"expected 'address', 'port', "
"or 'dscp'");
return (ISC_R_UNEXPECTEDTOKEN);
}
} else
@ -2428,8 +2463,14 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
return (ISC_R_UNEXPECTEDTOKEN);
}
if (have_dscp > 1) {
cfg_parser_error(pctx, 0, "expected at most one dscp");
return (ISC_R_UNEXPECTEDTOKEN);
}
CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj));
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
obj->value.sockaddrdscp.dscp = dscp;
*ret = obj;
return (ISC_R_SUCCESS);
@ -2447,10 +2488,16 @@ print_querysource(cfg_printer_t *pctx, const cfg_obj_t *obj) {
cfg_print_rawaddr(pctx, &na);
cfg_print_cstr(pctx, " port ");
cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr));
if (obj->value.sockaddrdscp.dscp != -1) {
cfg_print_cstr(pctx, " dscp ");
cfg_print_rawuint(pctx, obj->value.sockaddrdscp.dscp);
}
}
static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK;
static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK;
static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK |
CFG_ADDR_DSCPOK;
static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK |
CFG_ADDR_DSCPOK;
static cfg_type_t cfg_type_querysource4 = {
"querysource4", parse_querysource, NULL, cfg_doc_terminal,
@ -2780,7 +2827,7 @@ static cfg_type_t cfg_type_logfile = {
&cfg_rep_tuple, logfile_fields
};
/*% An IPv4 address with optional port, "*" accepted as wildcard. */
/*% An IPv4 address with optional dscp and port, "*" accepted as wildcard. */
static cfg_type_t cfg_type_sockaddr4wild = {
"sockaddr4wild", cfg_parse_sockaddr, cfg_print_sockaddr,
cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr4wild_flags
@ -2923,8 +2970,10 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_sessionkey = {
static cfg_tuplefielddef_t nameport_fields[] = {
{ "name", &cfg_type_astring, 0 },
{ "port", &cfg_type_optional_port, 0 },
{ "dscp", &cfg_type_optional_dscp, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_nameport = {
"nameport", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
&cfg_rep_tuple, nameport_fields
@ -2937,14 +2986,20 @@ doc_sockaddrnameport(cfg_printer_t *pctx, const cfg_type_t *type) {
cfg_print_cstr(pctx, "<quoted_string>");
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "[ port <integer> ]");
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "[ dscp <integer> ]");
cfg_print_chars(pctx, " | ", 3);
cfg_print_cstr(pctx, "<ipv4_address>");
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "[ port <integer> ]");
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "[ dscp <integer> ]");
cfg_print_chars(pctx, " | ", 3);
cfg_print_cstr(pctx, "<ipv6_address>");
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "[ port <integer> ]");
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "[ dscp <integer> ]");
cfg_print_chars(pctx, " )", 2);
}
@ -2970,6 +3025,8 @@ parse_sockaddrnameport(cfg_parser_t *pctx, const cfg_type_t *type,
&obj->value.tuple[0]));
CHECK(cfg_parse_obj(pctx, fields[1].type,
&obj->value.tuple[1]));
CHECK(cfg_parse_obj(pctx, fields[2].type,
&obj->value.tuple[2]));
*ret = obj;
obj = NULL;
}

View file

@ -1860,6 +1860,28 @@ cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na) {
cfg_print_chars(pctx, isc_buffer_base(&buf), isc_buffer_usedlength(&buf));
}
isc_result_t
cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp) {
isc_result_t result;
CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER));
if (pctx->token.type != isc_tokentype_number) {
cfg_parser_error(pctx, CFG_LOG_NEAR,
"expected number");
return (ISC_R_UNEXPECTEDTOKEN);
}
if (pctx->token.value.as_ulong > 63) {
cfg_parser_error(pctx, CFG_LOG_NEAR,
"dscp out of range");
return (ISC_R_RANGE);
}
*dscp = (isc_dscp_t)(pctx->token.value.as_ulong);
return (ISC_R_SUCCESS);
cleanup:
return (result);
}
/* netaddr */
static unsigned int netaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK;
@ -2030,17 +2052,43 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type,
isc_result_t result;
isc_netaddr_t netaddr;
in_port_t port = 0;
isc_dscp_t dscp = -1;
cfg_obj_t *obj = NULL;
int have_port = 0, have_dscp = 0;
CHECK(cfg_create_obj(pctx, type, &obj));
CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr));
CHECK(cfg_peektoken(pctx, 0));
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "port") == 0) {
CHECK(cfg_gettoken(pctx, 0)); /* read "port" */
CHECK(cfg_parse_rawport(pctx, flags, &port));
for (;;) {
CHECK(cfg_peektoken(pctx, 0));
if (pctx->token.type == isc_tokentype_string) {
if (strcasecmp(TOKEN_STRING(pctx), "port") == 0) {
CHECK(cfg_gettoken(pctx, 0)); /* read "port" */
CHECK(cfg_parse_rawport(pctx, flags, &port));
++have_port;
} else if ((flags & CFG_ADDR_DSCPOK) != 0 &&
strcasecmp(TOKEN_STRING(pctx), "dscp") == 0)
{
CHECK(cfg_gettoken(pctx, 0)); /* read "dscp" */
CHECK(cfg_parse_dscp(pctx, &dscp));
++have_dscp;
} else
break;
} else
break;
}
if (have_port > 1) {
cfg_parser_error(pctx, 0, "expected at most one port");
result = ISC_R_UNEXPECTEDTOKEN;
goto cleanup;
}
if (have_dscp > 1) {
cfg_parser_error(pctx, 0, "expected at most one dscp");
result = ISC_R_UNEXPECTEDTOKEN;
goto cleanup;
}
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
obj->value.sockaddrdscp.dscp = dscp;
*ret = obj;
return (ISC_R_SUCCESS);
@ -2055,6 +2103,13 @@ cfg_type_t cfg_type_sockaddr = {
&cfg_rep_sockaddr, &sockaddr_flags
};
static unsigned int sockaddrdscp_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK |
CFG_ADDR_DSCPOK;
cfg_type_t cfg_type_sockaddrdscp = {
"sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr,
&cfg_rep_sockaddr, &sockaddrdscp_flags
};
isc_result_t
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
const unsigned int *flagp = type->of;
@ -2075,6 +2130,10 @@ cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) {
cfg_print_chars(pctx, " port ", 6);
cfg_print_rawuint(pctx, port);
}
if (obj->value.sockaddrdscp.dscp != -1) {
cfg_print_chars(pctx, " dscp ", 6);
cfg_print_rawuint(pctx, obj->value.sockaddrdscp.dscp);
}
}
void
@ -2105,6 +2164,9 @@ cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type) {
} else {
cfg_print_cstr(pctx, "[ port <integer> ]");
}
if ((*flagp & CFG_ADDR_DSCPOK) != 0) {
cfg_print_cstr(pctx, " [ dscp <integer> ]");
}
}
isc_boolean_t
@ -2119,6 +2181,12 @@ cfg_obj_assockaddr(const cfg_obj_t *obj) {
return (&obj->value.sockaddr);
}
isc_dscp_t
cfg_obj_getdscp(const cfg_obj_t *obj) {
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddr);
return (obj->value.sockaddrdscp.dscp);
}
isc_result_t
cfg_gettoken(cfg_parser_t *pctx, int options) {
isc_result_t result;

View file

@ -22,6 +22,7 @@ cfg_obj_asuint64
cfg_obj_attach
cfg_obj_destroy
cfg_obj_file
cfg_obj_getdscp
cfg_obj_isboolean
cfg_obj_islist
cfg_obj_ismap