Compare commits
74
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
578a98e6e6 | ||
|
|
bafc47bef5 | ||
|
|
cdf097ea32 | ||
|
|
ef5cc6f9d6 | ||
|
|
d00d2dddb3 | ||
|
|
3fabca3fe8 | ||
|
|
7089e9cca4 | ||
|
|
c4780de0d4 | ||
|
|
9ec889940d | ||
|
|
08a2d2d37a | ||
|
|
97b9d76f52 | ||
|
|
ea54888e2e | ||
|
|
ce6f33ed0b | ||
|
|
901794f009 | ||
|
|
e478ec16f9 | ||
|
|
d15ba6eaba | ||
|
|
cde60b3085 | ||
|
|
4256a29ea9 | ||
|
|
4b8bdca210 | ||
|
|
1f0cffd16f | ||
|
|
fd36cafe5a | ||
|
|
5b3798661a | ||
|
|
deae248984 | ||
|
|
74fc261ee3 | ||
|
|
6cc85c208f | ||
|
|
3ebc29b82b | ||
|
|
757b9a5351 | ||
|
|
586ab26d51 | ||
|
|
5418603967 | ||
|
|
8ece19f681 | ||
|
|
de667d3c08 | ||
|
|
8e45de0f6f | ||
|
|
dec92aeab6 | ||
|
|
8ddc2b0225 | ||
|
|
7f423f0175 | ||
|
|
dccbc4086e | ||
|
|
d5a3200b3d | ||
|
|
70f46a537a | ||
|
|
5f269f9572 | ||
|
|
30708dff65 | ||
|
|
ff3f537167 | ||
|
|
6b70909322 | ||
|
|
4bbd2bb511 | ||
|
|
e3c37cef51 | ||
|
|
9925d4e1ad | ||
|
|
94c6914e72 | ||
|
|
ccc614d702 | ||
|
|
1eadb37cf3 | ||
|
|
5d2639df6d | ||
|
|
154f411370 | ||
|
|
7d94e47c26 | ||
|
|
ebe69ba220 | ||
|
|
52174dc8bc | ||
|
|
6a172b3621 | ||
|
|
9da63b9874 | ||
|
|
7b30e010b7 | ||
|
|
d375baa081 | ||
|
|
5b699987eb | ||
|
|
1802f71ed1 | ||
|
|
5343db271d | ||
|
|
8e31665541 | ||
|
|
d95e2af91c | ||
|
|
2dc79549a4 | ||
|
|
5c34e1006d | ||
|
|
4aae4ac05f | ||
|
|
1911a71fd5 | ||
|
|
3d58be4c15 | ||
|
|
a4ec819b3f | ||
|
|
2f1f4f49b7 | ||
|
|
0fa04a2f0a | ||
|
|
7db8344162 | ||
|
|
6cf6ef336b | ||
|
|
8b023a3d0e | ||
|
|
52d63eeafc |
@@ -1,3 +1,44 @@
|
||||
5090. [func] Use multiple event loops in socket code, and
|
||||
make network threads CPU-affinitive. This
|
||||
significantly improves performance on large
|
||||
systems. [GL #666]
|
||||
|
||||
5082. [bug] Fixed a race that could cause a crash in
|
||||
dig/host/nslookup. [GL #650]
|
||||
|
||||
5081. [func] Use per-worker queues in task manager, make task
|
||||
runners CPU-affine. [GL #659]
|
||||
|
||||
5080. [func] Improvements to "rndc nta" user interface:
|
||||
- catch and report invalid command line options
|
||||
- when removing an NTA from all views, do not
|
||||
abort with an error if the NTA was not found
|
||||
in one of the views
|
||||
- include the view name in "rndc nta -dump"
|
||||
output, for consistency with the add and remove
|
||||
actions
|
||||
Thanks to Tony Finch. [GL !816]
|
||||
|
||||
5079. [func] Disable IDN processing in dig and nslookup
|
||||
when not on a tty. [GL #653]
|
||||
|
||||
5078. [cleanup] Require python components to be explicitly disabled if
|
||||
python is not available on unix platforms. [GL #601]
|
||||
|
||||
5077. [cleanup] Remove ip6.int support (-i) from dig and mdig.
|
||||
[GL !969]
|
||||
|
||||
5076. [bug] "require-server-cookie" was not effective if
|
||||
"rate-limit" was configured. [GL #617]
|
||||
|
||||
5075. [bug] Refresh nameservers from cache when sending final
|
||||
query in qname minimization. [GL #16]
|
||||
|
||||
5074. [cleanup] Remove vector socket functions - isc_socket_recvv(),
|
||||
isc_socket_sendtov(), isc_socket_sendtov2(),
|
||||
isc_socket_sendv() - in order to simplify socket code.
|
||||
[GL #645]
|
||||
|
||||
5073. [bug] Destroy a task first when destroying rpzs and catzs.
|
||||
[GL #84]
|
||||
|
||||
|
||||
+7
-7
@@ -65,7 +65,7 @@ static char domainopt[DNS_NAME_MAXTEXT];
|
||||
static char hexcookie[81];
|
||||
|
||||
static bool short_form = false, printcmd = true,
|
||||
ip6_int = false, plusquest = false, pluscomm = false,
|
||||
plusquest = false, pluscomm = false,
|
||||
ipv4only = false, ipv6only = false;
|
||||
static uint32_t splitwidth = 0xffffffff;
|
||||
|
||||
@@ -153,7 +153,6 @@ help(void) {
|
||||
" -b address[#port] (bind to source address/port)\n"
|
||||
" -c class (specify query class)\n"
|
||||
" -f filename (batch mode)\n"
|
||||
" -i (use IP6.INT for IPv6 reverse lookups)\n"
|
||||
" -k keyfile (specify tsig key file)\n"
|
||||
" -m (enable memory usage debugging)\n"
|
||||
" -p port (specify port number)\n"
|
||||
@@ -193,8 +192,10 @@ help(void) {
|
||||
" +[no]fail (Don't try next server on SERVFAIL)\n"
|
||||
" +[no]header-only (Send query without a question section)\n"
|
||||
" +[no]identify (ID responders in short answers)\n"
|
||||
" +[no]idnin (Parse IDN names)\n"
|
||||
" +[no]idnout (Convert IDN response)\n"
|
||||
#ifdef HAVE_LIBIDN2
|
||||
" +[no]idnin (Parse IDN names [default=on on tty])\n"
|
||||
" +[no]idnout (Convert IDN response [default=on on tty])\n"
|
||||
#endif
|
||||
" +[no]ignore (Don't revert to TCP for TC responses.)\n"
|
||||
" +[no]keepalive (Request EDNS TCP keepalive)\n"
|
||||
" +[no]keepopen (Keep the TCP socket open between queries)\n"
|
||||
@@ -1606,7 +1607,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
|
||||
exit(0);
|
||||
break;
|
||||
case 'i':
|
||||
ip6_int = true;
|
||||
/* deprecated */
|
||||
break;
|
||||
case 'm': /* memdebug */
|
||||
/* memdebug is handled in preparse_args() */
|
||||
@@ -1787,13 +1788,12 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
|
||||
*lookup = clone_lookup(default_lookup, true);
|
||||
*need_clone = true;
|
||||
if (get_reverse(textname, sizeof(textname), value,
|
||||
ip6_int, false) == ISC_R_SUCCESS) {
|
||||
false) == ISC_R_SUCCESS) {
|
||||
strlcpy((*lookup)->textname, textname,
|
||||
sizeof((*lookup)->textname));
|
||||
debug("looking up %s", (*lookup)->textname);
|
||||
(*lookup)->trace_root = ((*lookup)->trace ||
|
||||
(*lookup)->ns_search_only);
|
||||
(*lookup)->ip6_int = ip6_int;
|
||||
if (!(*lookup)->rdtypeset)
|
||||
(*lookup)->rdtype = dns_rdatatype_ptr;
|
||||
if (!(*lookup)->rdclassset)
|
||||
|
||||
+15
-15
@@ -271,17 +271,6 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do reverse IPv6 lookups using the obsolete RFC 1886 IP6.INT
|
||||
domain, which is no longer in use. Obsolete bit string
|
||||
label queries (RFC 2874) are not attempted.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">keyfile</replaceable></term>
|
||||
<listitem>
|
||||
@@ -394,8 +383,7 @@
|
||||
<literal>94.2.0.192.in-addr.arpa</literal> and sets the
|
||||
query type and class to PTR and IN respectively. IPv6
|
||||
addresses are looked up using nibble format under the
|
||||
IP6.ARPA domain (but see also the <option>-i</option>
|
||||
option).
|
||||
IP6.ARPA domain.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -789,7 +777,13 @@
|
||||
<para>
|
||||
Process [do not process] IDN domain names on input.
|
||||
This requires IDN SUPPORT to have been enabled at
|
||||
compile time. The default is to process IDN input.
|
||||
compile time.
|
||||
</para>
|
||||
<para>
|
||||
The default is to process IDN input when standard output
|
||||
is a tty. The IDN processing on input is disabled when
|
||||
dig output is redirected to files, pipes, and other
|
||||
non-tty file descriptors.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -800,7 +794,13 @@
|
||||
<para>
|
||||
Convert [do not convert] puny code on output.
|
||||
This requires IDN SUPPORT to have been enabled at
|
||||
compile time. The default is to convert output.
|
||||
compile time.
|
||||
</para>
|
||||
<para>
|
||||
The default is to process puny code on output when
|
||||
standard output is a tty. The puny code processing on
|
||||
output is disabled when dig output is redirected to
|
||||
files, pipes, and other non-tty file descriptors.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
+106
-116
@@ -312,8 +312,7 @@ reverse_octets(const char *in, char **p, char *end) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
get_reverse(char *reverse, size_t len, char *value, bool ip6_int,
|
||||
bool strict)
|
||||
get_reverse(char *reverse, size_t len, char *value, bool strict)
|
||||
{
|
||||
int r;
|
||||
isc_result_t result;
|
||||
@@ -327,8 +326,6 @@ get_reverse(char *reverse, size_t len, char *value, bool ip6_int,
|
||||
dns_name_t *name;
|
||||
unsigned int options = 0;
|
||||
|
||||
if (ip6_int)
|
||||
options |= DNS_BYADDROPT_IPV6INT;
|
||||
name = dns_fixedname_initname(&fname);
|
||||
result = dns_byaddr_createptrname(&addr, options, name);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -628,7 +625,7 @@ make_empty_lookup(void) {
|
||||
looknew->ttlunits = false;
|
||||
looknew->qr = false;
|
||||
#ifdef HAVE_LIBIDN2
|
||||
looknew->idnin = (getenv("IDN_DISABLE") == NULL);
|
||||
looknew->idnin = isatty(1)?(getenv("IDN_DISABLE") == NULL):false;
|
||||
looknew->idnout = looknew->idnin;
|
||||
#else
|
||||
looknew->idnin = false;
|
||||
@@ -652,7 +649,6 @@ make_empty_lookup(void) {
|
||||
looknew->nsfound = 0;
|
||||
looknew->tcp_mode = false;
|
||||
looknew->tcp_mode_set = false;
|
||||
looknew->ip6_int = false;
|
||||
looknew->comments = true;
|
||||
looknew->stats = true;
|
||||
looknew->section_question = true;
|
||||
@@ -1523,23 +1519,21 @@ clear_query(dig_query_t *query) {
|
||||
|
||||
debug("clear_query(%p)", query);
|
||||
|
||||
if (query->timer != NULL)
|
||||
if (query->timer != NULL) {
|
||||
isc_timer_detach(&query->timer);
|
||||
}
|
||||
lookup = query->lookup;
|
||||
|
||||
if (lookup->current_query == query)
|
||||
if (lookup->current_query == query) {
|
||||
lookup->current_query = NULL;
|
||||
}
|
||||
|
||||
if (ISC_LINK_LINKED(query, link))
|
||||
if (ISC_LINK_LINKED(query, link)) {
|
||||
ISC_LIST_UNLINK(lookup->q, query, link);
|
||||
if (ISC_LINK_LINKED(query, clink))
|
||||
}
|
||||
if (ISC_LINK_LINKED(query, clink)) {
|
||||
ISC_LIST_UNLINK(lookup->connecting, query, clink);
|
||||
if (ISC_LINK_LINKED(&query->recvbuf, link))
|
||||
ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
|
||||
link);
|
||||
if (ISC_LINK_LINKED(&query->lengthbuf, link))
|
||||
ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf,
|
||||
link);
|
||||
}
|
||||
INSIST(query->recvspace != NULL);
|
||||
|
||||
if (query->sock != NULL) {
|
||||
@@ -1548,12 +1542,16 @@ clear_query(dig_query_t *query) {
|
||||
debug("sockcount=%d", sockcount);
|
||||
}
|
||||
isc_mempool_put(commctx, query->recvspace);
|
||||
isc_mempool_put(commctx, query->tmpsendspace);
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_invalidate(&query->lengthbuf);
|
||||
if (query->waiting_senddone)
|
||||
|
||||
if (query->waiting_senddone) {
|
||||
query->pending_free = true;
|
||||
else
|
||||
} else {
|
||||
query->magic = 0;
|
||||
isc_mem_free(mctx, query);
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
@@ -2461,13 +2459,14 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
|
||||
for (serv = ISC_LIST_HEAD(lookup->my_server_list);
|
||||
serv != NULL;
|
||||
serv = ISC_LIST_NEXT(serv, link)) {
|
||||
serv = ISC_LIST_NEXT(serv, link))
|
||||
{
|
||||
query = isc_mem_allocate(mctx, sizeof(dig_query_t));
|
||||
if (query == NULL)
|
||||
if (query == NULL) {
|
||||
fatal("memory allocation failure in %s:%d",
|
||||
__FILE__, __LINE__);
|
||||
debug("create query %p linked to lookup %p",
|
||||
query, lookup);
|
||||
}
|
||||
debug("create query %p linked to lookup %p", query, lookup);
|
||||
query->lookup = lookup;
|
||||
query->timer = NULL;
|
||||
query->waiting_connect = false;
|
||||
@@ -2488,20 +2487,24 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
query->msg_count = 0;
|
||||
query->byte_count = 0;
|
||||
query->ixfr_axfr = false;
|
||||
ISC_LIST_INIT(query->recvlist);
|
||||
ISC_LIST_INIT(query->lengthlist);
|
||||
query->sock = NULL;
|
||||
query->recvspace = isc_mempool_get(commctx);
|
||||
if (query->recvspace == NULL)
|
||||
query->tmpsendspace = isc_mempool_get(commctx);
|
||||
if (query->recvspace == NULL) {
|
||||
fatal("memory allocation failure");
|
||||
}
|
||||
|
||||
isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
|
||||
isc_buffer_init(&query->lengthbuf, query->lengthspace, 2);
|
||||
isc_buffer_init(&query->slbuf, query->slspace, 2);
|
||||
isc_buffer_init(&query->tmpsendbuf, query->tmpsendspace,
|
||||
COMMSIZE);
|
||||
query->sendbuf = lookup->renderbuf;
|
||||
|
||||
ISC_LINK_INIT(query, clink);
|
||||
ISC_LINK_INIT(query, link);
|
||||
|
||||
query->magic = DIG_QUERY_MAGIC;
|
||||
|
||||
ISC_LIST_ENQUEUE(lookup->q, query, link);
|
||||
}
|
||||
|
||||
@@ -2510,9 +2513,10 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
extrabytes = 0;
|
||||
dighost_printmessage(ISC_LIST_HEAD(lookup->q),
|
||||
lookup->sendmsg, true);
|
||||
if (lookup->stats)
|
||||
if (lookup->stats) {
|
||||
printf(";; QUERY SIZE: %u\n\n",
|
||||
isc_buffer_usedlength(&lookup->renderbuf));
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
@@ -2523,8 +2527,6 @@ setup_lookup(dig_lookup_t *lookup) {
|
||||
*/
|
||||
static void
|
||||
send_done(isc_task_t *_task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
||||
isc_buffer_t *b = NULL;
|
||||
dig_query_t *query, *next;
|
||||
dig_lookup_t *l;
|
||||
|
||||
@@ -2539,28 +2541,27 @@ send_done(isc_task_t *_task, isc_event_t *event) {
|
||||
debug("sendcount=%d", sendcount);
|
||||
INSIST(sendcount >= 0);
|
||||
|
||||
for (b = ISC_LIST_HEAD(sevent->bufferlist);
|
||||
b != NULL;
|
||||
b = ISC_LIST_HEAD(sevent->bufferlist)) {
|
||||
ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
|
||||
isc_mem_free(mctx, b);
|
||||
}
|
||||
|
||||
query = event->ev_arg;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
query->waiting_senddone = false;
|
||||
l = query->lookup;
|
||||
|
||||
if (l->ns_search_only && !l->trace_root && !l->tcp_mode) {
|
||||
if (!query->pending_free && l->ns_search_only &&
|
||||
!l->trace_root && !l->tcp_mode)
|
||||
{
|
||||
debug("sending next, since searching");
|
||||
next = ISC_LIST_NEXT(query, link);
|
||||
if (next != NULL)
|
||||
if (next != NULL) {
|
||||
send_udp(next);
|
||||
}
|
||||
}
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
if (query->pending_free)
|
||||
if (query->pending_free) {
|
||||
query->magic = 0;
|
||||
isc_mem_free(mctx, query);
|
||||
}
|
||||
|
||||
check_if_done();
|
||||
UNLOCK_LOOKUP;
|
||||
@@ -2578,6 +2579,7 @@ cancel_lookup(dig_lookup_t *lookup) {
|
||||
debug("cancel_lookup()");
|
||||
query = ISC_LIST_HEAD(lookup->q);
|
||||
while (query != NULL) {
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
next = ISC_LIST_NEXT(query, link);
|
||||
if (query->sock != NULL) {
|
||||
isc_socket_cancel(query->sock, global_task,
|
||||
@@ -2597,6 +2599,7 @@ bringup_timer(dig_query_t *query, unsigned int default_timeout) {
|
||||
dig_lookup_t *l;
|
||||
unsigned int local_timeout;
|
||||
isc_result_t result;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
debug("bringup_timer()");
|
||||
/*
|
||||
@@ -2661,6 +2664,7 @@ send_tcp_connect(dig_query_t *query) {
|
||||
isc_result_t result;
|
||||
dig_query_t *next;
|
||||
dig_lookup_t *l;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
debug("send_tcp_connect(%p)", query);
|
||||
|
||||
@@ -2777,17 +2781,6 @@ send_tcp_connect(dig_query_t *query) {
|
||||
}
|
||||
}
|
||||
|
||||
static isc_buffer_t *
|
||||
clone_buffer(isc_buffer_t *source) {
|
||||
isc_buffer_t *buffer;
|
||||
buffer = isc_mem_allocate(mctx, sizeof(*buffer));
|
||||
if (buffer == NULL)
|
||||
fatal("memory allocation failure in %s:%d",
|
||||
__FILE__, __LINE__);
|
||||
*buffer = *source;
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Send a UDP packet to the remote nameserver, possible starting the
|
||||
* recv action as well. Also make sure that the timer is running and
|
||||
@@ -2797,8 +2790,10 @@ static void
|
||||
send_udp(dig_query_t *query) {
|
||||
dig_lookup_t *l = NULL;
|
||||
isc_result_t result;
|
||||
isc_buffer_t *sendbuf;
|
||||
dig_query_t *next;
|
||||
isc_region_t r;
|
||||
isc_socketevent_t *sevent;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
debug("send_udp(%p)", query);
|
||||
|
||||
@@ -2859,29 +2854,27 @@ send_udp(dig_query_t *query) {
|
||||
check_result(result, "isc_socket_bind");
|
||||
|
||||
query->recv_made = true;
|
||||
ISC_LINK_INIT(&query->recvbuf, link);
|
||||
ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf,
|
||||
link);
|
||||
isc_buffer_availableregion(&query->recvbuf, &r);
|
||||
debug("recving with lookup=%p, query=%p, sock=%p",
|
||||
query->lookup, query, query->sock);
|
||||
result = isc_socket_recvv(query->sock, &query->recvlist, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
result = isc_socket_recv(query->sock, &r, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
debug("recvcount=%d", recvcount);
|
||||
}
|
||||
ISC_LIST_INIT(query->sendlist);
|
||||
sendbuf = clone_buffer(&query->sendbuf);
|
||||
ISC_LIST_ENQUEUE(query->sendlist, sendbuf, link);
|
||||
isc_buffer_usedregion(&query->sendbuf, &r);
|
||||
debug("sending a request");
|
||||
TIME_NOW(&query->time_sent);
|
||||
INSIST(query->sock != NULL);
|
||||
query->waiting_senddone = true;
|
||||
result = isc_socket_sendtov2(query->sock, &query->sendlist,
|
||||
global_task, send_done, query,
|
||||
&query->sockaddr, NULL,
|
||||
ISC_SOCKFLAG_NORETRY);
|
||||
check_result(result, "isc_socket_sendtov");
|
||||
sevent = isc_socket_socketevent(mctx, query->sock,
|
||||
ISC_SOCKEVENT_SENDDONE,
|
||||
send_done, query);
|
||||
result = isc_socket_sendto2(query->sock, &r,
|
||||
global_task, &query->sockaddr, NULL,
|
||||
sevent, ISC_SOCKFLAG_NORETRY);
|
||||
check_result(result, "isc_socket_sendto2");
|
||||
sendcount++;
|
||||
}
|
||||
|
||||
@@ -2902,6 +2895,7 @@ connect_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
LOCK_LOOKUP;
|
||||
query = event->ev_arg;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
l = query->lookup;
|
||||
isc_event_free(&event);
|
||||
|
||||
@@ -2971,7 +2965,8 @@ connect_timeout(isc_task_t *task, isc_event_t *event) {
|
||||
static void
|
||||
tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent;
|
||||
isc_buffer_t *b = NULL;
|
||||
isc_buffer_t b;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
dig_query_t *query = NULL;
|
||||
dig_lookup_t *l, *n;
|
||||
@@ -2987,14 +2982,11 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
LOCK_LOOKUP;
|
||||
sevent = (isc_socketevent_t *)event;
|
||||
query = event->ev_arg;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
recvcount--;
|
||||
INSIST(recvcount >= 0);
|
||||
|
||||
b = ISC_LIST_HEAD(sevent->bufferlist);
|
||||
INSIST(b == &query->lengthbuf);
|
||||
ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
|
||||
|
||||
if (sevent->result == ISC_R_CANCELED) {
|
||||
isc_event_free(&event);
|
||||
l = query->lookup;
|
||||
@@ -3027,7 +3019,10 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
UNLOCK_LOOKUP;
|
||||
return;
|
||||
}
|
||||
length = isc_buffer_getuint16(b);
|
||||
isc_buffer_init(&b, sevent->region.base, sevent->n);
|
||||
isc_buffer_add(&b, sevent->n);
|
||||
length = isc_buffer_getuint16(&b);
|
||||
|
||||
if (length == 0) {
|
||||
isc_event_free(&event);
|
||||
launch_next_query(query, false);
|
||||
@@ -3041,13 +3036,11 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_init(&query->recvbuf, query->recvspace, length);
|
||||
ENSURE(ISC_LIST_EMPTY(query->recvlist));
|
||||
ISC_LINK_INIT(&query->recvbuf, link);
|
||||
ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
|
||||
isc_buffer_availableregion(&query->recvbuf, &r);
|
||||
debug("recving with lookup=%p, query=%p", query->lookup, query);
|
||||
result = isc_socket_recvv(query->sock, &query->recvlist, length, task,
|
||||
recv_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
result = isc_socket_recv(query->sock, &r, length, task,
|
||||
recv_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
debug("resubmitted recv request with length %d, recvcount=%d",
|
||||
length, recvcount);
|
||||
@@ -3063,7 +3056,8 @@ static void
|
||||
launch_next_query(dig_query_t *query, bool include_question) {
|
||||
isc_result_t result;
|
||||
dig_lookup_t *l;
|
||||
isc_buffer_t *buffer;
|
||||
isc_region_t r;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
INSIST(!free_now);
|
||||
|
||||
@@ -3082,35 +3076,28 @@ launch_next_query(dig_query_t *query, bool include_question) {
|
||||
return;
|
||||
}
|
||||
|
||||
isc_buffer_clear(&query->slbuf);
|
||||
isc_buffer_clear(&query->lengthbuf);
|
||||
isc_buffer_putuint16(&query->slbuf, (uint16_t) query->sendbuf.used);
|
||||
ISC_LIST_INIT(query->sendlist);
|
||||
ISC_LINK_INIT(&query->slbuf, link);
|
||||
if (!query->first_soa_rcvd) {
|
||||
buffer = clone_buffer(&query->slbuf);
|
||||
ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
|
||||
if (include_question) {
|
||||
buffer = clone_buffer(&query->sendbuf);
|
||||
ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
|
||||
}
|
||||
}
|
||||
|
||||
ISC_LINK_INIT(&query->lengthbuf, link);
|
||||
ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
|
||||
|
||||
result = isc_socket_recvv(query->sock, &query->lengthlist, 0,
|
||||
global_task, tcp_length_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
isc_buffer_availableregion(&query->lengthbuf, &r);
|
||||
result = isc_socket_recv(query->sock, &r, 0,
|
||||
global_task, tcp_length_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
debug("recvcount=%d", recvcount);
|
||||
if (!query->first_soa_rcvd) {
|
||||
debug("sending a request in launch_next_query");
|
||||
TIME_NOW(&query->time_sent);
|
||||
query->waiting_senddone = true;
|
||||
result = isc_socket_sendv(query->sock, &query->sendlist,
|
||||
global_task, send_done, query);
|
||||
check_result(result, "isc_socket_sendv");
|
||||
isc_buffer_clear(&query->tmpsendbuf);
|
||||
isc_buffer_putuint16(&query->tmpsendbuf,
|
||||
isc_buffer_usedlength(&query->sendbuf));
|
||||
if (include_question) {
|
||||
isc_buffer_usedregion(&query->sendbuf, &r);
|
||||
isc_buffer_copyregion(&query->tmpsendbuf, &r);
|
||||
}
|
||||
isc_buffer_usedregion(&query->tmpsendbuf, &r);
|
||||
result = isc_socket_send(query->sock, &r,
|
||||
global_task, send_done, query);
|
||||
check_result(result, "isc_socket_send");
|
||||
sendcount++;
|
||||
debug("sendcount=%d", sendcount);
|
||||
}
|
||||
@@ -3143,6 +3130,7 @@ connect_done(isc_task_t *task, isc_event_t *event) {
|
||||
LOCK_LOOKUP;
|
||||
sevent = (isc_socketevent_t *)event;
|
||||
query = sevent->ev_arg;
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
INSIST(query->waiting_connect);
|
||||
|
||||
@@ -3460,8 +3448,9 @@ ednsvers(dns_rdataset_t *opt) {
|
||||
static void
|
||||
recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent = NULL;
|
||||
isc_region_t r;
|
||||
dig_query_t *query = NULL;
|
||||
isc_buffer_t *b = NULL;
|
||||
isc_buffer_t b;
|
||||
dns_message_t *msg = NULL;
|
||||
isc_result_t result;
|
||||
dig_lookup_t *n, *l;
|
||||
@@ -3491,9 +3480,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
|
||||
sevent = (isc_socketevent_t *)event;
|
||||
|
||||
b = ISC_LIST_HEAD(sevent->bufferlist);
|
||||
INSIST(b == &query->recvbuf);
|
||||
ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link);
|
||||
isc_buffer_init(&b, sevent->region.base, sevent->n);
|
||||
isc_buffer_add(&b, sevent->n);
|
||||
|
||||
if ((l->tcp_mode) && (query->timer != NULL))
|
||||
isc_timer_touch(query->timer);
|
||||
@@ -3569,7 +3557,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
result = dns_message_peekheader(b, &id, &msgflags);
|
||||
result = dns_message_peekheader(&b, &id, &msgflags);
|
||||
if (result != ISC_R_SUCCESS || l->sendmsg->id != id) {
|
||||
match = false;
|
||||
if (l->tcp_mode) {
|
||||
@@ -3638,7 +3626,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
|
||||
parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
|
||||
}
|
||||
result = dns_message_parse(msg, b, parseflags);
|
||||
result = dns_message_parse(msg, &b, parseflags);
|
||||
if (result == DNS_R_RECOVERABLE) {
|
||||
printf(";; Warning: Message parser reports malformed "
|
||||
"message packet.\n");
|
||||
@@ -3646,7 +3634,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf(";; Got bad packet: %s\n", isc_result_totext(result));
|
||||
hex_dump(b);
|
||||
hex_dump(&b);
|
||||
query->waiting_connect = false;
|
||||
dns_message_destroy(&msg);
|
||||
isc_event_free(&event);
|
||||
@@ -3800,7 +3788,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
|
||||
if (tsigkey != NULL) {
|
||||
result = dns_tsig_verify(&query->recvbuf, msg, NULL, NULL);
|
||||
result = dns_tsig_verify(&b, msg, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
printf(";; Couldn't verify signature: %s\n",
|
||||
isc_result_totext(result));
|
||||
@@ -3816,7 +3804,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
check_result(result,"dns_message_getquerytsig");
|
||||
}
|
||||
|
||||
extrabytes = isc_buffer_remaininglength(b);
|
||||
extrabytes = isc_buffer_remaininglength(&b);
|
||||
|
||||
debug("after parse");
|
||||
if (l->doing_xfr && l->xfr_q == NULL) {
|
||||
@@ -3863,8 +3851,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
(l->origin != NULL || l->need_search)) {
|
||||
if (!next_origin(query->lookup) || showsearch) {
|
||||
dighost_printmessage(query, msg, true);
|
||||
dighost_received(b->used, &sevent->address,
|
||||
query);
|
||||
dighost_received(isc_buffer_usedlength(&b),
|
||||
&sevent->address, query);
|
||||
}
|
||||
} else if (!l->trace && !l->ns_search_only) {
|
||||
dighost_printmessage(query, msg, true);
|
||||
@@ -3931,7 +3919,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
} else {
|
||||
|
||||
if (msg->rcode == dns_rcode_noerror || l->origin == NULL) {
|
||||
dighost_received(b->used, &sevent->address, query);
|
||||
dighost_received(isc_buffer_usedlength(&b),
|
||||
&sevent->address, query);
|
||||
}
|
||||
|
||||
if (!query->lookup->ns_search_only)
|
||||
@@ -3955,10 +3944,10 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
udp_mismatch:
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
|
||||
ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);
|
||||
result = isc_socket_recvv(query->sock, &query->recvlist, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recvv");
|
||||
isc_buffer_availableregion(&query->recvbuf, &r);
|
||||
result = isc_socket_recv(query->sock, &r, 1,
|
||||
global_task, recv_done, query);
|
||||
check_result(result, "isc_socket_recv");
|
||||
recvcount++;
|
||||
isc_event_free(&event);
|
||||
UNLOCK_LOOKUP;
|
||||
@@ -4033,6 +4022,7 @@ do_lookup(dig_lookup_t *lookup) {
|
||||
lookup->pending = true;
|
||||
query = ISC_LIST_HEAD(lookup->q);
|
||||
if (query != NULL) {
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
if (lookup->tcp_mode)
|
||||
send_tcp_connect(query);
|
||||
else
|
||||
|
||||
+3
-4
@@ -143,7 +143,6 @@ show_usage(void) {
|
||||
" -c specifies query class for non-IN data\n"
|
||||
" -C compares SOA records on authoritative nameservers\n"
|
||||
" -d is equivalent to -v\n"
|
||||
" -i IP6.INT reverse lookups\n"
|
||||
" -l lists all hosts in a domain, using AXFR\n"
|
||||
" -m set memory debugging flag (trace|record|usage)\n"
|
||||
" -N changes the number of dots allowed before root lookup is done\n"
|
||||
@@ -762,7 +761,7 @@ parse_args(bool is_batchfile, int argc, char **argv) {
|
||||
default_lookups = false;
|
||||
break;
|
||||
case 'i':
|
||||
lookup->ip6_int = true;
|
||||
/* deprecated */
|
||||
break;
|
||||
case 'n':
|
||||
/* deprecated */
|
||||
@@ -841,8 +840,8 @@ parse_args(bool is_batchfile, int argc, char **argv) {
|
||||
check_ra = true;
|
||||
|
||||
lookup->pending = false;
|
||||
if (get_reverse(store, sizeof(store), hostname,
|
||||
lookup->ip6_int, true) == ISC_R_SUCCESS) {
|
||||
if (get_reverse(store, sizeof(store), hostname, true)
|
||||
== ISC_R_SUCCESS) {
|
||||
strlcpy(lookup->textname, store, sizeof(lookup->textname));
|
||||
lookup->rdtype = dns_rdatatype_ptr;
|
||||
lookup->rdtypeset = true;
|
||||
|
||||
@@ -179,18 +179,6 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Obsolete.
|
||||
Use the IP6.INT domain for reverse lookups of IPv6
|
||||
addresses as defined in RFC1886 and deprecated in RFC4159.
|
||||
The default is to use IP6.ARPA as specified in RFC3596.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l</term>
|
||||
<listitem>
|
||||
|
||||
+12
-11
@@ -26,6 +26,7 @@
|
||||
#include <isc/formatcheck.h>
|
||||
#include <isc/lang.h>
|
||||
#include <isc/list.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/sockaddr.h>
|
||||
@@ -81,6 +82,11 @@ typedef struct dig_server dig_server_t;
|
||||
typedef ISC_LIST(dig_server_t) dig_serverlist_t;
|
||||
typedef struct dig_searchlist dig_searchlist_t;
|
||||
|
||||
#define DIG_QUERY_MAGIC ISC_MAGIC('D','i','g','q')
|
||||
|
||||
#define DIG_VALID_QUERY(x) ISC_MAGIC_VALID((x), DIG_QUERY_MAGIC)
|
||||
|
||||
|
||||
/*% The dig_lookup structure */
|
||||
struct dig_lookup {
|
||||
bool
|
||||
@@ -103,7 +109,6 @@ struct dig_lookup {
|
||||
trace_root, /*% initial query for either +trace or +nssearch */
|
||||
tcp_mode,
|
||||
tcp_mode_set,
|
||||
ip6_int,
|
||||
comments,
|
||||
stats,
|
||||
section_question,
|
||||
@@ -185,6 +190,7 @@ struct dig_lookup {
|
||||
|
||||
/*% The dig_query structure */
|
||||
struct dig_query {
|
||||
unsigned int magic;
|
||||
dig_lookup_t *lookup;
|
||||
bool waiting_connect,
|
||||
pending_free,
|
||||
@@ -203,15 +209,12 @@ struct dig_query {
|
||||
bool ixfr_axfr;
|
||||
char *servname;
|
||||
char *userarg;
|
||||
isc_bufferlist_t sendlist,
|
||||
recvlist,
|
||||
lengthlist;
|
||||
isc_buffer_t recvbuf,
|
||||
lengthbuf,
|
||||
slbuf;
|
||||
char *recvspace,
|
||||
lengthspace[4],
|
||||
slspace[4];
|
||||
tmpsendbuf,
|
||||
sendbuf;
|
||||
char *recvspace, *tmpsendspace,
|
||||
lengthspace[4];
|
||||
isc_socket_t *sock;
|
||||
ISC_LINK(dig_query_t) link;
|
||||
ISC_LINK(dig_query_t) clink;
|
||||
@@ -219,7 +222,6 @@ struct dig_query {
|
||||
isc_time_t time_sent;
|
||||
isc_time_t time_recv;
|
||||
uint64_t byte_count;
|
||||
isc_buffer_t sendbuf;
|
||||
isc_timer_t *timer;
|
||||
};
|
||||
|
||||
@@ -284,8 +286,7 @@ int
|
||||
getaddresses(dig_lookup_t *lookup, const char *host, isc_result_t *resultp);
|
||||
|
||||
isc_result_t
|
||||
get_reverse(char *reverse, size_t len, char *value, bool ip6_int,
|
||||
bool strict);
|
||||
get_reverse(char *reverse, size_t len, char *value, bool strict);
|
||||
|
||||
ISC_PLATFORM_NORETURN_PRE void
|
||||
fatal(const char *format, ...)
|
||||
|
||||
+1
-7
@@ -772,7 +772,7 @@ addlookup(char *opt) {
|
||||
rdclass = dns_rdataclass_in;
|
||||
}
|
||||
lookup = make_empty_lookup();
|
||||
if (get_reverse(store, sizeof(store), opt, lookup->ip6_int, true)
|
||||
if (get_reverse(store, sizeof(store), opt, true)
|
||||
== ISC_R_SUCCESS) {
|
||||
strlcpy(lookup->textname, store, sizeof(lookup->textname));
|
||||
lookup->rdtype = dns_rdatatype_ptr;
|
||||
@@ -923,12 +923,6 @@ flush_lookup_list(void) {
|
||||
ISC_SOCKCANCEL_ALL);
|
||||
isc_socket_detach(&q->sock);
|
||||
}
|
||||
if (ISC_LINK_LINKED(&q->recvbuf, link))
|
||||
ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf,
|
||||
link);
|
||||
if (ISC_LINK_LINKED(&q->lengthbuf, link))
|
||||
ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf,
|
||||
link);
|
||||
isc_buffer_invalidate(&q->recvbuf);
|
||||
isc_buffer_invalidate(&q->lengthbuf);
|
||||
qp = q;
|
||||
|
||||
@@ -489,7 +489,8 @@ nslookup -query=hinfo -timeout=10
|
||||
If you'd like to turn off the IDN support for some reason, define
|
||||
the <envar>IDN_DISABLE</envar> environment variable.
|
||||
The IDN support is disabled if the variable is set when
|
||||
<command>nslookup</command> runs.
|
||||
<command>nslookup</command> runs or when the standard output is not
|
||||
a tty.
|
||||
</para>
|
||||
</refsection>
|
||||
|
||||
|
||||
+2
-5
@@ -793,10 +793,7 @@ create_managers(void) {
|
||||
named_g_udpdisp = 1;
|
||||
#else
|
||||
if (named_g_udpdisp == 0) {
|
||||
if (named_g_cpus_detected == 1)
|
||||
named_g_udpdisp = 1;
|
||||
else
|
||||
named_g_udpdisp = named_g_cpus_detected - 1;
|
||||
named_g_udpdisp = named_g_cpus_detected;
|
||||
}
|
||||
if (named_g_udpdisp > named_g_cpus)
|
||||
named_g_udpdisp = named_g_cpus;
|
||||
@@ -824,7 +821,7 @@ create_managers(void) {
|
||||
}
|
||||
|
||||
result = isc_socketmgr_create2(named_g_mctx, &named_g_socketmgr,
|
||||
maxsocks);
|
||||
maxsocks, named_g_cpus);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_socketmgr_create() failed: %s",
|
||||
|
||||
+54
-15
@@ -9327,8 +9327,7 @@ load_zones(named_server_t *server, bool init, bool reconfig) {
|
||||
* the initial server setup; it isn't necessary during
|
||||
* a reload.)
|
||||
*/
|
||||
isc_taskmgr_setmode(named_g_taskmgr,
|
||||
isc_taskmgrmode_privileged);
|
||||
isc_taskmgr_setprivilegedmode(named_g_taskmgr);
|
||||
}
|
||||
|
||||
isc_task_endexclusive(server->task);
|
||||
@@ -10877,7 +10876,7 @@ named_server_dumpsecroots(named_server_t *server, isc_lex_t *lex,
|
||||
continue;
|
||||
}
|
||||
CHECK(putstr(text, "\n Negative trust anchors:\n\n"));
|
||||
CHECK(dns_ntatable_totext(ntatable, text));
|
||||
CHECK(dns_ntatable_totext(ntatable, NULL, text));
|
||||
}
|
||||
if (ptr != NULL)
|
||||
ptr = next_token(lex, text);
|
||||
@@ -14314,6 +14313,7 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
char *ptr, *nametext = NULL, *viewname;
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char viewbuf[DNS_NAME_FORMATSIZE];
|
||||
isc_stdtime_t now, when;
|
||||
isc_time_t t;
|
||||
char tbuf[64];
|
||||
@@ -14323,8 +14323,9 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
const dns_name_t *ntaname;
|
||||
dns_name_t *fname;
|
||||
dns_ttl_t ntattl;
|
||||
bool ttlset = false, excl = false;
|
||||
bool ttlset = false, excl = false, viewfound = false;
|
||||
dns_rdataclass_t rdclass = dns_rdataclass_in;
|
||||
bool first = true;
|
||||
|
||||
UNUSED(force);
|
||||
|
||||
@@ -14337,18 +14338,24 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
bool opts = true;
|
||||
|
||||
/* Check for options */
|
||||
ptr = next_token(lex, text);
|
||||
if (ptr == NULL) {
|
||||
return (ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
|
||||
if (argcheck(ptr, "dump")) {
|
||||
if (!opts) {
|
||||
nametext = ptr;
|
||||
} else if (strcmp(ptr, "--") == 0) {
|
||||
opts = false;
|
||||
} else if (argcheck(ptr, "dump")) {
|
||||
dump = true;
|
||||
} else if (argcheck(ptr, "remove")) {
|
||||
ntattl = 0;
|
||||
ttlset = true;
|
||||
} else if (argcheck(ptr, "force")) {
|
||||
} else if (opts && argcheck(ptr, "force")) {
|
||||
force = true;
|
||||
continue;
|
||||
} else if (argcheck(ptr, "lifetime")) {
|
||||
@@ -14388,6 +14395,9 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
tr.length = strlen(ptr);
|
||||
CHECK(dns_rdataclass_fromtext(&rdclass, &tr));
|
||||
continue;
|
||||
} else if (ptr[0] == '-') {
|
||||
msg = "Unknown option";
|
||||
CHECK(DNS_R_SYNTAX);
|
||||
} else {
|
||||
nametext = ptr;
|
||||
}
|
||||
@@ -14410,7 +14420,8 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
continue;
|
||||
}
|
||||
CHECK(dns_ntatable_totext(ntatable, text));
|
||||
|
||||
CHECK(dns_ntatable_totext(ntatable, view->name, text));
|
||||
}
|
||||
CHECK(putnull(text));
|
||||
|
||||
@@ -14448,6 +14459,14 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
|
||||
/* Look for the view name. */
|
||||
viewname = next_token(lex, text);
|
||||
if (viewname != NULL) {
|
||||
strlcpy(viewbuf, viewname, DNS_NAME_FORMATSIZE);
|
||||
viewname = viewbuf;
|
||||
}
|
||||
|
||||
if (next_token(lex, text) != NULL) {
|
||||
CHECK(DNS_R_SYNTAX);
|
||||
}
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
@@ -14458,11 +14477,10 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
view != NULL;
|
||||
view = ISC_LIST_NEXT(view, link))
|
||||
{
|
||||
static bool first = true;
|
||||
|
||||
if (viewname != NULL && strcmp(view->name, viewname) != 0) {
|
||||
continue;
|
||||
}
|
||||
viewfound = true;
|
||||
|
||||
if (view->rdclass != rdclass && rdclass != dns_rdataclass_any) {
|
||||
continue;
|
||||
@@ -14518,22 +14536,37 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
"added NTA '%s' (%d sec) in view '%s'",
|
||||
namebuf, ntattl, view->name);
|
||||
} else {
|
||||
CHECK(dns_ntatable_delete(ntatable, ntaname));
|
||||
bool removed;
|
||||
|
||||
result = dns_ntatable_delete(ntatable, ntaname);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
removed = true;
|
||||
} else if (result == ISC_R_NOTFOUND) {
|
||||
removed = false;
|
||||
} else {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
CHECK(putstr(text, "\n"));
|
||||
}
|
||||
first = false;
|
||||
|
||||
CHECK(putstr(text, "Negative trust anchor removed: "));
|
||||
CHECK(putstr(text, "Negative trust anchor "));
|
||||
CHECK(putstr(text, removed ? "removed: "
|
||||
: "not found: "));
|
||||
CHECK(putstr(text, namebuf));
|
||||
CHECK(putstr(text, "/"));
|
||||
CHECK(putstr(text, view->name));
|
||||
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
"removed NTA '%s' in view %s",
|
||||
namebuf, view->name);
|
||||
if (removed) {
|
||||
isc_log_write(named_g_lctx,
|
||||
NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER,
|
||||
ISC_LOG_INFO,
|
||||
"removed NTA '%s' in view %s",
|
||||
namebuf, view->name);
|
||||
}
|
||||
}
|
||||
|
||||
result = dns_view_saventa(view);
|
||||
@@ -14546,6 +14579,11 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
}
|
||||
}
|
||||
|
||||
if (!viewfound) {
|
||||
msg = "No such view";
|
||||
CHECK(ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
CHECK(putnull(text));
|
||||
|
||||
cleanup:
|
||||
@@ -14553,6 +14591,7 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
|
||||
(void) putstr(text, msg);
|
||||
(void) putnull(text);
|
||||
}
|
||||
|
||||
if (excl) {
|
||||
isc_task_endexclusive(server->task);
|
||||
}
|
||||
|
||||
@@ -650,6 +650,12 @@
|
||||
<option>-l</option>, <option>-r</option>, <option>-d</option>,
|
||||
<option>-f</option>, and <option>-c</option>.
|
||||
</para>
|
||||
<para>
|
||||
Unrecognized options are treated as errors. To reference
|
||||
a domain or view name that begins with a hyphen,
|
||||
use a double-hyphen on the command line to indicate the
|
||||
end of options.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
+540
-527
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
@ 3600 SOA . . 0 0 0 0 0
|
||||
@ 3600 NS .
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.8 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.8;
|
||||
notify-source 10.53.0.8;
|
||||
transfer-source 10.53.0.8;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.8; };
|
||||
listen-on-v6 { none; };
|
||||
dnssec-validation yes;
|
||||
rate-limit {};
|
||||
require-server-cookie yes;
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
type master;
|
||||
file "example.db";
|
||||
};
|
||||
@@ -20,3 +20,4 @@ copy_setports ns4/named.conf.in ns4/named.conf
|
||||
copy_setports ns5/named.conf.in ns5/named.conf
|
||||
copy_setports ns6/named.conf.in ns6/named.conf
|
||||
copy_setports ns7/named.conf.in ns7/named.conf
|
||||
copy_setports ns8/named.conf.in ns8/named.conf
|
||||
|
||||
@@ -169,6 +169,17 @@ if [ $linecount != 2 ]; then ret=1; fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking require-server-cookie yes with rate-limit ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS +qr +cookie +nobadcookie soa example @10.53.0.8 > dig.out.test$n
|
||||
grep "flags: qr[^;]* ad[ ;]" dig.out.test$n > /dev/null && ret=1
|
||||
grep BADCOOKIE dig.out.test$n > /dev/null || ret=1
|
||||
linecount=`getcookie dig.out.test$n | wc -l`
|
||||
if [ $linecount != 2 ]; then ret=1; fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
#
|
||||
# Test shared cookie-secret support.
|
||||
#
|
||||
|
||||
@@ -1873,8 +1873,8 @@ $PERL -e 'my $delay = '$start' + 13 - time(); select(undef, undef, undef, $delay
|
||||
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n._11
|
||||
lines=`grep " expiry " rndc.out.ns4.test$n._11 | wc -l`
|
||||
[ "$lines" -le 2 ] || ret=1
|
||||
grep "bogus.example: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1
|
||||
grep "badds.example: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1
|
||||
grep "bogus.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1
|
||||
grep "badds.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1
|
||||
$DIG $DIGOPTS b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.11 || ret=1
|
||||
grep "status: SERVFAIL" dig.out.ns4.test$n.11 > /dev/null && ret=1
|
||||
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.12 || ret=1
|
||||
@@ -1910,14 +1910,14 @@ ret=0
|
||||
echo_i "testing NTA removals ($n)"
|
||||
$RNDCCMD 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i
|
||||
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n.1
|
||||
grep "badds.example: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1
|
||||
grep "badds.example/_default: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1
|
||||
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1
|
||||
grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null && ret=1
|
||||
grep "^a.badds.example." dig.out.ns4.test$n.1 > /dev/null || ret=1
|
||||
$RNDCCMD 10.53.0.4 nta -remove badds.example > rndc.out.ns4.test$n.2
|
||||
grep "Negative trust anchor removed: badds.example/_default" rndc.out.ns4.test$n.2 > /dev/null || ret=1
|
||||
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
|
||||
grep "badds.example: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1
|
||||
grep "badds.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1
|
||||
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
|
||||
grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
@@ -1928,7 +1928,7 @@ echo_i "remove non-existent NTA three times"
|
||||
$RNDCCMD 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.4 2>&1
|
||||
$RNDCCMD 10.53.0.4 nta -remove foo > rndc.out.ns4.test$n.5 2>&1
|
||||
$RNDCCMD 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.6 2>&1
|
||||
grep "'nta' failed: not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1
|
||||
grep "not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
ret=0
|
||||
@@ -2009,7 +2009,7 @@ sleep 4
|
||||
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
|
||||
lines=`wc -l < rndc.out.ns4.test$n.3`
|
||||
[ "$lines" -eq 1 ] || ret=1
|
||||
grep "bogus.example: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1
|
||||
grep "bogus.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1
|
||||
$DIG $DIGOPTS b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1
|
||||
grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1
|
||||
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1
|
||||
|
||||
@@ -27,6 +27,7 @@ options {
|
||||
send-cookie no;
|
||||
require-server-cookie no;
|
||||
dnssec-validation yes;
|
||||
qname-minimization disabled;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
|
||||
@@ -27,6 +27,7 @@ options {
|
||||
send-cookie no;
|
||||
require-server-cookie no;
|
||||
dnssec-validation yes;
|
||||
qname-minimization disabled;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
|
||||
@@ -28,6 +28,7 @@ options {
|
||||
require-server-cookie no;
|
||||
minimal-responses no;
|
||||
dnssec-validation yes;
|
||||
qname-minimization disabled;
|
||||
};
|
||||
|
||||
server 10.53.0.1 { tcp-only yes; };
|
||||
|
||||
@@ -27,6 +27,7 @@ options {
|
||||
send-cookie no;
|
||||
require-server-cookie no;
|
||||
dnssec-validation yes;
|
||||
qname-minimization disabled;
|
||||
};
|
||||
|
||||
server 10.53.0.1 { tcp-only yes; };
|
||||
|
||||
@@ -157,7 +157,7 @@ status=`expr $status + $ret`
|
||||
copy_setports ns3/named3.conf.in ns3/named.conf
|
||||
$RNDCCMD reconfig 2>&1 | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
echo_i "checking lame server clients are dropped at the soft limit"
|
||||
echo_i "checking lame server clients are dropped near the soft limit"
|
||||
ret=0
|
||||
fail=0
|
||||
exceeded=0
|
||||
@@ -166,7 +166,7 @@ touch ans4/norespond
|
||||
for try in 1 2 3 4 5; do
|
||||
burst b $try 400
|
||||
$DIG @10.53.0.3 -p ${PORT} a ${try}.example > dig.out.ns3.$try
|
||||
stat 360 || exceeded=`expr $exceeded + 1`
|
||||
stat 370 || exceeded=`expr $exceeded + 1`
|
||||
grep "status: NOERROR" dig.out.ns3.$try > /dev/null 2>&1 && \
|
||||
success=`expr $success + 1`
|
||||
grep "status: SERVFAIL" dig.out.ns3.$try > /dev/null 2>&1 && \
|
||||
@@ -177,7 +177,7 @@ echo_i "$success successful valid queries (expected 5)"
|
||||
[ "$success" -eq 5 ] || { echo_i "failed"; ret=1; }
|
||||
echo_i "$fail SERVFAIL responses (expected 0)"
|
||||
[ "$fail" -eq 0 ] || { echo_i "failed"; ret=1; }
|
||||
echo_i "clients count exceeded 360 on $exceeded trials (expected 0)"
|
||||
echo_i "clients count exceeded 370 on $exceeded trials (expected 0)"
|
||||
[ "$exceeded" -eq 0 ] || { echo_i "failed"; ret=1; }
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -185,11 +185,11 @@ idna_enabled_test() {
|
||||
# Note that ASCII characters are converted to lower-case.
|
||||
|
||||
text="Checking valid non-ASCII label"
|
||||
idna_test "$text" "" "München" "münchen."
|
||||
idna_test "$text" "" "München" "M\195\188nchen."
|
||||
idna_test "$text" "+noidnin +noidnout" "München" "M\195\188nchen."
|
||||
idna_test "$text" "+noidnin +idnout" "München" "M\195\188nchen."
|
||||
idna_test "$text" "+idnin +noidnout" "München" "xn--mnchen-3ya."
|
||||
idna_test "$text" "+idnin +idnout" "München" "münchen."
|
||||
idna_test "$text" "+idnin +idnout" "München" "münchen."
|
||||
|
||||
|
||||
# Tests of transitional processing of a valid U-label
|
||||
@@ -210,7 +210,7 @@ idna_enabled_test() {
|
||||
# for the valid U-label.
|
||||
|
||||
text="Checking that non-transitional IDNA processing is used"
|
||||
idna_test "$text" "" "faß.de" "faß.de."
|
||||
idna_test "$text" "" "faß.de" "fa\195\159.de."
|
||||
idna_test "$text" "+noidnin +noidnout" "faß.de" "fa\195\159.de."
|
||||
idna_test "$text" "+noidnin +idnout" "faß.de" "fa\195\159.de."
|
||||
idna_test "$text" "+idnin +noidnout" "faß.de" "xn--fa-hia.de."
|
||||
@@ -220,11 +220,11 @@ idna_enabled_test() {
|
||||
# onto the Greek sigma character ("σ") in IDNA2003.
|
||||
|
||||
text="Second check that non-transitional IDNA processing is used"
|
||||
idna_test "$text" "" "βόλος.com" "βόλος.com."
|
||||
idna_test "$text" "" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
|
||||
idna_test "$text" "+noidnin +noidnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
|
||||
idna_test "$text" "+noidnin +idnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
|
||||
idna_test "$text" "+idnin +noidnout" "βόλος.com" "xn--nxasmm1c.com."
|
||||
idna_test "$text" "+idnin +idnout" "βόλος.com" "βόλος.com."
|
||||
idna_test "$text" "+idnin +idnout" "βόλος.com" "βόλος.com."
|
||||
|
||||
|
||||
|
||||
@@ -238,9 +238,9 @@ idna_enabled_test() {
|
||||
# The "+[no]idnin" flag has no effect in these cases.
|
||||
|
||||
text="Checking valid A-label"
|
||||
idna_test "$text" "" "xn--nxasmq6b.com" "βόλοσ.com."
|
||||
idna_test "$text" "" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
|
||||
idna_test "$text" "+noidnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
|
||||
idna_test "$text" "+noidnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
|
||||
idna_test "$text" "+noidnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
|
||||
idna_test "$text" "+idnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
|
||||
idna_test "$text" "+idnin +idnout" "xn--nxasmq6b.com" "βόλοσ.com."
|
||||
|
||||
@@ -259,7 +259,7 @@ idna_enabled_test() {
|
||||
# a shorter label is detected and rejected.
|
||||
|
||||
text="Checking punycode label shorter than minimum valid length"
|
||||
idna_fail "$text" "" "xn--xx"
|
||||
idna_test "$text" "" "xn--xx" "xn--xx."
|
||||
idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
|
||||
idna_fail "$text" "+noidnin +idnout" "xn--xx"
|
||||
idna_fail "$text" "+idnin +noidnout" "xn--xx"
|
||||
@@ -268,7 +268,7 @@ idna_enabled_test() {
|
||||
# Fake A-label - the string does not translate to anything.
|
||||
|
||||
text="Checking fake A-label"
|
||||
idna_fail "$text" "" "xn--ahahah"
|
||||
idna_test "$text" "" "xn--ahahah" "xn--ahahah."
|
||||
idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah."
|
||||
idna_fail "$text" "+noidnin +idnout" "xn--ahahah"
|
||||
idna_fail "$text" "+idnin +noidnout" "xn--ahahah"
|
||||
@@ -285,7 +285,7 @@ idna_enabled_test() {
|
||||
idna_fail "$text" "+idnin +noidnout" "$label"
|
||||
idna_fail "$text" "+idnin +idnout" "$label"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Tests of a valid unicode string but an invalid U-label (input)
|
||||
@@ -301,7 +301,7 @@ idna_enabled_test() {
|
||||
# The +[no]idnout options should not have any effect on the test.
|
||||
|
||||
text="Checking invalid input U-label"
|
||||
idna_fail "$text" "" "√.com"
|
||||
idna_test "$text" "" "√.com" "\226\136\154.com."
|
||||
idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com."
|
||||
idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com."
|
||||
idna_fail "$text" "+idnin +noidnout" "√.com"
|
||||
@@ -323,7 +323,7 @@ idna_enabled_test() {
|
||||
# The +[no]idnin options should not have any effect on the test.
|
||||
|
||||
text="Checking invalid output U-label"
|
||||
idna_fail "$text" "" "xn--19g"
|
||||
idna_test "$text" "" "xn--19g" "xn--19g."
|
||||
idna_test "$text" "+noidnin +noidnout" "xn--19g" "xn--19g."
|
||||
idna_fail "$text" "+noidnin +idnout" "xn--19g"
|
||||
idna_test "$text" "+idnin +noidnout" "xn--19g" "xn--19g."
|
||||
|
||||
@@ -150,10 +150,11 @@ $RNDCCMD 10.53.0.6 flush
|
||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.6 > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
sort ans2/query.log > ans2/query.log.sorted
|
||||
cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
|
||||
ADDR ns2.bad.
|
||||
NS bad.
|
||||
NS boing.bad.
|
||||
ADDR ns2.bad.
|
||||
__EOF
|
||||
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
|
||||
@@ -44,39 +44,42 @@ $SIG{TERM} = \&rmpid;
|
||||
|
||||
sub handleUDP {
|
||||
my ($buf) = @_;
|
||||
my $packet;
|
||||
my $request;
|
||||
|
||||
if ($Net::DNS::VERSION > 0.68) {
|
||||
$packet = new Net::DNS::Packet(\$buf, 0);
|
||||
$request = new Net::DNS::Packet(\$buf, 0);
|
||||
$@ and die $@;
|
||||
} else {
|
||||
my $err;
|
||||
($packet, $err) = new Net::DNS::Packet(\$buf, 0);
|
||||
($request, $err) = new Net::DNS::Packet(\$buf, 0);
|
||||
$err and die $err;
|
||||
}
|
||||
|
||||
my @questions = $packet->question;
|
||||
my @questions = $request->question;
|
||||
my $qname = $questions[0]->qname;
|
||||
my $qtype = $questions[0]->qtype;
|
||||
my $qclass = $questions[0]->qclass;
|
||||
my $id = $packet->header->id;
|
||||
my $id = $request->header->id;
|
||||
|
||||
$packet->header->qr(1);
|
||||
$packet->header->aa(1);
|
||||
$packet->header->tc(0);
|
||||
my $response = new Net::DNS::Packet($qname, $qtype, $qclass);
|
||||
$response->header->qr(1);
|
||||
$response->header->aa(1);
|
||||
$response->header->tc(0);
|
||||
$response->header->id($id);
|
||||
|
||||
# Responses to queries for no-questions/NS and ns.no-questions/A are
|
||||
# _not_ malformed or truncated.
|
||||
if ($qname eq "no-questions" && $qtype eq "NS") {
|
||||
$packet->push("answer", new Net::DNS::RR($qname . " 300 NS ns.no-questions"));
|
||||
$packet->push("additional", new Net::DNS::RR("ns.no-questions. 300 A 10.53.0.8"));
|
||||
return $packet->data;
|
||||
$response->push("answer", new Net::DNS::RR($qname . " 300 NS ns.no-questions"));
|
||||
$response->push("additional", new Net::DNS::RR("ns.no-questions. 300 A 10.53.0.8"));
|
||||
return $response->data;
|
||||
} elsif ($qname eq "ns.no-questions") {
|
||||
$packet->push("answer", new Net::DNS::RR($qname . " 300 A 10.53.0.8"));
|
||||
return $packet->data;
|
||||
$response->push("answer", new Net::DNS::RR($qname . " 300 A 10.53.0.8"))
|
||||
if ($qtype eq "A");
|
||||
return $response->data;
|
||||
} elsif ($qname =~ /\.formerr-to-all$/) {
|
||||
$packet->header->rcode("FORMERR");
|
||||
return $packet->data;
|
||||
$response->header->rcode("FORMERR");
|
||||
return $response->data;
|
||||
}
|
||||
|
||||
# don't use Net::DNS to construct the header only reply as early
|
||||
@@ -110,14 +113,14 @@ sub handleTCP {
|
||||
my $id = $request->header->id;
|
||||
|
||||
my @results = ();
|
||||
my $packet = new Net::DNS::Packet($qname, $qtype, $qclass);
|
||||
my $response = new Net::DNS::Packet($qname, $qtype, $qclass);
|
||||
|
||||
$packet->header->qr(1);
|
||||
$packet->header->aa(1);
|
||||
$packet->header->id($id);
|
||||
$response->header->qr(1);
|
||||
$response->header->aa(1);
|
||||
$response->header->id($id);
|
||||
|
||||
$packet->push("answer", new Net::DNS::RR("$qname 300 A 1.2.3.4"));
|
||||
push(@results, $packet->data);
|
||||
$response->push("answer", new Net::DNS::RR("$qname 300 A 1.2.3.4"));
|
||||
push(@results, $response->data);
|
||||
|
||||
return \@results;
|
||||
}
|
||||
|
||||
@@ -24,28 +24,6 @@ grep "another named process" ns2/named.run > /dev/null && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
if [ ! "$CYGWIN" ]; then
|
||||
n=`expr $n + 1`
|
||||
echo_i "verifying that named checks for conflicting listeners ($n)"
|
||||
ret=0
|
||||
(cd ns2; $NAMED -c named-alt1.conf -D ns2-extra-1 -X other.lock -m record,size,mctx -d 99 -g -U 4 >> named2.run 2>&1 & )
|
||||
for i in 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
grep "unable to listen on any configured interface" ns2/named2.run > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
grep "unable to listen on any configured interface" ns2/named2.run > /dev/null || ret=1
|
||||
for i in 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
grep "exiting (due to fatal error)" ns2/named2.run > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
pid=`cat ns2/named2.pid 2>/dev/null`
|
||||
test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "verifying that named checks for conflicting named processes ($n)"
|
||||
ret=0
|
||||
|
||||
@@ -83,6 +83,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -92,6 +93,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -101,6 +103,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -166,6 +169,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -175,6 +179,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -184,6 +189,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -247,6 +253,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -256,6 +263,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -265,6 +273,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -296,6 +305,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -305,6 +315,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nodata.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -314,6 +325,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -371,6 +383,17 @@ grep "syntax error" rndc.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "flush cache, re-enable serve-stale and query again ($n)"
|
||||
ret=0
|
||||
$RNDCCMD 10.53.0.1 flushtree example > rndc.out.test$n.1 2>&1 || ret=1
|
||||
$RNDCCMD 10.53.0.1 serve-stale on > rndc.out.test$n.2 2>&1 || ret=1
|
||||
$DIG -p ${PORT} @10.53.0.1 data.example TXT > dig.out.test$n
|
||||
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "enable responses from authoritative server ($n)"
|
||||
ret=0
|
||||
@@ -386,6 +409,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -395,6 +419,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.3 nodata.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -404,6 +429,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -474,6 +500,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -483,6 +510,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.3 nodata.example TXT > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -492,6 +520,7 @@ ret=0
|
||||
$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
|
||||
grep "example.*1.*IN" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
|
||||
+3
-9
@@ -120,7 +120,6 @@ static char hexcookie[81];
|
||||
|
||||
struct query {
|
||||
char textname[MXNAME]; /*% Name we're going to be looking up */
|
||||
bool ip6_int;
|
||||
bool recurse;
|
||||
bool have_aaonly;
|
||||
bool have_adflag;
|
||||
@@ -774,7 +773,6 @@ help(void) {
|
||||
" local opt is one of:\n"
|
||||
" -c class (specify query class)\n"
|
||||
" -t type (specify query type)\n"
|
||||
" -i (use IP6.INT for IPv6 reverse lookups)\n"
|
||||
" -x dot-notation (shortcut for reverse lookups)\n"
|
||||
" +timeout=### (Set query timeout) [UDP=5,TCP=10]\n"
|
||||
" +udptimeout=### (Set timeout before UDP retry)\n"
|
||||
@@ -995,8 +993,7 @@ reverse_octets(const char *in, char **p, char *end) {
|
||||
}
|
||||
|
||||
static void
|
||||
get_reverse(char *reverse, size_t len, const char *value,
|
||||
bool ip6_int)
|
||||
get_reverse(char *reverse, size_t len, const char *value)
|
||||
{
|
||||
int r;
|
||||
isc_result_t result;
|
||||
@@ -1010,8 +1007,6 @@ get_reverse(char *reverse, size_t len, const char *value,
|
||||
dns_name_t *name;
|
||||
unsigned int options = 0;
|
||||
|
||||
if (ip6_int)
|
||||
options |= DNS_BYADDROPT_IPV6INT;
|
||||
name = dns_fixedname_initname(&fname);
|
||||
result = dns_byaddr_createptrname(&addr, options, name);
|
||||
CHECK("dns_byaddr_createptrname2", result);
|
||||
@@ -1594,7 +1589,7 @@ dash_option(const char *option, char *next, struct query *query,
|
||||
exit(0);
|
||||
break;
|
||||
case 'i':
|
||||
query->ip6_int = true;
|
||||
/* deprecated */
|
||||
break;
|
||||
case 'm':
|
||||
/*
|
||||
@@ -1674,7 +1669,7 @@ dash_option(const char *option, char *next, struct query *query,
|
||||
query->rdtype = rdtype;
|
||||
return (value_from_next);
|
||||
case 'x':
|
||||
get_reverse(textname, sizeof(textname), value, query->ip6_int);
|
||||
get_reverse(textname, sizeof(textname), value);
|
||||
strlcpy(query->textname, textname, sizeof(query->textname));
|
||||
query->rdtype = dns_rdatatype_ptr;
|
||||
query->rdclass = dns_rdataclass_in;
|
||||
@@ -1788,7 +1783,6 @@ parse_args(bool is_batchfile, int argc, char **argv)
|
||||
|
||||
if (!is_batchfile) {
|
||||
default_query.textname[0] = 0;
|
||||
default_query.ip6_int = false;
|
||||
default_query.recurse = true;
|
||||
default_query.have_aaonly = false;
|
||||
default_query.have_adflag = true; /*XXX*/
|
||||
|
||||
@@ -420,11 +420,6 @@
|
||||
a reverse lookup with the "PTR" query type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <option>-i</option> option sets the reverse domain for
|
||||
IPv6 addresses to IP6.INT.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Reverse lookups — mapping addresses to names — are
|
||||
simplified by the <option>-x</option> option.
|
||||
@@ -434,8 +429,7 @@
|
||||
query name like <literal>11.12.13.10.in-addr.arpa</literal> and
|
||||
sets the query type and class to PTR and IN respectively.
|
||||
By default, IPv6 addresses are looked up using nibble format
|
||||
under the IP6.ARPA domain. To use the older RFC1886 method
|
||||
using the IP6.INT domain specify the <option>-i</option> option.
|
||||
under the IP6.ARPA domain.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
||||
+21
@@ -75,6 +75,9 @@
|
||||
/* Define to 1 if you have the <cmocka.h> header file. */
|
||||
#undef HAVE_CMOCKA_H
|
||||
|
||||
/* Define to 1 if you have the `cpuset_setaffinty' function. */
|
||||
#undef HAVE_CPUSET_SETAFFINITY
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_zalloc' function. */
|
||||
#undef HAVE_CRYPTO_ZALLOC
|
||||
|
||||
@@ -285,6 +288,9 @@
|
||||
/* define if OpenSSL supports Ed25519 */
|
||||
#undef HAVE_OPENSSL_ED25519
|
||||
|
||||
/* Define to 1 if you have the `processor_bind' function. */
|
||||
#undef HAVE_PROCESSOR_BIND
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
@@ -303,6 +309,9 @@
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
#undef HAVE_PTHREAD_PRIO_INHERIT
|
||||
|
||||
/* Define to 1 if you have the `pthread_setaffinity_np' function. */
|
||||
#undef HAVE_PTHREAD_SETAFFINITY_NP
|
||||
|
||||
/* Define to 1 if you have the `pthread_setname_np' function. */
|
||||
#undef HAVE_PTHREAD_SETNAME_NP
|
||||
|
||||
@@ -333,6 +342,9 @@
|
||||
/* Define to 1 if you have the <sched.h> header file. */
|
||||
#undef HAVE_SCHED_H
|
||||
|
||||
/* Define to 1 if you have the `sched_setaffinity' function. */
|
||||
#undef HAVE_SCHED_SETAFFINITY
|
||||
|
||||
/* Define to 1 if you have the `sched_yield' function. */
|
||||
#undef HAVE_SCHED_YIELD
|
||||
|
||||
@@ -387,6 +399,9 @@
|
||||
/* Define to 1 if you have the <sys/capability.h> header file. */
|
||||
#undef HAVE_SYS_CAPABILITY_H
|
||||
|
||||
/* Define to 1 if you have the <sys/cpuset.h> header file. */
|
||||
#undef HAVE_SYS_CPUSET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||
#undef HAVE_SYS_DEVPOLL_H
|
||||
|
||||
@@ -396,6 +411,12 @@
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/prctl.h> header file. */
|
||||
#undef HAVE_SYS_PRCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/procset.h> header file. */
|
||||
#undef HAVE_SYS_PROCSET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
|
||||
@@ -844,6 +844,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -1003,6 +1004,7 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
@@ -1255,6 +1257,15 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@@ -1392,7 +1403,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@@ -1545,6 +1556,7 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@@ -12140,7 +12152,7 @@ done
|
||||
if test "${with_python+set}" = set; then :
|
||||
withval=$with_python; use_python="$withval"
|
||||
else
|
||||
use_python="unspec"
|
||||
use_python="yes"
|
||||
fi
|
||||
|
||||
|
||||
@@ -12174,9 +12186,9 @@ $as_echo_n "checking for python support... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
|
||||
$as_echo "disabled" >&6; }
|
||||
;;
|
||||
unspec|yes|*)
|
||||
yes|*)
|
||||
case "$use_python" in
|
||||
unspec|yes|'')
|
||||
yes|'')
|
||||
for p in $python
|
||||
do
|
||||
for ac_prog in $p
|
||||
@@ -12278,30 +12290,16 @@ $as_echo "not found" >&6; }
|
||||
unset PYTHON
|
||||
fi
|
||||
done
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for python support" >&5
|
||||
$as_echo_n "checking for python support... " >&6; }
|
||||
if test "X$PYTHON" != "X"
|
||||
then
|
||||
case "$use_python_install_dir" in
|
||||
unspec)
|
||||
PYTHON_INSTALL_DIR=""
|
||||
PYTHON_INSTALL_LIB=""
|
||||
;;
|
||||
*)
|
||||
PYTHON_INSTALL_DIR="$use_python_install_dir"
|
||||
PYTHON_INSTALL_LIB="--install-lib=$use_python_install_dir"
|
||||
;;
|
||||
esac
|
||||
PYTHON_INSTALL_DIR="$use_python_install_dir"
|
||||
PYTHON_INSTALL_LIB="--install-lib=$use_python_install_dir"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for python support" >&5
|
||||
$as_echo_n "checking for python support... " >&6; }
|
||||
case "$use_python" in
|
||||
unspec)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
|
||||
$as_echo "disabled" >&6; }
|
||||
;;
|
||||
yes)
|
||||
as_fn_error $? "missing python" "$LINENO" 5
|
||||
;;
|
||||
esac
|
||||
as_fn_error $? "no; python required for dnssec-keymgr" "$LINENO" 5
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@@ -15249,6 +15247,43 @@ fi
|
||||
done
|
||||
|
||||
|
||||
for ac_header in sys/cpuset.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "sys/cpuset.h" "ac_cv_header_sys_cpuset_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sys_cpuset_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_SYS_CPUSET_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in sys/procset.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "sys/procset.h" "ac_cv_header_sys_procset_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sys_procset_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_SYS_PROCSET_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in pthread_setaffinity_np cpuset_setaffinity processor_bind sched_setaffinity
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# Look for functions relating to thread naming
|
||||
for ac_func in pthread_setname_np pthread_set_name_np
|
||||
do :
|
||||
@@ -23969,7 +24004,7 @@ report() {
|
||||
echo " DNS Response Policy Service interface (--enable-dnsrps)"
|
||||
test "yes" = "$enable_fixed" && \
|
||||
echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)"
|
||||
test "yes" = "$want_backtrace" && \
|
||||
test "yes" = "$enable_backtrace" && \
|
||||
echo " Print backtrace on crash (--enable-backtrace)"
|
||||
test "minimal" = "$want_symtable" && \
|
||||
echo " Use symbol table for backtrace, named only (--enable-symtable)"
|
||||
@@ -24027,7 +24062,7 @@ report() {
|
||||
echo " Using PKCS#11 for Public-Key Cryptography (--without-native-pkcs11)"
|
||||
)
|
||||
|
||||
test "yes" = "$want_backtrace" || \
|
||||
test "yes" = "$enable_backtrace" || \
|
||||
echo " Print backtrace on crash (--enable-backtrace)"
|
||||
test "yes" = "$want_querytrace" || \
|
||||
echo " Very verbose query trace logging (--enable-querytrace)"
|
||||
|
||||
+15
-25
@@ -184,7 +184,7 @@ AC_SUBST(PERL)
|
||||
AC_ARG_WITH(python,
|
||||
AS_HELP_STRING([--with-python=PATH],
|
||||
[specify path to python interpreter]),
|
||||
use_python="$withval", use_python="unspec")
|
||||
use_python="$withval", use_python="yes")
|
||||
AC_ARG_WITH(python-install-dir,
|
||||
AS_HELP_STRING([--with-python-install-dir=PATH],
|
||||
[installation directory for Python modules]),
|
||||
@@ -208,11 +208,11 @@ if (sys.version_info < (2,7)) or (sys.version_info < (3,2) and sys.version_info
|
||||
case "$use_python" in
|
||||
no)
|
||||
AC_MSG_CHECKING([for python support])
|
||||
AC_MSG_RESULT(disabled)
|
||||
AC_MSG_RESULT([disabled])
|
||||
;;
|
||||
unspec|yes|*)
|
||||
yes|*)
|
||||
case "$use_python" in
|
||||
unspec|yes|'')
|
||||
yes|'')
|
||||
for p in $python
|
||||
do
|
||||
AC_PATH_PROGS(PYTHON, $p)
|
||||
@@ -258,28 +258,14 @@ case "$use_python" in
|
||||
unset PYTHON
|
||||
fi
|
||||
done
|
||||
AC_MSG_CHECKING([for python support])
|
||||
if test "X$PYTHON" != "X"
|
||||
then
|
||||
case "$use_python_install_dir" in
|
||||
unspec)
|
||||
PYTHON_INSTALL_DIR=""
|
||||
PYTHON_INSTALL_LIB=""
|
||||
;;
|
||||
*)
|
||||
PYTHON_INSTALL_DIR="$use_python_install_dir"
|
||||
PYTHON_INSTALL_LIB="--install-lib=$use_python_install_dir"
|
||||
;;
|
||||
esac
|
||||
PYTHON_INSTALL_DIR="$use_python_install_dir"
|
||||
PYTHON_INSTALL_LIB="--install-lib=$use_python_install_dir"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_CHECKING([for python support])
|
||||
case "$use_python" in
|
||||
unspec)
|
||||
AC_MSG_RESULT(disabled)
|
||||
;;
|
||||
yes)
|
||||
AC_MSG_ERROR([missing python])
|
||||
;;
|
||||
esac
|
||||
AC_MSG_ERROR([no; python required for dnssec-keymgr])
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@@ -715,6 +701,10 @@ AC_CHECK_HEADERS([sched.h])
|
||||
AC_SEARCH_LIBS([sched_yield],[rt])
|
||||
AC_CHECK_FUNCS([sched_yield pthread_yield pthread_yield_np])
|
||||
|
||||
AC_CHECK_HEADERS([sys/cpuset.h])
|
||||
AC_CHECK_HEADERS([sys/procset.h])
|
||||
AC_CHECK_FUNCS([pthread_setaffinity_np cpuset_setaffinity processor_bind sched_setaffinity])
|
||||
|
||||
# Look for functions relating to thread naming
|
||||
AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np])
|
||||
AC_CHECK_HEADERS([pthread_np.h], [], [], [#include <pthread.h>])
|
||||
@@ -3225,7 +3215,7 @@ report() {
|
||||
echo " DNS Response Policy Service interface (--enable-dnsrps)"
|
||||
test "yes" = "$enable_fixed" && \
|
||||
echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)"
|
||||
test "yes" = "$want_backtrace" && \
|
||||
test "yes" = "$enable_backtrace" && \
|
||||
echo " Print backtrace on crash (--enable-backtrace)"
|
||||
test "minimal" = "$want_symtable" && \
|
||||
echo " Use symbol table for backtrace, named only (--enable-symtable)"
|
||||
@@ -3283,7 +3273,7 @@ report() {
|
||||
echo " Using PKCS#11 for Public-Key Cryptography (--without-native-pkcs11)"
|
||||
)
|
||||
|
||||
test "yes" = "$want_backtrace" || \
|
||||
test "yes" = "$enable_backtrace" || \
|
||||
echo " Print backtrace on crash (--enable-backtrace)"
|
||||
test "yes" = "$want_querytrace" || \
|
||||
echo " Very verbose query trace logging (--enable-querytrace)"
|
||||
|
||||
@@ -131,6 +131,15 @@
|
||||
|
||||
<section xml:id="relnotes_features"><info><title>New Features</title></info>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Task manager and socket code have been substantially modified.
|
||||
The manager uses per-cpu queues for tasks and network stack runs
|
||||
multiple event loops in CPU-affinitive threads. This greatly
|
||||
improves performance on large systems, especially when using
|
||||
multi-queue NICs.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A new secondary zone option, <command>mirror</command>,
|
||||
@@ -496,6 +505,16 @@
|
||||
<command>allow-query-cache</command> work. [GL #319]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
When compiled with IDN support, the <command>dig</command> and the
|
||||
<command>nslookup</command> commands now disable IDN processing when
|
||||
the standard output is not a tty (e.g. not used by human). The command
|
||||
line options +idnin and +idnout need to be used to enable IDN
|
||||
processing when <command>dig</command> or <command>nslookup</command>
|
||||
is used from the shell scripts.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
@@ -537,6 +556,13 @@
|
||||
added. This has been fixed. [GL #105]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The view name is now included in the output of
|
||||
<command>rndc nta -dump</command>, for consistency with
|
||||
other options. [GL !816]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<command>named</command> now rejects excessively large
|
||||
|
||||
+2
-5
@@ -55,6 +55,7 @@ dns_byaddr_createptrname(const isc_netaddr_t *address, unsigned int options,
|
||||
unsigned int len;
|
||||
|
||||
REQUIRE(address != NULL);
|
||||
UNUSED(options);
|
||||
|
||||
/*
|
||||
* We create the text representation and then convert to a
|
||||
@@ -81,11 +82,7 @@ dns_byaddr_createptrname(const isc_netaddr_t *address, unsigned int options,
|
||||
*cp++ = '.';
|
||||
}
|
||||
remaining = sizeof(textname) - (cp - textname);
|
||||
if ((options & DNS_BYADDROPT_IPV6INT) != 0) {
|
||||
strlcpy(cp, "ip6.int.", remaining);
|
||||
} else {
|
||||
strlcpy(cp, "ip6.arpa.", remaining);
|
||||
}
|
||||
strlcpy(cp, "ip6.arpa.", remaining);
|
||||
} else
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
|
||||
|
||||
+1
-1
@@ -461,7 +461,7 @@ dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx,
|
||||
client->timermgr = timermgr;
|
||||
|
||||
client->task = NULL;
|
||||
result = isc_task_create(client->taskmgr, 0, &client->task);
|
||||
result = isc_task_create(client->taskmgr, 50, &client->task);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
|
||||
+53
-32
@@ -299,7 +299,8 @@ static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr,
|
||||
isc_socketmgr_t *sockmgr,
|
||||
const isc_sockaddr_t *localaddr,
|
||||
isc_socket_t **sockp,
|
||||
isc_socket_t *dup_socket);
|
||||
isc_socket_t *dup_socket,
|
||||
bool duponly);
|
||||
static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr,
|
||||
isc_socketmgr_t *sockmgr,
|
||||
isc_taskmgr_t *taskmgr,
|
||||
@@ -317,7 +318,7 @@ static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp);
|
||||
static isc_result_t open_socket(isc_socketmgr_t *mgr,
|
||||
const isc_sockaddr_t *local,
|
||||
unsigned int options, isc_socket_t **sockp,
|
||||
isc_socket_t *dup_socket);
|
||||
isc_socket_t *dup_socket, bool duponly);
|
||||
static bool portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
|
||||
isc_sockaddr_t *sockaddrp);
|
||||
|
||||
@@ -728,7 +729,7 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest,
|
||||
if (portentry != NULL)
|
||||
bindoptions |= ISC_SOCKET_REUSEADDRESS;
|
||||
result = open_socket(sockmgr, &localaddr, bindoptions, &sock,
|
||||
NULL);
|
||||
NULL, false);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (portentry == NULL) {
|
||||
portentry = new_portentry(disp, port);
|
||||
@@ -956,7 +957,6 @@ allocate_sevent(dns_dispatch_t *disp, isc_socket_t *sock,
|
||||
free_sevent, disp->sepool);
|
||||
ev->result = ISC_R_UNSET;
|
||||
ISC_LINK_INIT(ev, ev_link);
|
||||
ISC_LIST_INIT(ev->bufferlist);
|
||||
ev->region.base = NULL;
|
||||
ev->n = 0;
|
||||
ev->offset = 0;
|
||||
@@ -1668,7 +1668,7 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
|
||||
static isc_result_t
|
||||
open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
|
||||
unsigned int options, isc_socket_t **sockp,
|
||||
isc_socket_t *dup_socket)
|
||||
isc_socket_t *dup_socket, bool duponly)
|
||||
{
|
||||
isc_socket_t *sock;
|
||||
isc_result_t result;
|
||||
@@ -1676,12 +1676,16 @@ open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
|
||||
sock = *sockp;
|
||||
if (sock != NULL) {
|
||||
result = isc_socket_open(sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
} else if (dup_socket != NULL) {
|
||||
}
|
||||
} else if (dup_socket != NULL &&
|
||||
(!isc_socket_hasreuseport() || duponly))
|
||||
{
|
||||
result = isc_socket_dup(dup_socket, &sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_socket_setname(sock, "dispatcher", NULL);
|
||||
*sockp = sock;
|
||||
@@ -1689,8 +1693,9 @@ open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
|
||||
} else {
|
||||
result = isc_socket_create(mgr, isc_sockaddr_pf(local),
|
||||
isc_sockettype_udp, &sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
isc_socket_setname(sock, "dispatcher", NULL);
|
||||
@@ -1700,9 +1705,9 @@ open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
|
||||
#endif
|
||||
result = isc_socket_bind(sock, local, options);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (*sockp == NULL)
|
||||
if (*sockp == NULL) {
|
||||
isc_socket_detach(&sock);
|
||||
else {
|
||||
} else {
|
||||
isc_socket_close(sock);
|
||||
}
|
||||
return (result);
|
||||
@@ -2504,7 +2509,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
|
||||
|
||||
disp->ntasks = 1;
|
||||
disp->task[0] = NULL;
|
||||
result = isc_task_create(taskmgr, 0, &disp->task[0]);
|
||||
result = isc_task_create(taskmgr, 50, &disp->task[0]);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto kill_socket;
|
||||
|
||||
@@ -2758,7 +2763,7 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
||||
static isc_result_t
|
||||
get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
|
||||
isc_socketmgr_t *sockmgr, const isc_sockaddr_t *localaddr,
|
||||
isc_socket_t **sockp, isc_socket_t *dup_socket)
|
||||
isc_socket_t **sockp, isc_socket_t *dup_socket, bool duponly)
|
||||
{
|
||||
unsigned int i, j;
|
||||
isc_socket_t *held[DNS_DISPATCH_HELD];
|
||||
@@ -2796,7 +2801,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
|
||||
prt = ports[isc_random_uniform(nports)];
|
||||
isc_sockaddr_setport(&localaddr_bound, prt);
|
||||
result = open_socket(sockmgr, &localaddr_bound,
|
||||
0, &sock, NULL);
|
||||
0, &sock, NULL, false);
|
||||
/*
|
||||
* Continue if the port choosen is already in use
|
||||
* or the OS has reserved it.
|
||||
@@ -2817,7 +2822,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
|
||||
/* Allow to reuse address for non-random ports. */
|
||||
result = open_socket(sockmgr, localaddr,
|
||||
ISC_SOCKET_REUSEADDRESS, &sock,
|
||||
dup_socket);
|
||||
dup_socket, duponly);
|
||||
|
||||
if (result == ISC_R_SUCCESS)
|
||||
*sockp = sock;
|
||||
@@ -2829,7 +2834,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
|
||||
i = 0;
|
||||
|
||||
for (j = 0; j < 0xffffU; j++) {
|
||||
result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
|
||||
result = open_socket(sockmgr, localaddr, 0, &sock, NULL, false);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto end;
|
||||
else if (portavailable(mgr, sock, NULL))
|
||||
@@ -2873,22 +2878,27 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
||||
dns_dispatch_t *disp;
|
||||
isc_socket_t *sock = NULL;
|
||||
int i = 0;
|
||||
bool duponly = ((attributes & DNS_DISPATCHATTR_CANREUSE) == 0);
|
||||
|
||||
/* This is an attribute needed only at creation time */
|
||||
attributes &= ~DNS_DISPATCHATTR_CANREUSE;
|
||||
/*
|
||||
* dispatch_allocate() checks mgr for us.
|
||||
*/
|
||||
disp = NULL;
|
||||
result = dispatch_allocate(mgr, maxrequests, &disp);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
disp->socktype = isc_sockettype_udp;
|
||||
|
||||
if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) {
|
||||
result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock,
|
||||
dup_socket);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
dup_socket, duponly);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto deallocate_dispatch;
|
||||
}
|
||||
|
||||
if (isc_log_wouldlog(dns_lctx, 90)) {
|
||||
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||
@@ -2911,38 +2921,45 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
||||
*/
|
||||
isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr));
|
||||
if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) {
|
||||
result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
|
||||
if (sock != NULL)
|
||||
result = open_socket(sockmgr, localaddr, 0,
|
||||
&sock, NULL, false);
|
||||
if (sock != NULL) {
|
||||
isc_socket_detach(&sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto deallocate_dispatch;
|
||||
}
|
||||
}
|
||||
|
||||
disp->port_table = isc_mem_get(mgr->mctx,
|
||||
sizeof(disp->port_table[0]) *
|
||||
DNS_DISPATCH_PORTTABLESIZE);
|
||||
if (disp->port_table == NULL)
|
||||
if (disp->port_table == NULL) {
|
||||
goto deallocate_dispatch;
|
||||
for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
|
||||
}
|
||||
for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) {
|
||||
ISC_LIST_INIT(disp->port_table[i]);
|
||||
}
|
||||
|
||||
result = isc_mempool_create(mgr->mctx, sizeof(dispportentry_t),
|
||||
&disp->portpool);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto deallocate_dispatch;
|
||||
}
|
||||
isc_mempool_setname(disp->portpool, "disp_portpool");
|
||||
isc_mempool_setfreemax(disp->portpool, 128);
|
||||
}
|
||||
disp->socket = sock;
|
||||
disp->local = *localaddr;
|
||||
|
||||
if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
|
||||
if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
|
||||
disp->ntasks = MAX_INTERNAL_TASKS;
|
||||
else
|
||||
} else {
|
||||
disp->ntasks = 1;
|
||||
}
|
||||
for (i = 0; i < disp->ntasks; i++) {
|
||||
disp->task[i] = NULL;
|
||||
result = isc_task_create(taskmgr, 0, &disp->task[i]);
|
||||
result = isc_task_create(taskmgr, 50, &disp->task[i]);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
while (--i >= 0) {
|
||||
isc_task_shutdown(disp->task[i]);
|
||||
@@ -2971,8 +2988,9 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
||||
}
|
||||
|
||||
result = isc_mutex_init(&disp->sepool_lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto kill_sepool;
|
||||
}
|
||||
|
||||
isc_mempool_setname(disp->sepool, "disp_sepool");
|
||||
isc_mempool_setmaxalloc(disp->sepool, 32768);
|
||||
@@ -2991,8 +3009,9 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
||||
|
||||
mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp);
|
||||
dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); /* XXX */
|
||||
if (disp->socket != NULL)
|
||||
if (disp->socket != NULL) {
|
||||
dispatch_log(disp, LVL(90), "created socket %p", disp->socket);
|
||||
}
|
||||
|
||||
*dispp = disp;
|
||||
|
||||
@@ -3006,11 +3025,13 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
||||
kill_ctlevent:
|
||||
isc_event_free(&disp->ctlevent);
|
||||
kill_task:
|
||||
for (i = 0; i < disp->ntasks; i++)
|
||||
for (i = 0; i < disp->ntasks; i++) {
|
||||
isc_task_detach(&disp->task[i]);
|
||||
}
|
||||
kill_socket:
|
||||
if (disp->socket != NULL)
|
||||
if (disp->socket != NULL) {
|
||||
isc_socket_detach(&disp->socket);
|
||||
}
|
||||
deallocate_dispatch:
|
||||
dispatch_free(&disp);
|
||||
|
||||
|
||||
@@ -60,13 +60,6 @@ typedef struct dns_byaddrevent {
|
||||
dns_namelist_t names;
|
||||
} dns_byaddrevent_t;
|
||||
|
||||
/*
|
||||
* This option is deprecated since we now only consider nibbles.
|
||||
#define DNS_BYADDROPT_IPV6NIBBLE 0x0001
|
||||
*/
|
||||
/*% Note DNS_BYADDROPT_IPV6NIBBLE is now deprecated. */
|
||||
#define DNS_BYADDROPT_IPV6INT 0x0002
|
||||
|
||||
isc_result_t
|
||||
dns_byaddr_create(isc_mem_t *mctx, const isc_netaddr_t *address,
|
||||
dns_view_t *view, unsigned int options, isc_task_t *task,
|
||||
@@ -84,8 +77,6 @@ dns_byaddr_create(isc_mem_t *mctx, const isc_netaddr_t *address,
|
||||
* 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa.
|
||||
* \endcode
|
||||
*
|
||||
*\li #DNS_BYADDROPT_IPV6INT can be used to get nibble lookups under ip6.int.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid mctx.
|
||||
|
||||
@@ -140,6 +140,7 @@ struct dns_dispatchset {
|
||||
#define DNS_DISPATCHATTR_CONNECTED 0x00000080U
|
||||
#define DNS_DISPATCHATTR_FIXEDID 0x00000100U
|
||||
#define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U
|
||||
#define DNS_DISPATCHATTR_CANREUSE 0x00000400U
|
||||
/*@}*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -182,9 +182,10 @@ dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now,
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf);
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, const char *view,
|
||||
isc_buffer_t **buf);
|
||||
/*%<
|
||||
* Dump the NTA table to buffer at 'buf'
|
||||
* Dump the NTA table to buffer at 'buf', with view names
|
||||
*
|
||||
* Requires:
|
||||
* \li "ntatable" is a valid table.
|
||||
|
||||
+7
-3
@@ -509,7 +509,9 @@ putstr(isc_buffer_t **b, const char *str) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
|
||||
dns_ntatable_totext(dns_ntatable_t *ntatable, const char *view,
|
||||
isc_buffer_t **buf)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node;
|
||||
dns_rbtnodechain_t chain;
|
||||
@@ -552,8 +554,10 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
|
||||
isc_time_formattimestamp(&t, tbuf,
|
||||
sizeof(tbuf));
|
||||
|
||||
snprintf(obuf, sizeof(obuf), "%s%s: %s %s",
|
||||
snprintf(obuf, sizeof(obuf), "%s%s%s%s: %s %s",
|
||||
first ? "" : "\n", nbuf,
|
||||
view != NULL ? "/" : "",
|
||||
view != NULL ? view : "",
|
||||
n->expiry <= now
|
||||
? "expired"
|
||||
: "expiry",
|
||||
@@ -588,7 +592,7 @@ dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = dns_ntatable_totext(ntatable, &text);
|
||||
result = dns_ntatable_totext(ntatable, NULL, &text);
|
||||
|
||||
if (isc_buffer_usedlength(text) != 0) {
|
||||
(void) putstr(&text, "\n");
|
||||
|
||||
+42
-8
@@ -586,7 +586,7 @@ static void resquery_response(isc_task_t *task, isc_event_t *event);
|
||||
static void resquery_connected(isc_task_t *task, isc_event_t *event);
|
||||
static void fctx_try(fetchctx_t *fctx, bool retrying,
|
||||
bool badcache);
|
||||
void fctx_minimize_qname(fetchctx_t *fctx);
|
||||
static isc_result_t fctx_minimize_qname(fetchctx_t *fctx);
|
||||
static void fctx_destroy(fetchctx_t *fctx);
|
||||
static bool fctx_unlink(fetchctx_t *fctx);
|
||||
static isc_result_t ncache_adderesult(dns_message_t *message,
|
||||
@@ -4142,7 +4142,23 @@ resume_qmin(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = true;
|
||||
fctx_minimize_qname(fctx);
|
||||
|
||||
result = fctx_minimize_qname(fctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!fctx->minimized) {
|
||||
/*
|
||||
* We have finished minimizing, but fctx->finds was filled at
|
||||
* the beginning of the run - now we need to clear it before
|
||||
* sending the final query to use proper nameservers.
|
||||
*/
|
||||
fctx_cancelqueries(fctx, false, false);
|
||||
fctx_cleanupall(fctx);
|
||||
}
|
||||
|
||||
fctx_try(fctx, true, false);
|
||||
|
||||
cleanup:
|
||||
@@ -4894,7 +4910,10 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
||||
fctx->ip6arpaskip =
|
||||
(options & DNS_FETCHOPT_QMIN_SKIP_IP6A) != 0 &&
|
||||
dns_name_issubdomain(&fctx->name, &ip6_arpa);
|
||||
fctx_minimize_qname(fctx);
|
||||
result = fctx_minimize_qname(fctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_mctx;
|
||||
}
|
||||
}
|
||||
|
||||
ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
|
||||
@@ -4908,6 +4927,13 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_mctx:
|
||||
fctx->magic = 0;
|
||||
isc_mem_detach(&fctx->mctx);
|
||||
dns_adb_detach(&fctx->adb);
|
||||
dns_db_detach(&fctx->cache);
|
||||
isc_timer_detach(&fctx->timer);
|
||||
|
||||
cleanup_rmessage:
|
||||
dns_message_destroy(&fctx->rmessage);
|
||||
|
||||
@@ -10320,19 +10346,24 @@ log_fetch(const dns_name_t *name, dns_rdatatype_t type) {
|
||||
"fetch: %s/%s", namebuf, typebuf);
|
||||
}
|
||||
|
||||
void
|
||||
static isc_result_t
|
||||
fctx_minimize_qname(fetchctx_t *fctx) {
|
||||
isc_result_t result;
|
||||
unsigned int dlabels, nlabels;
|
||||
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
|
||||
dlabels = dns_name_countlabels(&fctx->qmindcname);
|
||||
nlabels = dns_name_countlabels(&fctx->name);
|
||||
dns_name_free(&fctx->qminname, fctx->mctx);
|
||||
dns_name_init(&fctx->qminname, NULL);
|
||||
|
||||
if (dlabels > fctx->qmin_labels) {
|
||||
fctx->qmin_labels = dlabels+1;
|
||||
fctx->qmin_labels = dlabels + 1;
|
||||
} else {
|
||||
fctx->qmin_labels++;
|
||||
}
|
||||
|
||||
if (fctx->ip6arpaskip) {
|
||||
/*
|
||||
* For ip6.arpa we want to skip some of the labels, with
|
||||
@@ -10357,6 +10388,7 @@ fctx_minimize_qname(fetchctx_t *fctx) {
|
||||
} else if (fctx->qmin_labels > DNS_QMIN_MAXLABELS) {
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
}
|
||||
|
||||
if (fctx->qmin_labels < nlabels) {
|
||||
/*
|
||||
* We want to query for qmin_labels from fctx->name
|
||||
@@ -10366,16 +10398,18 @@ fctx_minimize_qname(fetchctx_t *fctx) {
|
||||
dns_name_split(&fctx->name,
|
||||
fctx->qmin_labels,
|
||||
NULL, dns_fixedname_name(&fname));
|
||||
dns_name_dup(dns_fixedname_name(&fname), fctx->mctx,
|
||||
&fctx->qminname);
|
||||
result = dns_name_dup(dns_fixedname_name(&fname), fctx->mctx,
|
||||
&fctx->qminname);
|
||||
fctx->qmintype = dns_rdatatype_ns;
|
||||
fctx->minimized = true;
|
||||
} else {
|
||||
/* Minimization is done, we'll ask for whole qname */
|
||||
fctx->qmintype = fctx->type;
|
||||
dns_name_dup(&fctx->name, fctx->mctx, &fctx->qminname);
|
||||
result = dns_name_dup(&fctx->name, fctx->mctx, &fctx->qminname);
|
||||
fctx->minimized = false;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
||||
+19
-30
@@ -114,9 +114,9 @@ struct isc_httpd {
|
||||
* compressed HTTP data, if compression is used.
|
||||
*
|
||||
*/
|
||||
isc_bufferlist_t bufflist;
|
||||
isc_buffer_t headerbuffer;
|
||||
isc_buffer_t compbuffer;
|
||||
isc_buffer_t *sendbuffer;
|
||||
|
||||
const char *mimetype;
|
||||
unsigned int retcode;
|
||||
@@ -667,10 +667,9 @@ isc_httpd_accept(isc_task_t *task, isc_event_t *ev) {
|
||||
}
|
||||
isc_buffer_init(&httpd->headerbuffer, headerdata, HTTP_SENDGROW);
|
||||
|
||||
ISC_LIST_INIT(httpd->bufflist);
|
||||
|
||||
isc_buffer_initnull(&httpd->compbuffer);
|
||||
isc_buffer_initnull(&httpd->bodybuffer);
|
||||
httpd->sendbuffer = NULL;
|
||||
reset_client(httpd);
|
||||
|
||||
r.base = (unsigned char *)httpd->recvbuf;
|
||||
@@ -840,12 +839,13 @@ isc_httpd_compress(isc_httpd_t *httpd) {
|
||||
|
||||
static void
|
||||
isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
isc_httpd_t *httpd = ev->ev_arg;
|
||||
isc_socketevent_t *sev = (isc_socketevent_t *)ev;
|
||||
isc_buffer_t *databuffer;
|
||||
isc_httpdurl_t *url;
|
||||
isc_time_t now;
|
||||
isc_region_t r;
|
||||
bool is_compressed = false;
|
||||
char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
|
||||
|
||||
@@ -963,22 +963,24 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
|
||||
isc_httpd_endheaders(httpd); /* done */
|
||||
|
||||
ISC_LIST_APPEND(httpd->bufflist, &httpd->headerbuffer, link);
|
||||
/*
|
||||
* Link the data buffer into our send queue, should we have any data
|
||||
* rendered into it. If no data is present, we won't do anything
|
||||
* with the buffer.
|
||||
* Append either the compressed or the non-compressed response body to
|
||||
* the response headers and store the result in httpd->sendbuffer.
|
||||
*/
|
||||
if (is_compressed == true) {
|
||||
ISC_LIST_APPEND(httpd->bufflist, &httpd->compbuffer, link);
|
||||
} else {
|
||||
if (isc_buffer_length(&httpd->bodybuffer) > 0) {
|
||||
ISC_LIST_APPEND(httpd->bufflist, &httpd->bodybuffer, link);
|
||||
}
|
||||
}
|
||||
isc_buffer_dup(httpd->mgr->mctx,
|
||||
&httpd->sendbuffer, &httpd->headerbuffer);
|
||||
isc_buffer_setautorealloc(httpd->sendbuffer, true);
|
||||
databuffer = (is_compressed ? &httpd->compbuffer : &httpd->bodybuffer);
|
||||
isc_buffer_usedregion(databuffer, &r);
|
||||
result = isc_buffer_copyregion(httpd->sendbuffer, &r);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
/*
|
||||
* Determine total response size.
|
||||
*/
|
||||
isc_buffer_usedregion(httpd->sendbuffer, &r);
|
||||
|
||||
/* check return code? */
|
||||
(void)isc_socket_sendv(httpd->sock, &httpd->bufflist, task,
|
||||
(void)isc_socket_send(httpd->sock, &r, task,
|
||||
isc_httpd_senddone, httpd);
|
||||
|
||||
out:
|
||||
@@ -1126,13 +1128,7 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) {
|
||||
ENTER("senddone");
|
||||
INSIST(ISC_HTTPD_ISSEND(httpd));
|
||||
|
||||
/*
|
||||
* First, unlink our header buffer from the socket's bufflist. This
|
||||
* is sort of an evil hack, since we know our buffer will be there,
|
||||
* and we know it's address, so we can just remove it directly.
|
||||
*/
|
||||
NOTICE("senddone unlinked header");
|
||||
ISC_LIST_UNLINK(sev->bufferlist, &httpd->headerbuffer, link);
|
||||
isc_buffer_free(&httpd->sendbuffer);
|
||||
|
||||
/*
|
||||
* We will always want to clean up our receive buffer, even if we
|
||||
@@ -1149,13 +1145,6 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) {
|
||||
}
|
||||
NOTICE("senddone free callback performed");
|
||||
}
|
||||
if (ISC_LINK_LINKED(&httpd->bodybuffer, link)) {
|
||||
ISC_LIST_UNLINK(sev->bufferlist, &httpd->bodybuffer, link);
|
||||
NOTICE("senddone body buffer unlinked");
|
||||
} else if (ISC_LINK_LINKED(&httpd->compbuffer, link)) {
|
||||
ISC_LIST_UNLINK(sev->bufferlist, &httpd->compbuffer, link);
|
||||
NOTICE("senddone compressed data unlinked and freed");
|
||||
}
|
||||
|
||||
if (sev->result != ISC_R_SUCCESS) {
|
||||
destroy_client(&httpd);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/platform.h>
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
@@ -204,7 +204,6 @@ struct isc_socketevent {
|
||||
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 */
|
||||
@@ -244,8 +243,7 @@ typedef enum {
|
||||
isc_sockettype_udp = 1,
|
||||
isc_sockettype_tcp = 2,
|
||||
isc_sockettype_unix = 3,
|
||||
isc_sockettype_fdwatch = 4,
|
||||
isc_sockettype_raw = 5
|
||||
isc_sockettype_raw = 4
|
||||
} isc_sockettype_t;
|
||||
|
||||
/*@{*/
|
||||
@@ -276,14 +274,6 @@ typedef enum {
|
||||
#define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */
|
||||
/*@}*/
|
||||
|
||||
/*@{*/
|
||||
/*!
|
||||
* Flags for fdwatchcreate.
|
||||
*/
|
||||
#define ISC_SOCKFDWATCH_READ 0x00000001 /*%< watch for readable */
|
||||
#define ISC_SOCKFDWATCH_WRITE 0x00000002 /*%< watch for writable */
|
||||
/*@}*/
|
||||
|
||||
/*%
|
||||
* This structure is actually just the common prefix of a socket manager
|
||||
* object implementation's version of an isc_socketmgr_t.
|
||||
@@ -330,76 +320,6 @@ struct isc_socket {
|
||||
*** those functions which return an isc_result.
|
||||
***/
|
||||
|
||||
isc_result_t
|
||||
isc_socket_fdwatchcreate(isc_socketmgr_t *manager,
|
||||
int fd,
|
||||
int flags,
|
||||
isc_sockfdwatch_t callback,
|
||||
void *cbarg,
|
||||
isc_task_t *task,
|
||||
isc_socket_t **socketp);
|
||||
/*%<
|
||||
* Create a new file descriptor watch socket managed by 'manager'.
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
*\li 'fd' is the already-opened file descriptor (must be less
|
||||
* than maxsockets).
|
||||
*\li This function is not available on Windows.
|
||||
*\li The callback function is called "in-line" - this means the function
|
||||
* needs to return as fast as possible, as all other I/O will be suspended
|
||||
* until the callback completes.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'manager' is a valid manager
|
||||
*
|
||||
*\li 'socketp' is a valid pointer, and *socketp == NULL
|
||||
*
|
||||
*\li 'fd' be opened.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
* '*socketp' is attached to the newly created fdwatch socket
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*\li #ISC_R_NORESOURCES
|
||||
*\li #ISC_R_UNEXPECTED
|
||||
*\li #ISC_R_RANGE
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_socket_fdwatchpoke(isc_socket_t *sock,
|
||||
int flags);
|
||||
/*%<
|
||||
* Poke a file descriptor watch socket informing the manager that it
|
||||
* should restart watching the socket
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
*\li 'sock' is the socket returned by isc_socket_fdwatchcreate
|
||||
*
|
||||
*\li 'flags' indicates what the manager should watch for on the socket
|
||||
* in addition to what it may already be watching. It can be one or
|
||||
* both of ISC_SOCKFDWATCH_READ and ISC_SOCKFDWATCH_WRITE. To
|
||||
* temporarily disable watching on a socket the value indicating
|
||||
* no more data should be returned from the call back routine.
|
||||
*
|
||||
*\li This function is not available on Windows.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'sock' is a valid isc socket
|
||||
*
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_socket_create(isc_socketmgr_t *manager,
|
||||
int pf,
|
||||
@@ -408,9 +328,6 @@ isc_socket_create(isc_socketmgr_t *manager,
|
||||
/*%<
|
||||
* Create a new 'type' socket managed by 'manager'.
|
||||
*
|
||||
* For isc_sockettype_fdwatch sockets you should use isc_socket_fdwatchcreate()
|
||||
* rather than isc_socket_create().
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
*\li 'pf' is the desired protocol family, e.g. PF_INET or PF_INET6.
|
||||
@@ -421,8 +338,6 @@ isc_socket_create(isc_socketmgr_t *manager,
|
||||
*
|
||||
*\li 'socketp' is a valid pointer, and *socketp == NULL
|
||||
*
|
||||
*\li 'type' is not isc_sockettype_fdwatch
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
* '*socketp' is attached to the newly created socket
|
||||
@@ -552,17 +467,12 @@ isc_socket_open(isc_socket_t *sock);
|
||||
* one. This optimization may not be available for some systems, in which
|
||||
* case this function will return ISC_R_NOTIMPLEMENTED and must not be used.
|
||||
*
|
||||
* isc_socket_open() should not be called on sockets created by
|
||||
* isc_socket_fdwatchcreate().
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* \li there must be no other reference to this socket.
|
||||
*
|
||||
* \li 'socket' is a valid and previously closed by isc_socket_close()
|
||||
*
|
||||
* \li 'sock->type' is not isc_sockettype_fdwatch
|
||||
*
|
||||
* Returns:
|
||||
* Same as isc_socket_create().
|
||||
* \li ISC_R_NOTIMPLEMENTED
|
||||
@@ -578,9 +488,6 @@ isc_socket_close(isc_socket_t *sock);
|
||||
* systems, in which case this function will return ISC_R_NOTIMPLEMENTED and
|
||||
* must not be used.
|
||||
*
|
||||
* isc_socket_close() should not be called on sockets created by
|
||||
* isc_socket_fdwatchcreate().
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* \li The socket must have a valid descriptor.
|
||||
@@ -589,8 +496,6 @@ isc_socket_close(isc_socket_t *sock);
|
||||
*
|
||||
* \li There must be no pending I/O requests.
|
||||
*
|
||||
* \li 'sock->type' is not isc_sockettype_fdwatch
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_R_NOTIMPLEMENTED
|
||||
*/
|
||||
@@ -742,10 +647,6 @@ isc_result_t
|
||||
isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
|
||||
unsigned int minimum,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg);
|
||||
isc_result_t
|
||||
isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
unsigned int minimum,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg);
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
@@ -775,11 +676,6 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
* into this function, or any data they refer to until the completion
|
||||
* event is received.
|
||||
*
|
||||
*\li For isc_socket_recvv():
|
||||
* On successful completion, '*buflist' will be empty, and the list of
|
||||
* all buffers will be returned in the done event's 'bufferlist'
|
||||
* member. On error return, '*buflist' will be unchanged.
|
||||
*
|
||||
*\li For isc_socket_recv2():
|
||||
* 'event' is not NULL, and the non-socket specific fields are
|
||||
* expected to be initialized.
|
||||
@@ -834,18 +730,6 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
|
||||
isc_result_t
|
||||
isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg);
|
||||
isc_result_t
|
||||
isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
|
||||
isc_result_t
|
||||
isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
unsigned int flags);
|
||||
isc_result_t
|
||||
isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_task_t *task,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
@@ -866,11 +750,6 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
* into this function, or any data they refer to until the completion
|
||||
* event is received.
|
||||
*
|
||||
*\li For isc_socket_sendv() and isc_socket_sendtov():
|
||||
* On successful completion, '*buflist' will be empty, and the list of
|
||||
* all buffers will be returned in the done event's 'bufferlist'
|
||||
* member. On error return, '*buflist' will be unchanged.
|
||||
*
|
||||
*\li For isc_socket_sendto2():
|
||||
* 'event' is not NULL, and the non-socket specific fields are
|
||||
* expected to be initialized.
|
||||
@@ -934,7 +813,7 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
unsigned int maxsocks);
|
||||
unsigned int maxsocks, int nthreads);
|
||||
/*%<
|
||||
* Create a socket manager. If "maxsocks" is non-zero, it specifies the
|
||||
* maximum number of sockets that the created manager should handle.
|
||||
@@ -1131,6 +1010,12 @@ isc_socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
|
||||
* Test interface. Drop UDP packet > 'maxudp'.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc_socket_hasreuseport(void);
|
||||
/*%<
|
||||
* Return true if there is SO_REUSEPORT support
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
int
|
||||
isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
/*! \file isc/strerr.h */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(strerror_r)
|
||||
|
||||
@@ -208,8 +208,12 @@ isc_task_detach(isc_task_t **taskp);
|
||||
|
||||
void
|
||||
isc_task_send(isc_task_t *task, isc_event_t **eventp);
|
||||
|
||||
void
|
||||
isc_task_sendto(isc_task_t *task, isc_event_t **eventp, int c);
|
||||
/*%<
|
||||
* Send '*event' to 'task'.
|
||||
* Send '*event' to 'task', if task is idle try starting it on cpu 'c'
|
||||
* If 'c' is smaller than 0 then cpu is selected randomly.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
@@ -221,11 +225,15 @@ isc_task_send(isc_task_t *task, isc_event_t **eventp);
|
||||
*\li *eventp == NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_task_sendtoanddetach(isc_task_t **taskp, isc_event_t **eventp, int c);
|
||||
|
||||
void
|
||||
isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
|
||||
/*%<
|
||||
* Send '*event' to '*taskp' and then detach '*taskp' from its
|
||||
* task.
|
||||
* task. If task is idle try starting it on cpu 'c'
|
||||
* If 'c' is smaller than 0 then cpu is selected randomly.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
@@ -666,7 +674,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
*/
|
||||
|
||||
void
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode);
|
||||
isc_taskmgr_setprivilegedmode(isc_taskmgr_t *manager);
|
||||
|
||||
isc_taskmgrmode_t
|
||||
isc_taskmgr_mode(isc_taskmgr_t *manager);
|
||||
|
||||
@@ -44,6 +44,9 @@ isc_thread_yield(void);
|
||||
void
|
||||
isc_thread_setname(isc_thread_t thread, const char *name);
|
||||
|
||||
isc_result_t
|
||||
isc_thread_setaffinity(int cpu);
|
||||
|
||||
/* XXX We could do fancier error handling... */
|
||||
|
||||
#define isc_thread_join(t, rp) \
|
||||
|
||||
@@ -18,6 +18,17 @@
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CPUSET_H)
|
||||
#include <sys/param.h>
|
||||
#include <sys/cpuset.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_PROCSET_H)
|
||||
#include <sys/types.h>
|
||||
#include <sys/processor.h>
|
||||
#include <sys/procset.h>
|
||||
#endif
|
||||
|
||||
#include <isc/thread.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -91,3 +102,33 @@ isc_thread_yield(void) {
|
||||
pthread_yield_np();
|
||||
#endif
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_thread_setaffinity(int cpu) {
|
||||
#if defined(HAVE_CPUSET_SETAFFINITY)
|
||||
cpuset_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(cpu, &cpuset);
|
||||
if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
|
||||
sizeof(cpuset), &cpuset) != 0)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
#elif defined(HAVE_PTHREAD_SETAFFINITY_NP)
|
||||
cpu_set_t set;
|
||||
CPU_ZERO(&set);
|
||||
CPU_SET(cpu, &set);
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
|
||||
&set) != 0)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
#elif defined(HAVE_PROCESSOR_BIND)
|
||||
if (processor_bind(P_LWPID, P_MYID, cpu, NULL) != 0) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
#else
|
||||
UNUSED(cpu);
|
||||
#endif
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
+324
-209
@@ -21,6 +21,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/event.h>
|
||||
#include <isc/json.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/time.h>
|
||||
@@ -41,18 +43,14 @@
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
/*%
|
||||
* For BIND9 internal applications:
|
||||
* when built with threads we use multiple worker threads shared by the whole
|
||||
* application.
|
||||
* when built without threads we share a single global task manager and use
|
||||
* an integrated event loop for socket, timer, and other generic task events.
|
||||
* For generic library:
|
||||
* we don't use either of them: an application can have multiple task managers
|
||||
* whether or not it's threaded, and if the application is threaded each thread
|
||||
* is expected to have a separate manager; no "worker threads" are shared by
|
||||
* the application threads.
|
||||
/*
|
||||
* Task manager is built around 'as little locking as possible' concept.
|
||||
* Each thread has his own queue of tasks to be run, if a task is in running
|
||||
* state it will stay on the runner it's currently on, if a task is in idle
|
||||
* state it can be woken up on a specific runner with isc_task_sendto - that
|
||||
* helps with data locality on CPU.
|
||||
*/
|
||||
|
||||
#ifdef ISC_TASK_TRACE
|
||||
#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
|
||||
task, isc_thread_self(), (m))
|
||||
@@ -86,6 +84,7 @@ static const char *statenames[] = {
|
||||
|
||||
typedef struct isc__task isc__task_t;
|
||||
typedef struct isc__taskmgr isc__taskmgr_t;
|
||||
typedef struct isc__taskqueue isc__taskqueue_t;
|
||||
|
||||
struct isc__task {
|
||||
/* Not locked. */
|
||||
@@ -104,6 +103,7 @@ struct isc__task {
|
||||
isc_time_t tnow;
|
||||
char name[16];
|
||||
void * tag;
|
||||
unsigned int threadid;
|
||||
/* Locked by task manager lock. */
|
||||
LINK(isc__task_t) link;
|
||||
LINK(isc__task_t) ready_link;
|
||||
@@ -121,27 +121,40 @@ struct isc__task {
|
||||
|
||||
typedef ISC_LIST(isc__task_t) isc__tasklist_t;
|
||||
|
||||
struct isc__taskqueue {
|
||||
/* Everything locked by lock */
|
||||
isc_mutex_t lock;
|
||||
isc__tasklist_t ready_tasks;
|
||||
isc__tasklist_t ready_priority_tasks;
|
||||
isc_condition_t work_available;
|
||||
isc_thread_t thread;
|
||||
unsigned int threadid;
|
||||
isc__taskmgr_t *manager;
|
||||
};
|
||||
|
||||
struct isc__taskmgr {
|
||||
/* Not locked. */
|
||||
isc_taskmgr_t common;
|
||||
isc_mem_t * mctx;
|
||||
isc_mutex_t lock;
|
||||
isc_mutex_t halt_lock;
|
||||
isc_condition_t halt_cond;
|
||||
unsigned int workers;
|
||||
isc_thread_t * threads;
|
||||
atomic_uint_fast32_t tasks_running;
|
||||
atomic_uint_fast32_t tasks_ready;
|
||||
atomic_uint_fast32_t curq;
|
||||
isc__taskqueue_t *queues;
|
||||
|
||||
/* Locked by task manager lock. */
|
||||
unsigned int default_quantum;
|
||||
LIST(isc__task_t) tasks;
|
||||
isc__tasklist_t ready_tasks;
|
||||
isc__tasklist_t ready_priority_tasks;
|
||||
isc_taskmgrmode_t mode;
|
||||
isc_condition_t work_available;
|
||||
isc_condition_t exclusive_granted;
|
||||
isc_condition_t paused;
|
||||
unsigned int tasks_running;
|
||||
unsigned int tasks_ready;
|
||||
bool pause_requested;
|
||||
bool exclusive_requested;
|
||||
bool exiting;
|
||||
bool pause_requested;
|
||||
bool exclusive_requested;
|
||||
bool exiting;
|
||||
|
||||
/* Locked by halt_lock */
|
||||
unsigned int halted;
|
||||
|
||||
/*
|
||||
* Multiple threads can read/write 'excl' at the same time, so we need
|
||||
@@ -175,22 +188,33 @@ isc_taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0);
|
||||
isc_result_t
|
||||
isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp);
|
||||
static inline bool
|
||||
empty_readyq(isc__taskmgr_t *manager);
|
||||
empty_readyq(isc__taskmgr_t *manager, int c);
|
||||
|
||||
static inline isc__task_t *
|
||||
pop_readyq(isc__taskmgr_t *manager);
|
||||
pop_readyq(isc__taskmgr_t *manager, int c);
|
||||
|
||||
static inline void
|
||||
push_readyq(isc__taskmgr_t *manager, isc__task_t *task);
|
||||
push_readyq(isc__taskmgr_t *manager, isc__task_t *task, int c);
|
||||
|
||||
static inline void
|
||||
wake_all_queues(isc__taskmgr_t *manager);
|
||||
|
||||
/***
|
||||
*** Tasks.
|
||||
***/
|
||||
|
||||
static inline void
|
||||
wake_all_queues(isc__taskmgr_t *manager) {
|
||||
for (unsigned int i = 0; i < manager->workers; i++) {
|
||||
LOCK(&manager->queues[i].lock);
|
||||
BROADCAST(&manager->queues[i].work_available);
|
||||
UNLOCK(&manager->queues[i].lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
task_finished(isc__task_t *task) {
|
||||
isc__taskmgr_t *manager = task->manager;
|
||||
|
||||
REQUIRE(EMPTY(task->events));
|
||||
REQUIRE(task->nevents == 0);
|
||||
REQUIRE(EMPTY(task->on_shutdown));
|
||||
@@ -201,6 +225,7 @@ task_finished(isc__task_t *task) {
|
||||
|
||||
LOCK(&manager->lock);
|
||||
UNLINK(manager->tasks, task, link);
|
||||
UNLOCK(&manager->lock);
|
||||
if (FINISHED(manager)) {
|
||||
/*
|
||||
* All tasks have completed and the
|
||||
@@ -208,10 +233,8 @@ task_finished(isc__task_t *task) {
|
||||
* any idle worker threads so they
|
||||
* can exit.
|
||||
*/
|
||||
BROADCAST(&manager->work_available);
|
||||
wake_all_queues(manager);
|
||||
}
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
DESTROYLOCK(&task->lock);
|
||||
task->common.impmagic = 0;
|
||||
task->common.magic = 0;
|
||||
@@ -235,6 +258,9 @@ isc_task_create(isc_taskmgr_t *manager0, unsigned int quantum,
|
||||
return (ISC_R_NOMEMORY);
|
||||
XTRACE("isc_task_create");
|
||||
task->manager = manager;
|
||||
task->threadid = atomic_fetch_add_explicit(&manager->curq, 1,
|
||||
memory_order_relaxed)
|
||||
% manager->workers;
|
||||
result = isc_mutex_init(&task->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(manager->mctx, task, sizeof(*task));
|
||||
@@ -351,12 +377,12 @@ task_ready(isc__task_t *task) {
|
||||
REQUIRE(task->state == task_state_ready);
|
||||
|
||||
XTRACE("task_ready");
|
||||
|
||||
LOCK(&manager->lock);
|
||||
push_readyq(manager, task);
|
||||
if (manager->mode == isc_taskmgrmode_normal || has_privilege)
|
||||
SIGNAL(&manager->work_available);
|
||||
UNLOCK(&manager->lock);
|
||||
LOCK(&manager->queues[task->threadid].lock);
|
||||
push_readyq(manager, task, task->threadid);
|
||||
if (manager->mode == isc_taskmgrmode_normal || has_privilege) {
|
||||
SIGNAL(&manager->queues[task->threadid].work_available);
|
||||
}
|
||||
UNLOCK(&manager->queues[task->threadid].lock);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@@ -414,7 +440,7 @@ isc_task_detach(isc_task_t **taskp) {
|
||||
}
|
||||
|
||||
static inline bool
|
||||
task_send(isc__task_t *task, isc_event_t **eventp) {
|
||||
task_send(isc__task_t *task, isc_event_t **eventp, int c) {
|
||||
bool was_idle = false;
|
||||
isc_event_t *event;
|
||||
|
||||
@@ -433,6 +459,7 @@ task_send(isc__task_t *task, isc_event_t **eventp) {
|
||||
|
||||
if (task->state == task_state_idle) {
|
||||
was_idle = true;
|
||||
task->threadid = c;
|
||||
INSIST(EMPTY(task->events));
|
||||
task->state = task_state_ready;
|
||||
}
|
||||
@@ -447,6 +474,16 @@ task_send(isc__task_t *task, isc_event_t **eventp) {
|
||||
|
||||
void
|
||||
isc_task_send(isc_task_t *task0, isc_event_t **eventp) {
|
||||
isc_task_sendto(task0, eventp, -1);
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
|
||||
isc_task_sendtoanddetach(taskp, eventp, -1);
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_sendto(isc_task_t *task0, isc_event_t **eventp, int c) {
|
||||
isc__task_t *task = (isc__task_t *)task0;
|
||||
bool was_idle;
|
||||
|
||||
@@ -455,16 +492,21 @@ isc_task_send(isc_task_t *task0, isc_event_t **eventp) {
|
||||
*/
|
||||
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
XTRACE("isc_task_send");
|
||||
|
||||
if (c < 0) {
|
||||
c = atomic_fetch_add_explicit(&task->manager->curq, 1,
|
||||
memory_order_relaxed);
|
||||
}
|
||||
c %= task->manager->workers;
|
||||
|
||||
/*
|
||||
* We're trying hard to hold locks for as short a time as possible.
|
||||
* We're also trying to hold as few locks as possible. This is why
|
||||
* some processing is deferred until after the lock is released.
|
||||
*/
|
||||
LOCK(&task->lock);
|
||||
was_idle = task_send(task, eventp);
|
||||
was_idle = task_send(task, eventp, c);
|
||||
UNLOCK(&task->lock);
|
||||
|
||||
if (was_idle) {
|
||||
@@ -488,7 +530,7 @@ isc_task_send(isc_task_t *task0, isc_event_t **eventp) {
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
|
||||
isc_task_sendtoanddetach(isc_task_t **taskp, isc_event_t **eventp, int c) {
|
||||
bool idle1, idle2;
|
||||
isc__task_t *task;
|
||||
|
||||
@@ -500,11 +542,16 @@ isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
|
||||
REQUIRE(taskp != NULL);
|
||||
task = (isc__task_t *)*taskp;
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
XTRACE("isc_task_sendanddetach");
|
||||
|
||||
if (c < 0) {
|
||||
c = atomic_fetch_add_explicit(&task->manager->curq, 1,
|
||||
memory_order_relaxed);
|
||||
}
|
||||
c %= task->manager->workers;
|
||||
|
||||
LOCK(&task->lock);
|
||||
idle1 = task_send(task, eventp);
|
||||
idle1 = task_send(task, eventp, c);
|
||||
idle2 = task_detach(task);
|
||||
UNLOCK(&task->lock);
|
||||
|
||||
@@ -829,13 +876,13 @@ isc_task_getcurrenttimex(isc_task_t *task0, isc_time_t *t) {
|
||||
* Caller must hold the task manager lock.
|
||||
*/
|
||||
static inline bool
|
||||
empty_readyq(isc__taskmgr_t *manager) {
|
||||
empty_readyq(isc__taskmgr_t *manager, int c) {
|
||||
isc__tasklist_t queue;
|
||||
|
||||
if (manager->mode == isc_taskmgrmode_normal)
|
||||
queue = manager->ready_tasks;
|
||||
queue = manager->queues[c].ready_tasks;
|
||||
else
|
||||
queue = manager->ready_priority_tasks;
|
||||
queue = manager->queues[c].ready_priority_tasks;
|
||||
|
||||
return (EMPTY(queue));
|
||||
}
|
||||
@@ -849,19 +896,21 @@ empty_readyq(isc__taskmgr_t *manager) {
|
||||
* Caller must hold the task manager lock.
|
||||
*/
|
||||
static inline isc__task_t *
|
||||
pop_readyq(isc__taskmgr_t *manager) {
|
||||
pop_readyq(isc__taskmgr_t *manager, int c) {
|
||||
isc__task_t *task;
|
||||
|
||||
if (manager->mode == isc_taskmgrmode_normal)
|
||||
task = HEAD(manager->ready_tasks);
|
||||
else
|
||||
task = HEAD(manager->ready_priority_tasks);
|
||||
if (manager->mode == isc_taskmgrmode_normal) {
|
||||
task = HEAD(manager->queues[c].ready_tasks);
|
||||
} else {
|
||||
task = HEAD(manager->queues[c].ready_priority_tasks);
|
||||
}
|
||||
|
||||
if (task != NULL) {
|
||||
DEQUEUE(manager->ready_tasks, task, ready_link);
|
||||
if (ISC_LINK_LINKED(task, ready_priority_link))
|
||||
DEQUEUE(manager->ready_priority_tasks, task,
|
||||
DEQUEUE(manager->queues[c].ready_tasks, task, ready_link);
|
||||
if (ISC_LINK_LINKED(task, ready_priority_link)) {
|
||||
DEQUEUE(manager->queues[c].ready_priority_tasks, task,
|
||||
ready_priority_link);
|
||||
}
|
||||
}
|
||||
|
||||
return (task);
|
||||
@@ -874,20 +923,26 @@ pop_readyq(isc__taskmgr_t *manager) {
|
||||
* Caller must hold the task manager lock.
|
||||
*/
|
||||
static inline void
|
||||
push_readyq(isc__taskmgr_t *manager, isc__task_t *task) {
|
||||
ENQUEUE(manager->ready_tasks, task, ready_link);
|
||||
if ((task->flags & TASK_F_PRIVILEGED) != 0)
|
||||
ENQUEUE(manager->ready_priority_tasks, task,
|
||||
push_readyq(isc__taskmgr_t *manager, isc__task_t *task, int c) {
|
||||
ENQUEUE(manager->queues[c].ready_tasks, task, ready_link);
|
||||
if ((task->flags & TASK_F_PRIVILEGED) != 0) {
|
||||
ENQUEUE(manager->queues[c].ready_priority_tasks, task,
|
||||
ready_priority_link);
|
||||
manager->tasks_ready++;
|
||||
}
|
||||
atomic_fetch_add_explicit(&manager->tasks_ready, 1,
|
||||
memory_order_acquire);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatch(isc__taskmgr_t *manager) {
|
||||
dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
isc__task_t *task;
|
||||
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
/* Wait for everything to initialize */
|
||||
LOCK(&manager->lock);
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
/*
|
||||
* Again we're trying to hold the lock for as short a time as possible
|
||||
* and to do as little locking and unlocking as possible.
|
||||
@@ -937,8 +992,7 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
* For N iterations of the loop, this code does N+1 locks and N+1
|
||||
* unlocks. The while expression is always protected by the lock.
|
||||
*/
|
||||
|
||||
LOCK(&manager->lock);
|
||||
LOCK(&manager->queues[threadid].lock);
|
||||
|
||||
while (!FINISHED(manager)) {
|
||||
/*
|
||||
@@ -951,13 +1005,26 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
* If a pause has been requested, don't do any work
|
||||
* until it's been released.
|
||||
*/
|
||||
while ((empty_readyq(manager) || manager->pause_requested ||
|
||||
manager->exclusive_requested) && !FINISHED(manager))
|
||||
while ((empty_readyq(manager, threadid) &&
|
||||
!manager->pause_requested &&
|
||||
!manager->exclusive_requested) &&
|
||||
!FINISHED(manager))
|
||||
{
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_WAIT, "wait"));
|
||||
WAIT(&manager->work_available, &manager->lock);
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_WAIT,
|
||||
manager->pause_requested
|
||||
? "paused" : "notpaused"));
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_WAIT,
|
||||
manager->exclusive_requested
|
||||
? "excreq" : "notexcreq"));
|
||||
WAIT(&manager->queues[threadid].work_available,
|
||||
&manager->queues[threadid].lock);
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_TASK,
|
||||
ISC_MSG_AWAKE, "awake"));
|
||||
@@ -965,7 +1032,42 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
|
||||
ISC_MSG_WORKING, "working"));
|
||||
|
||||
task = pop_readyq(manager);
|
||||
if (manager->pause_requested || manager->exclusive_requested) {
|
||||
UNLOCK(&manager->queues[threadid].lock);
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
|
||||
ISC_MSG_WORKING, "halting"));
|
||||
|
||||
/*
|
||||
* Switching to exclusive mode is done as a
|
||||
* 2-phase-lock, checking if we have to switch is
|
||||
* done without any locks on pause_requested and
|
||||
* exclusive_requested to save time - the worst
|
||||
* thing that can happen is that we'll launch one
|
||||
* task more and exclusive task will be postponed a
|
||||
* bit.
|
||||
*
|
||||
* Broadcasting on halt_cond seems suboptimal, but
|
||||
* exclusive tasks are rare enought that we don't
|
||||
* care.
|
||||
*/
|
||||
LOCK(&manager->halt_lock);
|
||||
manager->halted++;
|
||||
BROADCAST(&manager->halt_cond);
|
||||
while (manager->pause_requested ||
|
||||
manager->exclusive_requested)
|
||||
{
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
}
|
||||
manager->halted--;
|
||||
SIGNAL(&manager->halt_cond);
|
||||
UNLOCK(&manager->halt_lock);
|
||||
|
||||
LOCK(&manager->queues[threadid].lock);
|
||||
/* Restart the loop after */
|
||||
continue;
|
||||
}
|
||||
|
||||
task = pop_readyq(manager, threadid);
|
||||
if (task != NULL) {
|
||||
unsigned int dispatch_count = 0;
|
||||
bool done = false;
|
||||
@@ -976,19 +1078,23 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
INSIST(VALID_TASK(task));
|
||||
|
||||
/*
|
||||
* Note we only unlock the manager lock if we actually
|
||||
* have a task to do. We must reacquire the manager
|
||||
* Note we only unlock the queue lock if we actually
|
||||
* have a task to do. We must reacquire the queue
|
||||
* lock before exiting the 'if (task != NULL)' block.
|
||||
*/
|
||||
manager->tasks_ready--;
|
||||
manager->tasks_running++;
|
||||
UNLOCK(&manager->lock);
|
||||
UNLOCK(&manager->queues[threadid].lock);
|
||||
RUNTIME_CHECK(
|
||||
atomic_fetch_sub_explicit(&manager->tasks_ready,
|
||||
1, memory_order_release) > 0);
|
||||
atomic_fetch_add_explicit(&manager->tasks_running, 1,
|
||||
memory_order_acquire);
|
||||
|
||||
LOCK(&task->lock);
|
||||
INSIST(task->state == task_state_ready);
|
||||
task->state = task_state_running;
|
||||
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_RUNNING, "running"));
|
||||
XTRACE(task->name);
|
||||
TIME_NOW(&task->tnow);
|
||||
task->now = isc_time_seconds(&task->tnow);
|
||||
do {
|
||||
@@ -1004,6 +1110,7 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
ISC_MSGSET_TASK,
|
||||
ISC_MSG_EXECUTE,
|
||||
"execute action"));
|
||||
XTRACE(task->name);
|
||||
if (event->ev_action != NULL) {
|
||||
UNLOCK(&task->lock);
|
||||
(event->ev_action)(
|
||||
@@ -1094,15 +1201,10 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
if (finished)
|
||||
task_finished(task);
|
||||
|
||||
LOCK(&manager->lock);
|
||||
manager->tasks_running--;
|
||||
if (manager->exclusive_requested &&
|
||||
manager->tasks_running == 1) {
|
||||
SIGNAL(&manager->exclusive_granted);
|
||||
} else if (manager->pause_requested &&
|
||||
manager->tasks_running == 0) {
|
||||
SIGNAL(&manager->paused);
|
||||
}
|
||||
RUNTIME_CHECK(
|
||||
atomic_fetch_sub_explicit(&manager->tasks_running,
|
||||
1, memory_order_release) > 0);
|
||||
LOCK(&manager->queues[threadid].lock);
|
||||
if (requeue) {
|
||||
/*
|
||||
* We know we're awake, so we don't have
|
||||
@@ -1123,7 +1225,7 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
* were usually nonempty, the 'optimization'
|
||||
* might even hurt rather than help.
|
||||
*/
|
||||
push_readyq(manager, task);
|
||||
push_readyq(manager, task, threadid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1133,27 +1235,62 @@ dispatch(isc__taskmgr_t *manager) {
|
||||
* we're stuck. Automatically drop privileges at that
|
||||
* point and continue with the regular ready queue.
|
||||
*/
|
||||
if (manager->tasks_running == 0 && empty_readyq(manager)) {
|
||||
manager->mode = isc_taskmgrmode_normal;
|
||||
if (!empty_readyq(manager))
|
||||
BROADCAST(&manager->work_available);
|
||||
if (manager->mode != isc_taskmgrmode_normal &&
|
||||
atomic_load_explicit(&manager->tasks_running,
|
||||
memory_order_acquire) == 0)
|
||||
{
|
||||
UNLOCK(&manager->queues[threadid].lock);
|
||||
LOCK(&manager->lock);
|
||||
/*
|
||||
* Check once again, under lock. Mode can only
|
||||
* change from privileged to normal anyway, and
|
||||
* if we enter this loop twice at the same time
|
||||
* we'll end up in a deadlock over queue locks.
|
||||
*
|
||||
*/
|
||||
if (manager->mode != isc_taskmgrmode_normal &&
|
||||
atomic_load_explicit(&manager->tasks_running,
|
||||
memory_order_acquire) == 0)
|
||||
{
|
||||
bool empty = true;
|
||||
unsigned int i;
|
||||
for (i = 0; i < manager->workers && empty; i++)
|
||||
{
|
||||
LOCK(&manager->queues[i].lock);
|
||||
empty &= empty_readyq(manager, i);
|
||||
UNLOCK(&manager->queues[i].lock);
|
||||
}
|
||||
if (empty) {
|
||||
manager->mode = isc_taskmgrmode_normal;
|
||||
wake_all_queues(manager);
|
||||
}
|
||||
}
|
||||
UNLOCK(&manager->lock);
|
||||
LOCK(&manager->queues[threadid].lock);
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK(&manager->lock);
|
||||
UNLOCK(&manager->queues[threadid].lock);
|
||||
/*
|
||||
* There might be other dispatchers waiting on empty tasks,
|
||||
* wake them up.
|
||||
*/
|
||||
wake_all_queues(manager);
|
||||
}
|
||||
|
||||
static isc_threadresult_t
|
||||
#ifdef _WIN32
|
||||
WINAPI
|
||||
#endif
|
||||
run(void *uap) {
|
||||
isc__taskmgr_t *manager = uap;
|
||||
run(void *queuep) {
|
||||
isc__taskqueue_t *tq = queuep;
|
||||
isc__taskmgr_t *manager = tq->manager;
|
||||
int threadid = tq->threadid;
|
||||
isc_thread_setaffinity(threadid);
|
||||
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_STARTING, "starting"));
|
||||
|
||||
dispatch(manager);
|
||||
dispatch(manager, threadid);
|
||||
|
||||
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_EXITING, "exiting"));
|
||||
@@ -1167,27 +1304,23 @@ run(void *uap) {
|
||||
|
||||
static void
|
||||
manager_free(isc__taskmgr_t *manager) {
|
||||
isc_mem_t *mctx;
|
||||
|
||||
(void)isc_condition_destroy(&manager->exclusive_granted);
|
||||
(void)isc_condition_destroy(&manager->work_available);
|
||||
(void)isc_condition_destroy(&manager->paused);
|
||||
isc_mem_free(manager->mctx, manager->threads);
|
||||
for (unsigned int i = 0; i < manager->workers; i++) {
|
||||
DESTROYLOCK(&manager->queues[i].lock);
|
||||
}
|
||||
DESTROYLOCK(&manager->lock);
|
||||
DESTROYLOCK(&manager->excl_lock);
|
||||
DESTROYLOCK(&manager->halt_lock);
|
||||
isc_mem_put(manager->mctx, manager->queues,
|
||||
manager->workers * sizeof(isc__taskqueue_t));
|
||||
manager->common.impmagic = 0;
|
||||
manager->common.magic = 0;
|
||||
mctx = manager->mctx;
|
||||
isc_mem_put(mctx, manager, sizeof(*manager));
|
||||
isc_mem_detach(&mctx);
|
||||
isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
unsigned int default_quantum, isc_taskmgr_t **managerp)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned int i, started = 0;
|
||||
unsigned int i;
|
||||
isc__taskmgr_t *manager;
|
||||
|
||||
/*
|
||||
@@ -1198,64 +1331,35 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
REQUIRE(managerp != NULL && *managerp == NULL);
|
||||
|
||||
manager = isc_mem_get(mctx, sizeof(*manager));
|
||||
if (manager == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
RUNTIME_CHECK(manager != NULL);
|
||||
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
||||
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
||||
manager->mode = isc_taskmgrmode_normal;
|
||||
manager->mctx = NULL;
|
||||
result = isc_mutex_init(&manager->lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_mgr;
|
||||
result = isc_mutex_init(&manager->excl_lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
DESTROYLOCK(&manager->lock);
|
||||
goto cleanup_mgr;
|
||||
}
|
||||
RUNTIME_CHECK(isc_mutex_init(&manager->lock) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_init(&manager->excl_lock) == ISC_R_SUCCESS);
|
||||
|
||||
manager->workers = 0;
|
||||
manager->threads = isc_mem_allocate(mctx,
|
||||
workers * sizeof(isc_thread_t));
|
||||
if (manager->threads == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto cleanup_lock;
|
||||
}
|
||||
if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_condition_init() %s",
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED, "failed"));
|
||||
result = ISC_R_UNEXPECTED;
|
||||
goto cleanup_threads;
|
||||
}
|
||||
if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_condition_init() %s",
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED, "failed"));
|
||||
result = ISC_R_UNEXPECTED;
|
||||
goto cleanup_workavailable;
|
||||
}
|
||||
if (isc_condition_init(&manager->paused) != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_condition_init() %s",
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED, "failed"));
|
||||
result = ISC_R_UNEXPECTED;
|
||||
goto cleanup_exclusivegranted;
|
||||
}
|
||||
if (default_quantum == 0)
|
||||
RUNTIME_CHECK(isc_mutex_init(&manager->halt_lock) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_condition_init(&manager->halt_cond) == ISC_R_SUCCESS);
|
||||
|
||||
manager->workers = workers;
|
||||
|
||||
if (default_quantum == 0) {
|
||||
default_quantum = DEFAULT_DEFAULT_QUANTUM;
|
||||
}
|
||||
manager->default_quantum = default_quantum;
|
||||
INIT_LIST(manager->tasks);
|
||||
INIT_LIST(manager->ready_tasks);
|
||||
INIT_LIST(manager->ready_priority_tasks);
|
||||
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
|
||||
RUNTIME_CHECK(manager->queues != NULL);
|
||||
|
||||
manager->tasks_running = 0;
|
||||
manager->tasks_ready = 0;
|
||||
manager->exclusive_requested = false;
|
||||
manager->pause_requested = false;
|
||||
manager->curq = 0;
|
||||
manager->exiting = false;
|
||||
manager->excl = NULL;
|
||||
manager->halted = 0;
|
||||
manager->exclusive_requested = false;
|
||||
manager->pause_requested = false;
|
||||
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
|
||||
@@ -1264,40 +1368,29 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
* Start workers.
|
||||
*/
|
||||
for (i = 0; i < workers; i++) {
|
||||
if (isc_thread_create(run, manager,
|
||||
&manager->threads[manager->workers]) ==
|
||||
ISC_R_SUCCESS) {
|
||||
char name[16]; /* thread name limit on Linux */
|
||||
snprintf(name, sizeof(name), "isc-worker%04u", i);
|
||||
isc_thread_setname(manager->threads[manager->workers],
|
||||
name);
|
||||
manager->workers++;
|
||||
started++;
|
||||
}
|
||||
INIT_LIST(manager->queues[i].ready_tasks);
|
||||
INIT_LIST(manager->queues[i].ready_priority_tasks);
|
||||
RUNTIME_CHECK(isc_mutex_init(&manager->queues[i].lock)
|
||||
== ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_condition_init(
|
||||
&manager->queues[i].work_available)
|
||||
== ISC_R_SUCCESS);
|
||||
manager->queues[i].manager = manager;
|
||||
manager->queues[i].threadid = i;
|
||||
RUNTIME_CHECK(isc_thread_create(run, &manager->queues[i],
|
||||
&manager->queues[i].thread)
|
||||
== ISC_R_SUCCESS);
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "isc-worker%04u", i);
|
||||
isc_thread_setname(manager->queues[i].thread, name);
|
||||
}
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
if (started == 0) {
|
||||
manager_free(manager);
|
||||
return (ISC_R_NOTHREADS);
|
||||
}
|
||||
isc_thread_setconcurrency(workers);
|
||||
|
||||
*managerp = (isc_taskmgr_t *)manager;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_exclusivegranted:
|
||||
(void)isc_condition_destroy(&manager->exclusive_granted);
|
||||
cleanup_workavailable:
|
||||
(void)isc_condition_destroy(&manager->work_available);
|
||||
cleanup_threads:
|
||||
isc_mem_free(mctx, manager->threads);
|
||||
cleanup_lock:
|
||||
DESTROYLOCK(&manager->lock);
|
||||
cleanup_mgr:
|
||||
isc_mem_put(mctx, manager, sizeof(*manager));
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1355,29 +1448,34 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
|
||||
|
||||
/*
|
||||
* Post shutdown event(s) to every task (if they haven't already been
|
||||
* posted).
|
||||
* posted). To make things easier post idle tasks to worker 0.
|
||||
*/
|
||||
LOCK(&manager->queues[0].lock);
|
||||
for (task = HEAD(manager->tasks);
|
||||
task != NULL;
|
||||
task = NEXT(task, link)) {
|
||||
LOCK(&task->lock);
|
||||
if (task_shutdown(task))
|
||||
push_readyq(manager, task);
|
||||
if (task_shutdown(task)) {
|
||||
task->threadid = 0;
|
||||
push_readyq(manager, task, 0);
|
||||
}
|
||||
UNLOCK(&task->lock);
|
||||
}
|
||||
UNLOCK(&manager->queues[0].lock);
|
||||
|
||||
/*
|
||||
* Wake up any sleeping workers. This ensures we get work done if
|
||||
* there's work left to do, and if there are already no tasks left
|
||||
* it will cause the workers to see manager->exiting.
|
||||
*/
|
||||
BROADCAST(&manager->work_available);
|
||||
wake_all_queues(manager);
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
/*
|
||||
* Wait for all the worker threads to exit.
|
||||
*/
|
||||
for (i = 0; i < manager->workers; i++)
|
||||
(void)isc_thread_join(manager->threads[i], NULL);
|
||||
(void)isc_thread_join(manager->queues[i].thread, NULL);
|
||||
|
||||
manager_free(manager);
|
||||
|
||||
@@ -1385,11 +1483,11 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
|
||||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode) {
|
||||
isc_taskmgr_setprivilegedmode(isc_taskmgr_t *manager0) {
|
||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||
|
||||
LOCK(&manager->lock);
|
||||
manager->mode = mode;
|
||||
manager->mode = isc_taskmgrmode_privileged;
|
||||
UNLOCK(&manager->lock);
|
||||
}
|
||||
|
||||
@@ -1406,24 +1504,35 @@ isc_taskmgr_mode(isc_taskmgr_t *manager0) {
|
||||
void
|
||||
isc__taskmgr_pause(isc_taskmgr_t *manager0) {
|
||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||
manager->pause_requested = true;
|
||||
LOCK(&manager->lock);
|
||||
while (manager->tasks_running > 0) {
|
||||
WAIT(&manager->paused, &manager->lock);
|
||||
|
||||
LOCK(&manager->halt_lock);
|
||||
while (manager->exclusive_requested || manager->pause_requested) {
|
||||
UNLOCK(&manager->halt_lock);
|
||||
/* This is ugly but pause is used EXCLUSIVELY in tests */
|
||||
isc_thread_yield();
|
||||
LOCK(&manager->halt_lock);
|
||||
}
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
manager->pause_requested = true;
|
||||
while (manager->halted < manager->workers) {
|
||||
wake_all_queues(manager);
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
}
|
||||
UNLOCK(&manager->halt_lock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||
|
||||
LOCK(&manager->lock);
|
||||
LOCK(&manager->halt_lock);
|
||||
if (manager->pause_requested) {
|
||||
manager->pause_requested = false;
|
||||
BROADCAST(&manager->work_available);
|
||||
while (manager->halted > 0) {
|
||||
BROADCAST(&manager->halt_cond);
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
}
|
||||
}
|
||||
UNLOCK(&manager->lock);
|
||||
UNLOCK(&manager->halt_lock);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1462,24 +1571,25 @@ isc_result_t
|
||||
isc_task_beginexclusive(isc_task_t *task0) {
|
||||
isc__task_t *task = (isc__task_t *)task0;
|
||||
isc__taskmgr_t *manager = task->manager;
|
||||
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
REQUIRE(task->state == task_state_running);
|
||||
/*
|
||||
* TODO REQUIRE(task == task->manager->excl);
|
||||
* it should be here, it fails on shutdown server->task
|
||||
*/
|
||||
REQUIRE(task == task->manager->excl ||
|
||||
(task->manager->exiting && task->manager->excl == NULL));
|
||||
|
||||
LOCK(&manager->lock);
|
||||
if (manager->exclusive_requested) {
|
||||
UNLOCK(&manager->lock);
|
||||
if (manager->exclusive_requested || manager->pause_requested) {
|
||||
return (ISC_R_LOCKBUSY);
|
||||
}
|
||||
|
||||
LOCK(&manager->halt_lock);
|
||||
INSIST(!manager->exclusive_requested && !manager->pause_requested);
|
||||
manager->exclusive_requested = true;
|
||||
while (manager->tasks_running > 1) {
|
||||
WAIT(&manager->exclusive_granted, &manager->lock);
|
||||
while (manager->halted + 1 < manager->workers) {
|
||||
wake_all_queues(manager);
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
}
|
||||
UNLOCK(&manager->lock);
|
||||
UNLOCK(&manager->halt_lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -1490,11 +1600,14 @@ isc_task_endexclusive(isc_task_t *task0) {
|
||||
|
||||
REQUIRE(VALID_TASK(task));
|
||||
REQUIRE(task->state == task_state_running);
|
||||
LOCK(&manager->lock);
|
||||
LOCK(&manager->halt_lock);
|
||||
REQUIRE(manager->exclusive_requested);
|
||||
manager->exclusive_requested = false;
|
||||
BROADCAST(&manager->work_available);
|
||||
UNLOCK(&manager->lock);
|
||||
while (manager->halted > 0) {
|
||||
BROADCAST(&manager->halt_cond);
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
}
|
||||
UNLOCK(&manager->halt_lock);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1515,14 +1628,14 @@ isc_task_setprivilege(isc_task_t *task0, bool priv) {
|
||||
if (priv == oldpriv)
|
||||
return;
|
||||
|
||||
LOCK(&manager->lock);
|
||||
LOCK(&manager->queues[task->threadid].lock);
|
||||
if (priv && ISC_LINK_LINKED(task, ready_link))
|
||||
ENQUEUE(manager->ready_priority_tasks, task,
|
||||
ready_priority_link);
|
||||
ENQUEUE(manager->queues[task->threadid].ready_priority_tasks,
|
||||
task, ready_priority_link);
|
||||
else if (!priv && ISC_LINK_LINKED(task, ready_priority_link))
|
||||
DEQUEUE(manager->ready_priority_tasks, task,
|
||||
ready_priority_link);
|
||||
UNLOCK(&manager->lock);
|
||||
DEQUEUE(manager->queues[task->threadid].ready_priority_tasks,
|
||||
task, ready_priority_link);
|
||||
UNLOCK(&manager->queues[task->threadid].lock);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1575,11 +1688,13 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||
(int) mgr->tasks_running));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_ready));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||
(int) mgr->tasks_ready));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-ready */
|
||||
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* thread-model */
|
||||
|
||||
@@ -67,7 +67,6 @@ set_and_drop(isc_task_t *task, isc_event_t *event) {
|
||||
*value = (int) isc_taskmgr_mode(taskmgr);
|
||||
counter++;
|
||||
UNLOCK(&lock);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_normal);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -230,7 +229,7 @@ ATF_TC_BODY(privileged_events, tc) {
|
||||
isc_task_send(task2, &event);
|
||||
|
||||
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
isc_taskmgr_setprivilegedmode(taskmgr);
|
||||
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
|
||||
|
||||
isc__taskmgr_resume(taskmgr);
|
||||
@@ -351,7 +350,7 @@ ATF_TC_BODY(privilege_drop, tc) {
|
||||
isc_task_send(task2, &event);
|
||||
|
||||
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
isc_taskmgr_setprivilegedmode(taskmgr);
|
||||
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
|
||||
|
||||
isc__taskmgr_resume(taskmgr);
|
||||
@@ -363,14 +362,12 @@ ATF_TC_BODY(privilege_drop, tc) {
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't guarantee what order the events fire, but
|
||||
* we do know *exactly one* of the privileged tasks will
|
||||
* have run in privileged mode...
|
||||
* We need to check that all privilege mode events were fired
|
||||
* in privileged mode, and non privileged in non-privileged.
|
||||
*/
|
||||
ATF_CHECK(a == isc_taskmgrmode_privileged ||
|
||||
c == isc_taskmgrmode_privileged ||
|
||||
ATF_CHECK(a == isc_taskmgrmode_privileged &&
|
||||
c == isc_taskmgrmode_privileged &&
|
||||
d == isc_taskmgrmode_privileged);
|
||||
ATF_CHECK(a + c + d == isc_taskmgrmode_privileged);
|
||||
|
||||
/* ...and neither of the non-privileged tasks did... */
|
||||
ATF_CHECK(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal);
|
||||
|
||||
+820
-1380
File diff suppressed because it is too large
Load Diff
@@ -79,6 +79,9 @@ isc_thread_setconcurrency(unsigned int level);
|
||||
void
|
||||
isc_thread_setname(isc_thread_t, const char *);
|
||||
|
||||
isc_result_t
|
||||
isc_thread_setaffinity(int cpu);
|
||||
|
||||
int
|
||||
isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *));
|
||||
|
||||
|
||||
@@ -78,19 +78,16 @@ isc_socket_getpeername
|
||||
isc_socket_getsockname
|
||||
isc_socket_gettag
|
||||
isc_socket_gettype
|
||||
isc_socket_hasreuseport
|
||||
isc_socket_ipv6only
|
||||
isc_socket_listen
|
||||
isc_socket_open
|
||||
isc_socket_permunix
|
||||
isc_socket_recv
|
||||
isc_socket_recv2
|
||||
isc_socket_recvv
|
||||
isc_socket_send
|
||||
isc_socket_sendto
|
||||
isc_socket_sendto2
|
||||
isc_socket_sendtov
|
||||
isc_socket_sendtov2
|
||||
isc_socket_sendv
|
||||
isc_socket_setname
|
||||
isc_socketmgr_create
|
||||
isc_socketmgr_create2
|
||||
@@ -584,6 +581,8 @@ isc_task_purgeevent
|
||||
isc_task_purgerange
|
||||
isc_task_send
|
||||
isc_task_sendanddetach
|
||||
isc_task_sendto
|
||||
isc_task_sendtoanddetach
|
||||
isc_task_setname
|
||||
isc_task_setprivilege
|
||||
isc_task_shutdown
|
||||
@@ -600,7 +599,7 @@ isc_taskmgr_renderjson
|
||||
isc_taskmgr_renderxml
|
||||
@END LIBXML2
|
||||
isc_taskmgr_setexcltask
|
||||
isc_taskmgr_setmode
|
||||
isc_taskmgr_setprivilegedmode
|
||||
isc_taskpool_create
|
||||
isc_taskpool_destroy
|
||||
isc_taskpool_expand
|
||||
@@ -613,6 +612,7 @@ isc_thread_key_create
|
||||
isc_thread_key_delete
|
||||
isc_thread_key_getspecific
|
||||
isc_thread_key_setspecific
|
||||
isc_thread_setaffinity
|
||||
isc_thread_setconcurrency
|
||||
isc_thread_setname
|
||||
isc_time_add
|
||||
|
||||
+40
-288
@@ -47,7 +47,6 @@
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/bufferlist.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/list.h>
|
||||
#include <isc/log.h>
|
||||
@@ -271,16 +270,6 @@ struct isc_socket {
|
||||
|
||||
#define _set_state(sock, _state) do { (sock)->state = (_state); (sock)->state_lineno = __LINE__; } while (0)
|
||||
|
||||
/*
|
||||
* Buffer structure
|
||||
*/
|
||||
typedef struct buflist buflist_t;
|
||||
|
||||
struct buflist {
|
||||
void *buf;
|
||||
unsigned int buflen;
|
||||
ISC_LINK(buflist_t) link;
|
||||
};
|
||||
|
||||
/*
|
||||
* I/O Completion ports Info structures
|
||||
@@ -296,7 +285,8 @@ typedef struct IoCompletionInfo {
|
||||
DWORD received_bytes;
|
||||
int request_type;
|
||||
struct msghdr messagehdr;
|
||||
ISC_LIST(buflist_t) bufferlist; /*%< list of buffers */
|
||||
void *buf;
|
||||
unsigned int buflen;
|
||||
} IoCompletionInfo;
|
||||
|
||||
/*
|
||||
@@ -518,8 +508,6 @@ iocompletionport_init(isc_socketmgr_t *manager) {
|
||||
strbuf);
|
||||
}
|
||||
|
||||
manager->maxIOCPThreads = min(isc_os_ncpus() + 1, MAX_IOCPTHREADS);
|
||||
|
||||
/* Now Create the Completion Port */
|
||||
manager->hIoCompletionPort = CreateIoCompletionPort(
|
||||
INVALID_HANDLE_VALUE, NULL,
|
||||
@@ -950,91 +938,33 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
IoCompletionInfo *lpo)
|
||||
{
|
||||
unsigned int iovcount;
|
||||
isc_buffer_t *buffer;
|
||||
buflist_t *cpbuffer;
|
||||
isc_region_t used;
|
||||
size_t write_count;
|
||||
size_t skip_count;
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
|
||||
memmove(&msg->to_addr, &dev->address.type, dev->address.length);
|
||||
msg->to_addr_len = dev->address.length;
|
||||
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
write_count = 0;
|
||||
iovcount = 0;
|
||||
|
||||
/*
|
||||
* Single buffer I/O? Skip what we've done so far in this region.
|
||||
*/
|
||||
if (buffer == NULL) {
|
||||
write_count = dev->region.length - dev->n;
|
||||
cpbuffer = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(buflist_t));
|
||||
RUNTIME_CHECK(cpbuffer != NULL);
|
||||
cpbuffer->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, write_count);
|
||||
RUNTIME_CHECK(cpbuffer->buf != NULL);
|
||||
write_count = dev->region.length - dev->n;
|
||||
lpo->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, write_count);
|
||||
RUNTIME_CHECK(lpo->buf != NULL);
|
||||
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"alloc_buffer %p %d %p %d", cpbuffer, sizeof(buflist_t),
|
||||
cpbuffer->buf, write_count);
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"alloc_buffer %p %d", lpo->buf, write_count);
|
||||
|
||||
memmove(cpbuffer->buf,(dev->region.base + dev->n), write_count);
|
||||
cpbuffer->buflen = (unsigned int)write_count;
|
||||
ISC_LINK_INIT(cpbuffer, link);
|
||||
ISC_LIST_ENQUEUE(lpo->bufferlist, cpbuffer, link);
|
||||
iov[0].buf = cpbuffer->buf;
|
||||
iov[0].len = (u_long)write_count;
|
||||
iovcount = 1;
|
||||
memmove(lpo->buf,(dev->region.base + dev->n), write_count);
|
||||
lpo->buflen = (unsigned int)write_count;
|
||||
iov[0].buf = lpo->buf;
|
||||
iov[0].len = (u_long)write_count;
|
||||
iovcount = 1;
|
||||
|
||||
goto config;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multibuffer I/O.
|
||||
* Skip the data in the buffer list that we have already written.
|
||||
*/
|
||||
skip_count = dev->n;
|
||||
while (buffer != NULL) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (skip_count < isc_buffer_usedlength(buffer))
|
||||
break;
|
||||
skip_count -= isc_buffer_usedlength(buffer);
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
while (buffer != NULL) {
|
||||
INSIST(iovcount < MAXSCATTERGATHER_SEND);
|
||||
|
||||
isc_buffer_usedregion(buffer, &used);
|
||||
|
||||
if (used.length > 0) {
|
||||
int uselen = (int)(used.length - skip_count);
|
||||
cpbuffer = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(buflist_t));
|
||||
RUNTIME_CHECK(cpbuffer != NULL);
|
||||
cpbuffer->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, uselen);
|
||||
RUNTIME_CHECK(cpbuffer->buf != NULL);
|
||||
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"alloc_buffer %p %d %p %d", cpbuffer, sizeof(buflist_t),
|
||||
cpbuffer->buf, write_count);
|
||||
|
||||
memmove(cpbuffer->buf,(used.base + skip_count), uselen);
|
||||
cpbuffer->buflen = uselen;
|
||||
iov[iovcount].buf = cpbuffer->buf;
|
||||
iov[iovcount].len = (u_long)(used.length - skip_count);
|
||||
write_count += uselen;
|
||||
skip_count = 0;
|
||||
iovcount++;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
|
||||
INSIST(skip_count == 0);
|
||||
|
||||
config:
|
||||
msg->msg_iov = iov;
|
||||
msg->msg_iovlen = iovcount;
|
||||
msg->msg_totallen = (u_int)write_count;
|
||||
@@ -1059,8 +989,6 @@ static void
|
||||
destroy_socketevent(isc_event_t *event) {
|
||||
isc_socketevent_t *ev = (isc_socketevent_t *)event;
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(ev->bufferlist));
|
||||
|
||||
(ev->destroy)(event);
|
||||
}
|
||||
|
||||
@@ -1079,7 +1007,6 @@ allocate_socketevent(isc_mem_t *mctx, isc_socket_t *sock,
|
||||
|
||||
ev->result = ISC_R_IOERROR; // XXXMLG temporary change to detect failure to set
|
||||
ISC_LINK_INIT(ev, ev_link);
|
||||
ISC_LIST_INIT(ev->bufferlist);
|
||||
ev->region.base = NULL;
|
||||
ev->n = 0;
|
||||
ev->offset = 0;
|
||||
@@ -1215,9 +1142,7 @@ map_socket_error(isc_socket_t *sock, int windows_errno, int *isc_errno,
|
||||
|
||||
static void
|
||||
fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
isc_region_t r;
|
||||
int copylen;
|
||||
isc_buffer_t *buffer;
|
||||
|
||||
INSIST(dev->n < dev->minimum);
|
||||
INSIST(sock->recvbuf.remaining > 0);
|
||||
@@ -1241,36 +1166,12 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
dev->address = sock->address;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run through the list of buffers we were given, and find the
|
||||
* first one with space. Once it is found, loop through, filling
|
||||
* the buffers as much as possible.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(dev->bufferlist);
|
||||
if (buffer != NULL) { // Multi-buffer receive
|
||||
while (buffer != NULL && sock->recvbuf.remaining > 0) {
|
||||
REQUIRE(ISC_BUFFER_VALID(buffer));
|
||||
if (isc_buffer_availablelength(buffer) > 0) {
|
||||
isc_buffer_availableregion(buffer, &r);
|
||||
copylen = min(r.length,
|
||||
sock->recvbuf.remaining);
|
||||
memmove(r.base, sock->recvbuf.consume_position,
|
||||
copylen);
|
||||
sock->recvbuf.consume_position += copylen;
|
||||
sock->recvbuf.remaining -= copylen;
|
||||
isc_buffer_add(buffer, copylen);
|
||||
dev->n += copylen;
|
||||
}
|
||||
buffer = ISC_LIST_NEXT(buffer, link);
|
||||
}
|
||||
} else { // Single-buffer receive
|
||||
copylen = min(dev->region.length - dev->n, sock->recvbuf.remaining);
|
||||
memmove(dev->region.base + dev->n,
|
||||
sock->recvbuf.consume_position, copylen);
|
||||
sock->recvbuf.consume_position += copylen;
|
||||
sock->recvbuf.remaining -= copylen;
|
||||
dev->n += copylen;
|
||||
}
|
||||
copylen = min(dev->region.length - dev->n, sock->recvbuf.remaining);
|
||||
memmove(dev->region.base + dev->n,
|
||||
sock->recvbuf.consume_position, copylen);
|
||||
sock->recvbuf.consume_position += copylen;
|
||||
sock->recvbuf.remaining -= copylen;
|
||||
dev->n += copylen;
|
||||
|
||||
/*
|
||||
* UDP receives are all-consuming. That is, if we have 4k worth of
|
||||
@@ -1377,7 +1278,6 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
|
||||
lpo->dev = dev;
|
||||
mh = &lpo->messagehdr;
|
||||
memset(mh, 0, sizeof(struct msghdr));
|
||||
ISC_LIST_INIT(lpo->bufferlist);
|
||||
|
||||
build_msghdr_send(sock, dev, mh, cmsg, sock->iov, lpo);
|
||||
|
||||
@@ -1649,7 +1549,6 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
REQUIRE(socketp != NULL && *socketp == NULL);
|
||||
REQUIRE(type != isc_sockettype_fdwatch);
|
||||
|
||||
#ifndef SOCK_RAW
|
||||
if (type == isc_sockettype_raw)
|
||||
@@ -1855,7 +1754,6 @@ isc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) {
|
||||
isc_result_t
|
||||
isc_socket_open(isc_socket_t *sock) {
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(sock->type != isc_sockettype_fdwatch);
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
@@ -1887,7 +1785,6 @@ isc_socket_detach(isc_socket_t **socketp) {
|
||||
REQUIRE(socketp != NULL);
|
||||
sock = *socketp;
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(sock->type != isc_sockettype_fdwatch);
|
||||
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
@@ -1913,7 +1810,6 @@ isc_socket_detach(isc_socket_t **socketp) {
|
||||
isc_result_t
|
||||
isc_socket_close(isc_socket_t *sock) {
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(sock->type != isc_sockettype_fdwatch);
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
@@ -2301,8 +2197,6 @@ static void
|
||||
internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
struct msghdr *messagehdr, int nbytes, int send_errno, IoCompletionInfo *lpo)
|
||||
{
|
||||
buflist_t *buffer;
|
||||
|
||||
/*
|
||||
* Find out what socket this is and lock it.
|
||||
*/
|
||||
@@ -2315,17 +2209,14 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND,
|
||||
"internal_send: task got socket event %p", dev);
|
||||
|
||||
buffer = ISC_LIST_HEAD(lpo->bufferlist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(lpo->bufferlist, buffer, link);
|
||||
|
||||
if (lpo->buf != NULL) {
|
||||
socket_log(__LINE__, sock, NULL, TRACE,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
|
||||
"free_buffer %p %p", buffer, buffer->buf);
|
||||
"free_buffer %p", lpo->buf);
|
||||
|
||||
HeapFree(hHeapHandle, 0, buffer->buf);
|
||||
HeapFree(hHeapHandle, 0, buffer);
|
||||
buffer = ISC_LIST_HEAD(lpo->bufferlist);
|
||||
HeapFree(hHeapHandle, 0, lpo->buf);
|
||||
lpo->buf = NULL;
|
||||
lpo->buflen = 0;
|
||||
}
|
||||
|
||||
INSIST(sock->pending_iocp > 0);
|
||||
@@ -2645,7 +2536,7 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
unsigned int maxsocks)
|
||||
unsigned int maxsocks, int nthreads)
|
||||
{
|
||||
isc_socketmgr_t *manager;
|
||||
isc_result_t result;
|
||||
@@ -2681,6 +2572,10 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
}
|
||||
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
if (nthreads == 0) {
|
||||
nthreads = isc_os_ncpus() + 1;
|
||||
}
|
||||
manager->maxIOCPThreads = min(nthreads, MAX_IOCPTHREADS);
|
||||
|
||||
iocompletionport_init(manager); /* Create the Completion Ports */
|
||||
|
||||
@@ -2836,77 +2731,6 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
isc_taskaction_t action, void *arg)
|
||||
{
|
||||
isc_socketevent_t *dev;
|
||||
isc_socketmgr_t *manager;
|
||||
unsigned int iocount;
|
||||
isc_buffer_t *buffer;
|
||||
isc_result_t ret;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
|
||||
/*
|
||||
* Make sure that the socket is not closed. XXXMLG change error here?
|
||||
*/
|
||||
if (sock->fd == INVALID_SOCKET) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
|
||||
REQUIRE(buflist != NULL);
|
||||
REQUIRE(!ISC_LIST_EMPTY(*buflist));
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
iocount = isc_bufferlist_availablecount(buflist);
|
||||
REQUIRE(iocount > 0);
|
||||
|
||||
INSIST(sock->bound);
|
||||
|
||||
dev = allocate_socketevent(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_RECVDONE, action, arg);
|
||||
if (dev == NULL) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* UDP sockets are always partial read
|
||||
*/
|
||||
if (sock->type == isc_sockettype_udp)
|
||||
dev->minimum = 1;
|
||||
else {
|
||||
if (minimum == 0)
|
||||
dev->minimum = iocount;
|
||||
else
|
||||
dev->minimum = minimum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move each buffer from the passed in list to our internal one.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(*buflist, buffer, link);
|
||||
ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link);
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
}
|
||||
|
||||
ret = socket_recv(sock, dev, task, 0);
|
||||
|
||||
UNLOCK(&sock->lock);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
|
||||
unsigned int minimum, isc_task_t *task,
|
||||
@@ -2967,7 +2791,6 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
event->region = *region;
|
||||
event->n = 0;
|
||||
event->offset = 0;
|
||||
@@ -3078,7 +2901,6 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_result_t ret;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(sock->type != isc_sockettype_fdwatch);
|
||||
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
@@ -3112,80 +2934,6 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg)
|
||||
{
|
||||
return (isc_socket_sendtov2(sock, buflist, task, action, arg, NULL,
|
||||
NULL, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
|
||||
{
|
||||
return (isc_socket_sendtov2(sock, buflist, task, action, arg, address,
|
||||
pktinfo, 0));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
unsigned int flags)
|
||||
{
|
||||
isc_socketevent_t *dev;
|
||||
isc_socketmgr_t *manager;
|
||||
unsigned int iocount;
|
||||
isc_buffer_t *buffer;
|
||||
isc_result_t ret;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
|
||||
/*
|
||||
* make sure that the socket's not closed
|
||||
*/
|
||||
if (sock->fd == INVALID_SOCKET) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
REQUIRE(buflist != NULL);
|
||||
REQUIRE(!ISC_LIST_EMPTY(*buflist));
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
iocount = isc_bufferlist_usedcount(buflist);
|
||||
REQUIRE(iocount > 0);
|
||||
|
||||
dev = allocate_socketevent(manager->mctx, sock,
|
||||
ISC_SOCKEVENT_SENDDONE, action, arg);
|
||||
if (dev == NULL) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move each buffer from the passed in list to our internal one.
|
||||
*/
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
while (buffer != NULL) {
|
||||
ISC_LIST_DEQUEUE(*buflist, buffer, link);
|
||||
ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link);
|
||||
buffer = ISC_LIST_HEAD(*buflist);
|
||||
}
|
||||
|
||||
ret = socket_send(sock, dev, task, address, pktinfo, flags);
|
||||
UNLOCK(&sock->lock);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
|
||||
const isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
@@ -3209,7 +2957,6 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CONNREFUSED);
|
||||
}
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
event->region = *region;
|
||||
event->n = 0;
|
||||
event->offset = 0;
|
||||
@@ -3946,20 +3693,25 @@ isc_socket_socketevent(isc_mem_t *mctx, void *sender,
|
||||
return (allocate_socketevent(mctx, sender, eventtype, action, arg));
|
||||
}
|
||||
|
||||
bool
|
||||
isc_socket_hasreuseport() {
|
||||
return (false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
static const char *
|
||||
_socktype(isc_sockettype_t type) {
|
||||
if (type == isc_sockettype_udp)
|
||||
switch (type) {
|
||||
case isc_sockettype_udp:
|
||||
return ("udp");
|
||||
else if (type == isc_sockettype_tcp)
|
||||
case isc_sockettype_tcp:
|
||||
return ("tcp");
|
||||
else if (type == isc_sockettype_unix)
|
||||
case isc_sockettype_unix:
|
||||
return ("unix");
|
||||
else if (type == isc_sockettype_fdwatch)
|
||||
return ("fdwatch");
|
||||
else
|
||||
default:
|
||||
return ("not-initialized");
|
||||
}
|
||||
}
|
||||
|
||||
#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
|
||||
|
||||
@@ -66,6 +66,12 @@ isc_thread_setname(isc_thread_t thread, const char *name) {
|
||||
UNUSED(name);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_thread_setaffinity(int cpu) {
|
||||
/* no-op on Windows for now */
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void *
|
||||
isc_thread_key_getspecific(isc_thread_key_t key) {
|
||||
return(TlsGetValue(key));
|
||||
|
||||
+1
-1
@@ -2960,7 +2960,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
|
||||
ns_server_attach(manager->sctx, &client->sctx);
|
||||
|
||||
client->task = NULL;
|
||||
result = isc_task_create(manager->taskmgr, 0, &client->task);
|
||||
result = isc_task_create(manager->taskmgr, 50, &client->task);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_client;
|
||||
isc_task_setname(client->task, "client", client);
|
||||
|
||||
@@ -470,6 +470,7 @@ ns_interface_listenudp(ns_interface_t *ifp) {
|
||||
else
|
||||
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||
attrs |= DNS_DISPATCHATTR_NOLISTEN;
|
||||
attrs |= DNS_DISPATCHATTR_CANREUSE;
|
||||
attrmask = 0;
|
||||
attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;
|
||||
attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
|
||||
|
||||
+13
-8
@@ -5237,6 +5237,19 @@ ns__query_start(query_ctx_t *qctx) {
|
||||
qctx->need_wildcardproof = false;
|
||||
qctx->rpz = false;
|
||||
|
||||
/*
|
||||
* If we require a server cookie then send back BADCOOKIE
|
||||
* before we have done too much work.
|
||||
*/
|
||||
if (!TCP(qctx->client) && qctx->client->view->requireservercookie &&
|
||||
WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client))
|
||||
{
|
||||
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
|
||||
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
|
||||
qctx->client->message->rcode = dns_rcode_badcookie;
|
||||
return (query_done(qctx));
|
||||
}
|
||||
|
||||
if (qctx->client->view->checknames &&
|
||||
!dns_rdata_checkowner(qctx->client->query.qname,
|
||||
qctx->client->message->rdclass,
|
||||
@@ -6276,14 +6289,6 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
|
||||
return (DNS_R_DROP);
|
||||
}
|
||||
}
|
||||
} else if (!TCP(qctx->client) &&
|
||||
qctx->client->view->requireservercookie &&
|
||||
WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client))
|
||||
{
|
||||
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
|
||||
qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
|
||||
qctx->client->message->rcode = dns_rcode_badcookie;
|
||||
return (DNS_R_DROP);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
@@ -824,6 +824,8 @@
|
||||
./bin/tests/system/cookie/ns6/root.hint ZONE 2017,2018
|
||||
./bin/tests/system/cookie/ns7/named.conf.in CONF-C 2018
|
||||
./bin/tests/system/cookie/ns7/root.db ZONE 2018
|
||||
./bin/tests/system/cookie/ns8/example.db ZONE 2018
|
||||
./bin/tests/system/cookie/ns8/named.conf.in CONF-C 2018
|
||||
./bin/tests/system/cookie/setup.sh SH 2018
|
||||
./bin/tests/system/cookie/tests.sh SH 2014,2015,2016,2017,2018
|
||||
./bin/tests/system/coverage/01-ksk-inactive/README X 2013,2018
|
||||
|
||||
Reference in New Issue
Block a user