+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
isc_netaddr_t netaddr;
int match;
unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE;
+ isc_dscp_t dispdscp = -1;
if (TCP_CLIENT(client)) {
socket = client->tcpsocket;
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");
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;
/* 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;
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;
client->tcpbuf = NULL;
client->opt = NULL;
client->udpsize = 512;
+ client->dscp = -1;
client->extflags = 0;
client->ednsversion = -1;
client->next = NULL;
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,
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\
}
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++) {
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");
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);
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);
}
*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
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) {
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);
*/
stack[pushed].element = cfg_list_next(element);
stack[pushed].port = port;
+ stack[pushed].dscp = dscp;
pushed++;
goto newlist;
}
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);
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))
pushed--;
element = stack[pushed].element;
port = stack[pushed].port;
+ dscp = stack[pushed].dscp;
goto resume;
}
if (i < addrcount) {
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) {
INSIST(keycount == addrcount);
*addrsp = addrs;
+ *dscpsp = dscps;
*keysp = keys;
*countp = addrcount;
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)
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;
}
isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *));
*addrsp = NULL;
+ if (dscpsp != NULL)
+ *dscpsp = NULL;
*keysp = NULL;
}
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,
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;
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,
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);
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 */
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);
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 */
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;
};
***/
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.
*/
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
ifp->ntcpcurrent = 0;
ifp->nudpdispatch = 0;
+ ifp->dscp = -1;
+
ISC_LINK_INIT(ifp, link);
ns_interfacemgr_attach(mgr, &ifp->mgr);
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,
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;
if (result != ISC_R_SUCCESS)
return (result);
+ ifp->dscp = dscp;
+
result = ns_interface_listenudp(ifp);
if (result != ISC_R_SUCCESS)
goto cleanup_interface;
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;
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,
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
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;
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,
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;
elt->mctx = mctx;
ISC_LINK_INIT(elt, link);
elt->port = port;
+ elt->dscp = dscp;
elt->acl = acl;
*target = elt;
return (ISC_R_SUCCESS);
}
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;
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;
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);
}
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);
#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];
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;
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);
* 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;
unsigned int attrs, attrmask;
const cfg_obj_t *obj = NULL;
unsigned int maxdispatchbuffers;
+ isc_dscp_t dscp = -1;
switch (af) {
case AF_INET:
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!
*/
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));
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));
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));
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));
*
* 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) {
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.
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.
}
}
+ /*
+ * 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");
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 "
}
}
- 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));
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);
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;
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);
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)
* 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;
}
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;
}
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.
*/
* 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,
* 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,
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);
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);
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;
dns_zonestat_level_t statlevel;
int seconds;
dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
+ isc_dscp_t dscp;
i = 0;
if (zconfig != NULL) {
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));
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;
(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);
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;
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;
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);
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);
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
datasize 104857600;
deallocate-on-exit yes;
directory ".";
+ dscp 41;
dump-file "named_dumpdb";
fake-iquery yes;
files 1000;
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;
serial-query-rate 100;
server-id none;
max-cache-size 20000000000000;
+ transfer-source 0.0.0.0 dscp 63;
zone-statistics none;
};
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;
--- /dev/null
+/*
+ * 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";
+};
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
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
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; };
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; };
--- /dev/null
+rm -f */root.bk
+rm -f dig.out.10.53.0.?
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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";
+};
--- /dev/null
+$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
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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; };
+};
--- /dev/null
+$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
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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";
+};
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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";
+};
--- /dev/null
+$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
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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; };
+};
--- /dev/null
+$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
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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";
+};
--- /dev/null
+-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T dscp=46
--- /dev/null
+/*
+ * 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; };
+};
--- /dev/null
+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
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";
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; };
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; };
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; };
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; };
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; };
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; };
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; };
</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>
</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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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> 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>
<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>
<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>
<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>
<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>
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>
};
--- /dev/null
+
+ 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.
};
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>;
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>;
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 );
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>;
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
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 );
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 );
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>;
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>;
};
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 );
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> {
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>
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 );
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>;
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>;
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>;
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
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 );
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)
result = ISC_R_FAILURE;
}
+ tresult = check_dscp(options, logctx);
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+
return (result);
}
ai->srtt = entry->srtt;
ai->flags = entry->flags;
ai->entry = entry;
+ ai->dscp = -1;
ISC_LINK_INIT(ai, publink);
return (ai);
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;
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)
*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) {
return (result);
}
+isc_result_t
+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;
+ dns_forwarder_t *fwd, *nfwd;
+
+ 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 (fwd = ISC_LIST_HEAD(*fwdrs);
+ fwd != NULL;
+ fwd = ISC_LIST_NEXT(fwd, link))
+ {
+ nfwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
+ if (nfwd == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ *nfwd = *fwd;
+ ISC_LINK_INIT(nfwd, link);
+ ISC_LIST_APPEND(forwarders->fwdrs, nfwd, 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(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;
- isc_sockaddr_t *sa, *nsa;
+ dns_forwarder_t *fwd;
+ isc_sockaddr_t *sa;
REQUIRE(VALID_FWDTABLE(fwdtable));
if (forwarders == NULL)
return (ISC_R_NOMEMORY);
- ISC_LIST_INIT(forwarders->addrs);
+ ISC_LIST_INIT(forwarders->fwdrs);
for (sa = ISC_LIST_HEAD(*addrs);
sa != NULL;
sa = ISC_LIST_NEXT(sa, link))
{
- nsa = isc_mem_get(fwdtable->mctx, sizeof(isc_sockaddr_t));
- if (nsa == NULL) {
+ fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
+ if (fwd == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
- *nsa = *sa;
- ISC_LINK_INIT(nsa, link);
- ISC_LIST_APPEND(forwarders->addrs, nsa, link);
+ fwd->addr = *sa;
+ fwd->dscp = -1;
+ ISC_LINK_INIT(fwd, link);
+ ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
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(dns_forwarder_t));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
return (result);
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));
}
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;
*\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 */
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;
};
*/
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
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 */
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 */
*\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,
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,
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,
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.
*
*\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,
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,
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,
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.
*
* \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 */
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;
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
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'.
*\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
*\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);
/*%<
*\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);
/*%<
*\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);
/*%<
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);
+}
isc_boolean_t canceling; /* ctlevent outstanding */
isc_sockaddr_t destaddr;
unsigned int udpcount;
+ isc_dscp_t dscp;
};
#define DNS_REQUEST_F_CONNECTING 0x0001
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);
* 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);
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);
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;
if (result != ISC_R_SUCCESS)
goto cleanup;
#endif
+
attrs = 0;
attrs |= DNS_DISPATCHATTR_TCP;
attrs |= DNS_DISPATCHATTR_PRIVATE;
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,
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);
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));
}
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));
}
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;
udptimeout = 1;
}
request->udpcount = udpretries;
+ request->dscp = dscp;
/*
* Create timer now. We will set it below once.
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;
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));
}
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));
}
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));
}
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;
udptimeout = 1;
}
request->udpcount = udpretries;
+ request->dscp = dscp;
/*
* Create timer now. We will set it below once.
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;
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;
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;
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;
isc_sockaddr_t addr;
isc_boolean_t have_addr = ISC_FALSE;
unsigned int srtt;
+ isc_dscp_t dscp = -1;
FCTXTRACE("query");
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.
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;
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;
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,
if (result != ISC_R_SUCCESS)
goto cleanup_socket;
#endif
-
/*
* A dispatch will be created once the connect succeeds.
*/
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;
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
*
* 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);
* 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) {
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;
* 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;
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)) {
}
}
- 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);
else
ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
}
- sa = ISC_LIST_NEXT(sa, link);
+ fwd = ISC_LIST_NEXT(fwd, link);
}
/*
}
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;
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);
+}
+
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
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
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
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
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
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
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
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
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
* may differ due to IXFR->AXFR fallback.
*/
dns_rdatatype_t reqtype;
+ isc_dscp_t dscp;
isc_sockaddr_t masteraddr;
isc_sockaddr_t sourceaddr;
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);
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));
}
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;
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));
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)
{
xfr->checkid = ISC_TRUE;
xfr->id = (isc_uint16_t)(tmp & 0xffff);
xfr->reqtype = reqtype;
+ xfr->dscp = dscp;
/* sockaddr */
xfr->socket = NULL;
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++;
isc_uint32_t minretry;
isc_sockaddr_t *masters;
+ isc_dscp_t *masterdscps;
dns_name_t **masterkeynames;
isc_boolean_t *mastersok;
unsigned int masterscnt;
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;
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 */
dns_name_t ns;
isc_sockaddr_t dst;
dns_tsigkey_t *key;
+ isc_dscp_t dscp;
ISC_LINK(dns_notify_t) link;
};
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;
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;
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));
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)
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)
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));
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));
}
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++) {
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));
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);
}
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));
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;
/*
* 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;
* Everything is ok so attach to the zone.
*/
zone->notify = newaddrs;
+ zone->notifydscp = newdscps;
zone->notifykeynames = newnames;
zone->notifycnt = count;
unlock:
{
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;
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
/*
* 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;
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);
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));
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(¬ify->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;
timeout = 15;
if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
timeout = 30;
- result = dns_request_createvia2(notify->zone->view->requestmgr,
- message, &src, ¬ify->dst, 0, key,
- timeout * 3, timeout,
+ result = dns_request_createvia4(notify->zone->view->requestmgr,
+ message, &src, ¬ify->dst, dscp,
+ 0, key, timeout * 3, timeout, 0,
notify->zone->task, notify_done,
notify, ¬ify->request);
if (result == ISC_R_SUCCESS) {
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));
}
}
- have_xfrsource = ISC_FALSE;
+ have_xfrsource = have_xfrdscp = ISC_FALSE;
reqnsid = zone->view->requestnsid;
if (zone->view->peers != NULL) {
dns_peer_t *peer = NULL;
&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);
&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)) {
&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;
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,
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));
&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);
*/
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;
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",
isc_sockaddr_t masteraddr;
isc_time_t now;
const char *soa_before = "";
+ isc_dscp_t dscp = -1;
UNUSED(task);
* 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.
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) {
sendtomaster(dns_forward_t *forward) {
isc_result_t result;
isc_sockaddr_t src;
+ isc_dscp_t dscp = -1;
LOCK_ZONE(forward->zone);
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);
#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
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;
* _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 */
#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)
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;
/*%
*/
/*@}*/
+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);
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 */
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));
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@
CHECK(isc_socketmgr_create(mctx, &socketmgr));
return (ISC_R_SUCCESS);
- cleanup:
+ cleanup:
cleanup_managers();
return (result);
}
#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
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);
}
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
*/
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());
}
-
* 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);
/*%<
#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
#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) {
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
#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.
isc_sockfdwatch_t fdwatchcb;
int fdwatchflags;
isc_task_t *fdwatchtask;
+ int dscp;
};
#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g')
#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.
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
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
isc__socket_ipv6only,
isc__socket_fdwatchpoke,
isc__socket_dup,
- isc__socket_getfd
+ isc__socket_getfd,
+ isc__socket_dscp
}
#ifndef BIND9
,
}
#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);
}
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));
#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,
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;
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;
}
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)
ev->attributes = 0;
ev->destroy = ev->ev_destroy;
ev->ev_destroy = destroy_socketevent;
+ ev->dscp = 0;
return (ev);
}
* 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
sock->manager = manager;
sock->type = type;
sock->fd = -1;
+ sock->dscp = -1;
sock->dupped = 0;
sock->statsindex = NULL;
#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) {
*/
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) {
}
#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:
*/
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
*/
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);
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);
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);
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);
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));
}
#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.
* 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);
/*
isc__socket_sendtov
isc__socket_sendv
isc__socket_setname
+isc__socket_socketevent
isc__socketmgr_create
isc__socketmgr_create2
isc__socketmgr_destroy
isc_net_ntop
isc_net_probe_ipv6only
isc_net_probe_ipv6pktinfo
+isc_net_probedscp
isc_net_probeipv4
isc_net_probeipv6
isc_net_probeunix
isc_sockaddr_setport
isc_sockaddr_totext
isc_sockaddr_v6fromin
+isc_socket_dscp
isc_socketmgr_renderxml
isc_stats_attach
isc_stats_create
if (ipv6_result == ISC_R_DISABLED)
ipv6_result = ISC_R_SUCCESS;
}
+
+unsigned int
+isc_net_probedscp() {
+ return (0);
+}
}
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)
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);
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);
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);
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);
#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);
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 *
* 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);
/*%<
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 */
#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)
/*@}*/
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;
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);
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;
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;
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 */
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 }
};
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 }
};
*/
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 = {
};
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 };
};
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 };
{ "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 },
}
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));
}
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)
else
INSIST(0);
- port = 0;
-
for (;;) {
CHECK(cfg_peektoken(pctx, 0));
if (pctx->token.type == isc_tokentype_string) {
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
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);
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,
&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
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
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);
}
&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;
}
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;
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);
&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;
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
} else {
cfg_print_cstr(pctx, "[ port <integer> ]");
}
+ if ((*flagp & CFG_ADDR_DSCPOK) != 0) {
+ cfg_print_cstr(pctx, " [ dscp <integer> ]");
+ }
}
isc_boolean_t
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;
cfg_obj_attach
cfg_obj_destroy
cfg_obj_file
+cfg_obj_getdscp
cfg_obj_isboolean
cfg_obj_islist
cfg_obj_ismap