Compare commits
35
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f9da7f225 | ||
|
|
b7a76fad2b | ||
|
|
5e5e8da953 | ||
|
|
7b8757db45 | ||
|
|
dc2ca4fa8d | ||
|
|
6f89098e32 | ||
|
|
2f93fa320f | ||
|
|
3d11d69ebf | ||
|
|
cb847810aa | ||
|
|
2680c6d189 | ||
|
|
2445c44f21 | ||
|
|
a1101c07fc | ||
|
|
ea2720cc00 | ||
|
|
a6c53a015a | ||
|
|
e2102aabbe | ||
|
|
e4e9930397 | ||
|
|
58e1baba7a | ||
|
|
3ed794bb45 | ||
|
|
3e8838654d | ||
|
|
fcb8aec700 | ||
|
|
1565ee6c3d | ||
|
|
527e540841 | ||
|
|
43ca8bc50a | ||
|
|
733a3db7a5 | ||
|
|
7b9f4cfc08 | ||
|
|
258f1dc94c | ||
|
|
b1c35f812a | ||
|
|
f65933d11a | ||
|
|
e1f80772b2 | ||
|
|
f880388607 | ||
|
|
3fa5684e19 | ||
|
|
28025720a8 | ||
|
|
e83e6be806 | ||
|
|
505b88e1a3 | ||
|
|
b7a199184c |
@@ -1,3 +1,29 @@
|
|||||||
|
5139. [bug] If possible, don't use forwarders when priming.
|
||||||
|
This ensures we can get root server IP addresses
|
||||||
|
from priming query response glue, which may not
|
||||||
|
be present if the forwarding server is returning
|
||||||
|
minimal responses. [GL #752]
|
||||||
|
|
||||||
|
5138. [bug] Under some circumstances named could hit an assertion
|
||||||
|
failure when doing qname minimization when using
|
||||||
|
forwarders. [GL #797]
|
||||||
|
|
||||||
|
5137. [func] named now logs messages whenever a mirror zone becomes
|
||||||
|
usable or unusable for resolution purposes. [GL #818]
|
||||||
|
|
||||||
|
5136. [cleanup] Check in named-checkconf that allow-update and
|
||||||
|
allow-update-forwarding are not set at the
|
||||||
|
view/options level; fix documentation. [GL #512]
|
||||||
|
|
||||||
|
5135. [port] sparc: Use smt_pause() instead of pause. [GL #816]
|
||||||
|
|
||||||
|
5134. [bug] win32: WSAStartup was not called before getservbyname
|
||||||
|
was called. [GL #590]
|
||||||
|
|
||||||
|
5133. [bug] 'rndc managed-keys' didn't handle class and view
|
||||||
|
correctly and failed to add new lines between each
|
||||||
|
view. [GL !1327]
|
||||||
|
|
||||||
5132. [bug] Fix race condition in cleanup part of dns_dt_create().
|
5132. [bug] Fix race condition in cleanup part of dns_dt_create().
|
||||||
[GL !1323]
|
[GL !1323]
|
||||||
|
|
||||||
|
|||||||
+22
-29
@@ -4995,16 +4995,10 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||||||
&view->sortlist));
|
&view->sortlist));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure default allow-notify, allow-update
|
* Configure default allow-update and allow-update-forwarding ACLs,
|
||||||
* and allow-update-forwarding ACLs, so they can be
|
* so they can be inherited by zones. (Note these cannot be set at
|
||||||
* inherited by zones. (Note these cannot be set at
|
|
||||||
* options/view level.)
|
* options/view level.)
|
||||||
*/
|
*/
|
||||||
if (view->notifyacl == NULL) {
|
|
||||||
CHECK(configure_view_acl(vconfig, config, named_g_config,
|
|
||||||
"allow-notify", NULL, actx,
|
|
||||||
named_g_mctx, &view->notifyacl));
|
|
||||||
}
|
|
||||||
if (view->updateacl == NULL) {
|
if (view->updateacl == NULL) {
|
||||||
CHECK(configure_view_acl(NULL, NULL, named_g_config,
|
CHECK(configure_view_acl(NULL, NULL, named_g_config,
|
||||||
"allow-update", NULL, actx,
|
"allow-update", NULL, actx,
|
||||||
@@ -5017,14 +5011,19 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure default allow-transer ACL so it can be inherited
|
* Configure default allow-transfer and allow-notify ACLs so they
|
||||||
* by zones. (Note this *can* be set at options or view level.)
|
* can be inherited by zones.
|
||||||
*/
|
*/
|
||||||
if (view->transferacl == NULL) {
|
if (view->transferacl == NULL) {
|
||||||
CHECK(configure_view_acl(vconfig, config, named_g_config,
|
CHECK(configure_view_acl(vconfig, config, named_g_config,
|
||||||
"allow-transfer", NULL, actx,
|
"allow-transfer", NULL, actx,
|
||||||
named_g_mctx, &view->transferacl));
|
named_g_mctx, &view->transferacl));
|
||||||
}
|
}
|
||||||
|
if (view->notifyacl == NULL) {
|
||||||
|
CHECK(configure_view_acl(vconfig, config, named_g_config,
|
||||||
|
"allow-notify", NULL, actx,
|
||||||
|
named_g_mctx, &view->notifyacl));
|
||||||
|
}
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
result = named_config_get(maps, "provide-ixfr", &obj);
|
result = named_config_get(maps, "provide-ixfr", &obj);
|
||||||
@@ -6894,7 +6893,7 @@ tat_timer_tick(isc_task_t *task, isc_event_t *event) {
|
|||||||
static void
|
static void
|
||||||
pps_timer_tick(isc_task_t *task, isc_event_t *event) {
|
pps_timer_tick(isc_task_t *task, isc_event_t *event) {
|
||||||
static unsigned int oldrequests = 0;
|
static unsigned int oldrequests = 0;
|
||||||
unsigned int requests = ns_client_requests;
|
unsigned int requests = atomic_load(&ns_client_requests);
|
||||||
|
|
||||||
UNUSED(task);
|
UNUSED(task);
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
@@ -15049,29 +15048,17 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
/* Look for the optional class name. */
|
/* Look for the optional class name. */
|
||||||
classtxt = next_token(lex, text);
|
classtxt = next_token(lex, text);
|
||||||
if (classtxt != NULL) {
|
if (classtxt != NULL) {
|
||||||
/* Look for the optional view name. */
|
|
||||||
viewtxt = next_token(lex, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classtxt == NULL) {
|
|
||||||
rdclass = dns_rdataclass_in;
|
|
||||||
} else {
|
|
||||||
isc_textregion_t r;
|
isc_textregion_t r;
|
||||||
r.base = classtxt;
|
r.base = classtxt;
|
||||||
r.length = strlen(classtxt);
|
r.length = strlen(classtxt);
|
||||||
result = dns_rdataclass_fromtext(&rdclass, &r);
|
result = dns_rdataclass_fromtext(&rdclass, &r);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
if (viewtxt == NULL) {
|
snprintf(msg, sizeof(msg),
|
||||||
rdclass = dns_rdataclass_in;
|
"unknown class '%s'", classtxt);
|
||||||
viewtxt = classtxt;
|
(void) putstr(text, msg);
|
||||||
result = ISC_R_SUCCESS;
|
goto cleanup;
|
||||||
} else {
|
|
||||||
snprintf(msg, sizeof(msg),
|
|
||||||
"unknown class '%s'", classtxt);
|
|
||||||
(void) putstr(text, msg);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
viewtxt = next_token(lex, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (view = ISC_LIST_HEAD(server->viewlist);
|
for (view = ISC_LIST_HEAD(server->viewlist);
|
||||||
@@ -15100,6 +15087,9 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case REFRESH:
|
case REFRESH:
|
||||||
|
if (!first) {
|
||||||
|
CHECK(putstr(text, "\n"));
|
||||||
|
}
|
||||||
CHECK(mkey_refresh(view, text));
|
CHECK(mkey_refresh(view, text));
|
||||||
break;
|
break;
|
||||||
case STATUS:
|
case STATUS:
|
||||||
@@ -15107,12 +15097,14 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
CHECK(putstr(text, "\n\n"));
|
CHECK(putstr(text, "\n\n"));
|
||||||
}
|
}
|
||||||
CHECK(mkey_status(view, text));
|
CHECK(mkey_status(view, text));
|
||||||
first = false;
|
|
||||||
break;
|
break;
|
||||||
case SYNC:
|
case SYNC:
|
||||||
CHECK(dns_zone_flush(view->managed_keys));
|
CHECK(dns_zone_flush(view->managed_keys));
|
||||||
break;
|
break;
|
||||||
case DESTROY:
|
case DESTROY:
|
||||||
|
if (!first) {
|
||||||
|
CHECK(putstr(text, "\n"));
|
||||||
|
}
|
||||||
CHECK(mkey_destroy(server, view, text));
|
CHECK(mkey_destroy(server, view, text));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -15123,6 +15115,7 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
if (viewtxt != NULL) {
|
if (viewtxt != NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
|||||||
+9
-7
@@ -75,7 +75,7 @@ static isccc_region_t secret;
|
|||||||
static bool failed = false;
|
static bool failed = false;
|
||||||
static bool c_flag = false;
|
static bool c_flag = false;
|
||||||
static isc_mem_t *rndc_mctx;
|
static isc_mem_t *rndc_mctx;
|
||||||
static int sends, recvs, connects;
|
static atomic_uint_fast32_t sends, recvs, connects;
|
||||||
static char *command;
|
static char *command;
|
||||||
static char *args;
|
static char *args;
|
||||||
static char program[256];
|
static char program[256];
|
||||||
@@ -273,11 +273,11 @@ rndc_senddone(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
UNUSED(task);
|
UNUSED(task);
|
||||||
|
|
||||||
sends--;
|
atomic_fetch_sub(&sends, 1);
|
||||||
if (sevent->result != ISC_R_SUCCESS)
|
if (sevent->result != ISC_R_SUCCESS)
|
||||||
fatal("send failed: %s", isc_result_totext(sevent->result));
|
fatal("send failed: %s", isc_result_totext(sevent->result));
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
if (sends == 0 && recvs == 0) {
|
if (atomic_load(&sends) == 0 && atomic_load(&recvs) == 0) {
|
||||||
isc_socket_detach(&sock);
|
isc_socket_detach(&sock);
|
||||||
isc_task_shutdown(task);
|
isc_task_shutdown(task);
|
||||||
RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS);
|
RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS);
|
||||||
@@ -346,7 +346,7 @@ rndc_recvdone(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
isccc_sexpr_free(&response);
|
isccc_sexpr_free(&response);
|
||||||
if (sends == 0 && recvs == 0) {
|
if (atomic_load(&sends) == 0 && atomic_load(&recvs) == 0) {
|
||||||
isc_socket_detach(&sock);
|
isc_socket_detach(&sock);
|
||||||
isc_task_shutdown(task);
|
isc_task_shutdown(task);
|
||||||
RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS);
|
RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS);
|
||||||
@@ -430,7 +430,7 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
|
|||||||
recvs++;
|
recvs++;
|
||||||
DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
|
DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
|
||||||
NULL));
|
NULL));
|
||||||
sends++;
|
atomic_fetch_add(&sends, 1);
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
isccc_sexpr_free(&response);
|
isccc_sexpr_free(&response);
|
||||||
@@ -498,7 +498,7 @@ rndc_connected(isc_task_t *task, isc_event_t *event) {
|
|||||||
recvs++;
|
recvs++;
|
||||||
DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
|
DO("send message", isc_socket_send(sock, &r, task, rndc_senddone,
|
||||||
NULL));
|
NULL));
|
||||||
sends++;
|
atomic_fetch_add(&sends, 1);
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
isccc_sexpr_free(&request);
|
isccc_sexpr_free(&request);
|
||||||
}
|
}
|
||||||
@@ -999,8 +999,10 @@ main(int argc, char **argv) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
fatal("isc_app_run() failed: %s", isc_result_totext(result));
|
fatal("isc_app_run() failed: %s", isc_result_totext(result));
|
||||||
|
|
||||||
if (connects > 0 || sends > 0 || recvs > 0)
|
if (atomic_load(&connects) > 0 || atomic_load(&sends) > 0 ||
|
||||||
|
atomic_load(&recvs) > 0) {
|
||||||
isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL);
|
isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
isc_task_detach(&task);
|
isc_task_detach(&task);
|
||||||
isc_taskmgr_destroy(&taskmgr);
|
isc_taskmgr_destroy(&taskmgr);
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
view {
|
||||||
|
allow-update-forwarding { any; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
options {
|
||||||
|
allow-update-forwarding { any; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
view {
|
||||||
|
allow-update { any; };
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
options {
|
||||||
|
allow-update { any; };
|
||||||
|
};
|
||||||
@@ -133,6 +133,9 @@ view "third" {
|
|||||||
zone "dnssec" {
|
zone "dnssec" {
|
||||||
type master;
|
type master;
|
||||||
file "file";
|
file "file";
|
||||||
|
allow-update {
|
||||||
|
"any";
|
||||||
|
};
|
||||||
auto-dnssec maintain;
|
auto-dnssec maintain;
|
||||||
};
|
};
|
||||||
zone "p" {
|
zone "p" {
|
||||||
@@ -145,9 +148,6 @@ view "third" {
|
|||||||
1.2.3.4;
|
1.2.3.4;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
allow-update {
|
|
||||||
"any";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
view "chaos" chaos {
|
view "chaos" chaos {
|
||||||
zone "hostname.bind" chaos {
|
zone "hostname.bind" chaos {
|
||||||
|
|||||||
@@ -57,18 +57,14 @@ showprivate () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check that signing records are marked as complete
|
# check that signing records are marked as complete
|
||||||
checkprivate () { (
|
checkprivate () {
|
||||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||||
ret=0
|
showprivate "$@" | grep -q incomplete || return 0
|
||||||
showprivate "$@" | grep incomplete >/dev/null 2>&1 && { ret=1; sleep 1; continue; }
|
sleep 1
|
||||||
break
|
|
||||||
done
|
done
|
||||||
[ $ret -eq 1 ] && {
|
echo_d "$1 signing incomplete"
|
||||||
echo_d "$1 signing incomplete"
|
return 1
|
||||||
return 1
|
}
|
||||||
}
|
|
||||||
return 0
|
|
||||||
) }
|
|
||||||
|
|
||||||
# check that a zone file is raw format, version 0
|
# check that a zone file is raw format, version 0
|
||||||
israw0 () {
|
israw0 () {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ options {
|
|||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
dnssec-validation yes;
|
dnssec-validation yes;
|
||||||
|
minimal-responses yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
zone "." {
|
zone "." {
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.7;
|
||||||
|
notify-source 10.53.0.7;
|
||||||
|
transfer-source 10.53.0.7;
|
||||||
|
port @PORT@;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.7; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
forwarders { 10.53.0.4; };
|
||||||
|
forward first;
|
||||||
|
dnssec-validation yes;
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "." {
|
||||||
|
type hint;
|
||||||
|
file "root.db";
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
; 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.
|
||||||
|
|
||||||
|
$TTL 300
|
||||||
|
. IN SOA gson.nominum.com. a.root.servers.nil. (
|
||||||
|
2000042100 ; serial
|
||||||
|
600 ; refresh
|
||||||
|
600 ; retry
|
||||||
|
1200 ; expire
|
||||||
|
600 ; minimum
|
||||||
|
)
|
||||||
|
. NS a.root-servers.nil.
|
||||||
|
a.root-servers.nil. A 10.53.0.1
|
||||||
|
|
||||||
|
example1 NS ns.example1
|
||||||
|
ns.example1 A 10.53.0.1
|
||||||
|
|
||||||
|
example2 NS ns.example2
|
||||||
|
ns.example2 A 10.53.0.1
|
||||||
|
|
||||||
|
example3 NS ns.example3
|
||||||
|
ns.example3 A 10.53.0.1
|
||||||
@@ -18,3 +18,4 @@ copy_setports ns2/named.conf.in ns2/named.conf
|
|||||||
copy_setports ns3/named.conf.in ns3/named.conf
|
copy_setports ns3/named.conf.in ns3/named.conf
|
||||||
copy_setports ns4/named.conf.in ns4/named.conf
|
copy_setports ns4/named.conf.in ns4/named.conf
|
||||||
copy_setports ns5/named.conf.in ns5/named.conf
|
copy_setports ns5/named.conf.in ns5/named.conf
|
||||||
|
copy_setports ns7/named.conf.in ns7/named.conf
|
||||||
|
|||||||
@@ -147,5 +147,17 @@ if [ $sent -ne 1 ]; then ret=1; fi
|
|||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
echo_i "checking that priming queries are not forwarded"
|
||||||
|
ret=0
|
||||||
|
$DIG $DIGOPTS +noadd +noauth txt.example1. txt @10.53.0.7 > dig.out.f7 || ret=1
|
||||||
|
sent=`sed -n '/sending packet to 10.53.0.1/,/^$/p' ns7/named.run | grep ";.*IN.*NS" | wc -l`
|
||||||
|
[ $sent -eq 1 ] || ret=1
|
||||||
|
sent=`grep "10.53.0.7#.* (.): query '\./NS/IN' approved" ns4/named.run | wc -l`
|
||||||
|
[ $sent -eq 0 ] || ret=1
|
||||||
|
sent=`grep "10.53.0.7#.* (.): query '\./NS/IN' approved" ns1/named.run | wc -l`
|
||||||
|
[ $sent -eq 1 ] || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo_i "exit status: $status"
|
echo_i "exit status: $status"
|
||||||
[ $status -eq 0 ] || exit 1
|
[ $status -eq 0 ] || exit 1
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ zone "verify-ixfr" {
|
|||||||
type master;
|
type master;
|
||||||
file "verify-ixfr.db.signed";
|
file "verify-ixfr.db.signed";
|
||||||
ixfr-from-differences yes;
|
ixfr-from-differences yes;
|
||||||
|
allow-transfer { 10.53.0.3; };
|
||||||
};
|
};
|
||||||
|
|
||||||
zone "verify-reconfig" {
|
zone "verify-reconfig" {
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ ret=0
|
|||||||
wait_for_transfer verify-unsigned
|
wait_for_transfer verify-unsigned
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-unsigned SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-unsigned SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||||
nextpart ns3/named.run | grep "verify-unsigned.*Zone contains no DNSSEC keys" > /dev/null || ret=1
|
nextpartpeek ns3/named.run | grep "verify-unsigned.*Zone contains no DNSSEC keys" > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-unsigned.*mirror zone is now in use" > /dev/null && ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -73,7 +74,8 @@ nextpartreset ns3/named.run
|
|||||||
wait_for_transfer verify-untrusted
|
wait_for_transfer verify-untrusted
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-untrusted SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-untrusted SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||||
nextpart ns3/named.run | grep "verify-untrusted.*No trusted KSK DNSKEY found" > /dev/null || ret=1
|
nextpartpeek ns3/named.run | grep "verify-untrusted.*No trusted KSK DNSKEY found" > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-untrusted.*mirror zone is now in use" > /dev/null && ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -84,7 +86,8 @@ nextpartreset ns3/named.run
|
|||||||
wait_for_transfer verify-axfr
|
wait_for_transfer verify-axfr
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||||
nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-axfr SOA" > /dev/null || ret=1
|
nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-axfr SOA" > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-axfr.*mirror zone is now in use" > /dev/null && ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -98,6 +101,7 @@ $RNDCCMD 10.53.0.3 retransfer verify-axfr > /dev/null 2>&1
|
|||||||
wait_for_transfer verify-axfr
|
wait_for_transfer verify-axfr
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-axfr.*mirror zone is now in use" > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -106,12 +110,23 @@ echo_i "checking that an IXFR of an incorrectly signed mirror zone is rejected (
|
|||||||
nextpartreset ns3/named.run
|
nextpartreset ns3/named.run
|
||||||
ret=0
|
ret=0
|
||||||
wait_for_transfer verify-ixfr
|
wait_for_transfer verify-ixfr
|
||||||
nextpart ns3/named.run > /dev/null
|
|
||||||
# Make a copy of the original zone file for reuse in journal tests below.
|
# Make a copy of the original zone file for reuse in journal tests below.
|
||||||
cp ns2/verify-ixfr.db.signed ns3/verify-journal.db.mirror
|
cp ns2/verify-ixfr.db.signed ns3/verify-journal.db.mirror
|
||||||
# Wait 1 second so that the zone file timestamp changes and the subsequent
|
# Wait 1 second so that the zone file timestamp changes and the subsequent
|
||||||
# invocation of "rndc reload" triggers a zone reload.
|
# invocation of "rndc reload" triggers a zone reload. This should also be way
|
||||||
|
# more than enough for the log message announcing the mirror zone coming into
|
||||||
|
# effect to appear in the log (see below).
|
||||||
sleep 1
|
sleep 1
|
||||||
|
# Sanity check: the initial, properly signed version of the zone should have
|
||||||
|
# been announced as coming into effect. Note that we cannot check that
|
||||||
|
# immediately after wait_for_transfer() as the latter might return before the
|
||||||
|
# log message we are looking for here appears; we also cannot call nextpart()
|
||||||
|
# after we update the zone on ns2 since there is a possibility of periodic
|
||||||
|
# refreshes triggering an IXFR of the "verify-ixfr" zone before the "rndc
|
||||||
|
# refresh" call below and that possibility needs to be handled as proper
|
||||||
|
# behavior. Thus, we need to look for the log message now.
|
||||||
|
nextpart ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null || ret=1
|
||||||
|
# Update the "verify-ixfr" zone on ns2.
|
||||||
cat ns2/verify-ixfr.db.bad.signed > ns2/verify-ixfr.db.signed
|
cat ns2/verify-ixfr.db.bad.signed > ns2/verify-ixfr.db.signed
|
||||||
reload_zone verify-ixfr ${UPDATED_SERIAL_BAD}
|
reload_zone verify-ixfr ${UPDATED_SERIAL_BAD}
|
||||||
# Make a copy of the bad zone journal for reuse in journal tests below.
|
# Make a copy of the bad zone journal for reuse in journal tests below.
|
||||||
@@ -127,7 +142,10 @@ fi
|
|||||||
# Ensure the new, bad version of the zone was not accepted.
|
# Ensure the new, bad version of the zone was not accepted.
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||||
nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1
|
nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1
|
||||||
|
# Despite the verification failure for this IXFR, this mirror zone should still
|
||||||
|
# be in use as its previous version should have been verified successfully.
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is no longer in use" > /dev/null && ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -148,6 +166,10 @@ wait_for_transfer verify-ixfr
|
|||||||
# Ensure the new, good version of the zone was accepted.
|
# Ensure the new, good version of the zone was accepted.
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
||||||
|
# The log message announcing the mirror zone coming into effect should not have
|
||||||
|
# been logged this time since the mirror zone in question is expected to
|
||||||
|
# already be in use before this test case is checked.
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null && ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -158,7 +180,8 @@ nextpartreset ns3/named.run
|
|||||||
wait_for_load verify-load ${UPDATED_SERIAL_BAD} ns3/named.run
|
wait_for_load verify-load ${UPDATED_SERIAL_BAD} ns3/named.run
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-load SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-load SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||||
nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-load SOA" > /dev/null || ret=1
|
nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-load SOA" > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-load.*mirror zone is now in use" > /dev/null && ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -172,6 +195,7 @@ $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3
|
|||||||
wait_for_load verify-load ${UPDATED_SERIAL_GOOD} ns3/named.run
|
wait_for_load verify-load ${UPDATED_SERIAL_GOOD} ns3/named.run
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-load SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-load SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-load.*mirror zone is now in use" > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -181,12 +205,31 @@ ret=0
|
|||||||
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mirror ns3
|
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mirror ns3
|
||||||
cp ns3/verify-journal.db.mirror ns3/verify-ixfr.db.mirror
|
cp ns3/verify-journal.db.mirror ns3/verify-ixfr.db.mirror
|
||||||
cp ns3/verify-journal.db.bad.mirror.jnl ns3/verify-ixfr.db.mirror.jnl
|
cp ns3/verify-journal.db.bad.mirror.jnl ns3/verify-ixfr.db.mirror.jnl
|
||||||
|
# Temporarily disable transfers of the "verify-ixfr" zone on ns2. This is
|
||||||
|
# required to reliably test whether the message announcing the mirror zone
|
||||||
|
# coming into effect is not logged after a failed journal verification since
|
||||||
|
# otherwise a corrected version of the zone may be transferred after
|
||||||
|
# verification fails but before we look for the aforementioned log message.
|
||||||
|
# (NOTE: Keep the embedded newline in the sed function list below.)
|
||||||
|
sed '/^zone "verify-ixfr" {$/,/^};$/ {
|
||||||
|
s/10.53.0.3/10.53.0.254/
|
||||||
|
}' ns2/named.conf > ns2/named.conf.modified
|
||||||
|
mv ns2/named.conf.modified ns2/named.conf
|
||||||
|
rndc_reconfig ns2 10.53.0.2
|
||||||
nextpart ns3/named.run > /dev/null
|
nextpart ns3/named.run > /dev/null
|
||||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3
|
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3
|
||||||
wait_for_load verify-ixfr ${UPDATED_SERIAL_BAD} ns3/named.run
|
wait_for_load verify-ixfr ${UPDATED_SERIAL_BAD} ns3/named.run
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||||
nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1
|
nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null && ret=1
|
||||||
|
# Restore transfers for the "verify-ixfr" zone on ns2.
|
||||||
|
# (NOTE: Keep the embedded newline in the sed function list below.)
|
||||||
|
sed '/^zone "verify-ixfr" {$/,/^};$/ {
|
||||||
|
s/10.53.0.254/10.53.0.3/
|
||||||
|
}' ns2/named.conf > ns2/named.conf.modified
|
||||||
|
mv ns2/named.conf.modified ns2/named.conf
|
||||||
|
rndc_reconfig ns2 10.53.0.2
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -201,6 +244,7 @@ $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3
|
|||||||
wait_for_load verify-ixfr ${UPDATED_SERIAL_GOOD} ns3/named.run
|
wait_for_load verify-ixfr ${UPDATED_SERIAL_GOOD} ns3/named.run
|
||||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -301,7 +345,9 @@ grep "flags:.* ad" dig.out.ns3.test$n.1 > /dev/null || ret=1
|
|||||||
# Sanity check: the authoritative server should have been queried.
|
# Sanity check: the authoritative server should have been queried.
|
||||||
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" > /dev/null || ret=1
|
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" > /dev/null || ret=1
|
||||||
# Reconfigure ns2 so that the zone can be mirrored on ns3.
|
# Reconfigure ns2 so that the zone can be mirrored on ns3.
|
||||||
sed "s/10.53.0.254/10.53.0.3/;" ns2/named.conf > ns2/named.conf.modified
|
sed '/^zone "initially-unavailable" {$/,/^};$/ {
|
||||||
|
s/10.53.0.254/10.53.0.3/
|
||||||
|
}' ns2/named.conf > ns2/named.conf.modified
|
||||||
mv ns2/named.conf.modified ns2/named.conf
|
mv ns2/named.conf.modified ns2/named.conf
|
||||||
rndc_reconfig ns2 10.53.0.2
|
rndc_reconfig ns2 10.53.0.2
|
||||||
# Flush the cache on ns3 and retransfer the mirror zone.
|
# Flush the cache on ns3 and retransfer the mirror zone.
|
||||||
@@ -324,7 +370,9 @@ echo_i "checking that resolution succeeds with expired mirror zone data ($n)"
|
|||||||
ret=0
|
ret=0
|
||||||
# Reconfigure ns2 so that the zone from the previous test can no longer be
|
# Reconfigure ns2 so that the zone from the previous test can no longer be
|
||||||
# mirrored on ns3.
|
# mirrored on ns3.
|
||||||
sed "s/10.53.0.3/10.53.0.254/;" ns2/named.conf > ns2/named.conf.modified
|
sed '/^zone "initially-unavailable" {$/,/^};$/ {
|
||||||
|
s/10.53.0.3/10.53.0.254/
|
||||||
|
}' ns2/named.conf > ns2/named.conf.modified
|
||||||
mv ns2/named.conf.modified ns2/named.conf
|
mv ns2/named.conf.modified ns2/named.conf
|
||||||
rndc_reconfig ns2 10.53.0.2
|
rndc_reconfig ns2 10.53.0.2
|
||||||
# Stop ns3, update the timestamp of the zone file to one far in the past, then
|
# Stop ns3, update the timestamp of the zone file to one far in the past, then
|
||||||
@@ -335,7 +383,9 @@ nextpart ns3/named.run > /dev/null
|
|||||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3
|
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3
|
||||||
# Ensure named attempts to retransfer the zone due to its expiry.
|
# Ensure named attempts to retransfer the zone due to its expiry.
|
||||||
wait_for_transfer initially-unavailable
|
wait_for_transfer initially-unavailable
|
||||||
nextpart ns3/named.run | grep "initially-unavailable.*expired" > /dev/null || ret=1
|
# Ensure the expected messages were logged.
|
||||||
|
nextpartpeek ns3/named.run | grep "initially-unavailable.*expired" > /dev/null || ret=1
|
||||||
|
nextpartpeek ns3/named.run | grep "initially-unavailable.*mirror zone is no longer in use" > /dev/null || ret=1
|
||||||
# Query for a record in the expired zone. Resolution should still succeed.
|
# Query for a record in the expired zone. Resolution should still succeed.
|
||||||
$DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A > dig.out.ns3.test$n 2>&1 || ret=1
|
$DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A > dig.out.ns3.test$n 2>&1 || ret=1
|
||||||
# Check response code and flags in the answer.
|
# Check response code and flags in the answer.
|
||||||
|
|||||||
@@ -10,14 +10,15 @@
|
|||||||
# information regarding copyright ownership.
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
rm -f */K* */*.signed */trusted.conf */*.jnl */*.bk
|
rm -f */K* */*.signed */trusted.conf */*.jnl */*.bk
|
||||||
rm -f dsset-. ns1/dsset-.
|
|
||||||
rm -f ns*/named.lock
|
|
||||||
rm -f */managed-keys.bind* */named.secroots
|
|
||||||
rm -f */managed*.conf ns1/managed.key ns1/managed.key.id
|
rm -f */managed*.conf ns1/managed.key ns1/managed.key.id
|
||||||
|
rm -f */managed-keys.bind* */named.secroots
|
||||||
|
rm -f */named.conf
|
||||||
rm -f */named.memstats */named.run */named.run.prev
|
rm -f */named.memstats */named.run */named.run.prev
|
||||||
rm -f dig.out* delv.out* rndc.out* signer.out*
|
rm -f dig.out* delv.out* rndc.out* signer.out*
|
||||||
rm -f ns1/named.secroots ns1/root.db.signed* ns1/root.db.tmp
|
rm -f dsset-. ns1/dsset-.
|
||||||
rm -f */named.conf
|
|
||||||
rm -rf ns4/nope
|
|
||||||
rm -f ns5/named.args
|
|
||||||
rm -f ns*/managed-keys.bind*
|
rm -f ns*/managed-keys.bind*
|
||||||
|
rm -f ns*/named.lock
|
||||||
|
rm -f ns1/named.secroots ns1/root.db.signed* ns1/root.db.tmp
|
||||||
|
rm -f ns5/named.args
|
||||||
|
rm -f ns6/view1.mkeys ns6/view2.mkeys
|
||||||
|
rm -rf ns4/nope
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NS6
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.6;
|
||||||
|
notify-source 10.53.0.6;
|
||||||
|
transfer-source 10.53.0.6;
|
||||||
|
port @PORT@;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.6; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
recursion yes;
|
||||||
|
notify no;
|
||||||
|
dnssec-enable yes;
|
||||||
|
dnssec-validation auto;
|
||||||
|
bindkeys-file "managed.conf";
|
||||||
|
};
|
||||||
|
|
||||||
|
key rndc_key {
|
||||||
|
secret "1234abcd8765";
|
||||||
|
algorithm hmac-sha256;
|
||||||
|
};
|
||||||
|
|
||||||
|
controls {
|
||||||
|
inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||||
|
};
|
||||||
|
|
||||||
|
view view1 {
|
||||||
|
zone "." {
|
||||||
|
type hint;
|
||||||
|
file "../../common/root.hint";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
view view2 {
|
||||||
|
zone "." {
|
||||||
|
type hint;
|
||||||
|
file "../../common/root.hint";
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -19,6 +19,7 @@ copy_setports ns2/named.conf.in ns2/named.conf
|
|||||||
copy_setports ns3/named.conf.in ns3/named.conf
|
copy_setports ns3/named.conf.in ns3/named.conf
|
||||||
copy_setports ns4/named.conf.in ns4/named.conf
|
copy_setports ns4/named.conf.in ns4/named.conf
|
||||||
copy_setports ns5/named.conf.in ns5/named.conf
|
copy_setports ns5/named.conf.in ns5/named.conf
|
||||||
|
copy_setports ns6/named.conf.in ns6/named.conf
|
||||||
|
|
||||||
cp ns5/named1.args ns5/named.args
|
cp ns5/named1.args ns5/named.args
|
||||||
|
|
||||||
|
|||||||
@@ -755,5 +755,20 @@ grep "status: NOERROR" dig.out.ns5.b.test$n > /dev/null || ret=1
|
|||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo_i "check 'rndc managed-keys' and views ($n)"
|
||||||
|
ret=0
|
||||||
|
$RNDCCMD 10.53.0.6 managed-keys refresh in view1 > rndc.out.ns6.view1.test$n || ret=1
|
||||||
|
grep "refreshing managed keys for 'view1'" rndc.out.ns6.view1.test$n > /dev/null || ret=1
|
||||||
|
lines=`wc -l < rndc.out.ns6.view1.test$n`
|
||||||
|
[ $lines -eq 1 ] || ret=1
|
||||||
|
$RNDCCMD 10.53.0.6 managed-keys refresh > rndc.out.ns6.view2.test$n || ret=1
|
||||||
|
lines=`wc -l < rndc.out.ns6.view2.test$n`
|
||||||
|
grep "refreshing managed keys for 'view1'" rndc.out.ns6.view2.test$n > /dev/null || ret=1
|
||||||
|
grep "refreshing managed keys for 'view2'" rndc.out.ns6.view2.test$n > /dev/null || ret=1
|
||||||
|
[ $lines -eq 2 ] || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo_i "exit status: $status"
|
echo_i "exit status: $status"
|
||||||
[ $status -eq 0 ] || exit 1
|
[ $status -eq 0 ] || exit 1
|
||||||
|
|||||||
+56
-43
@@ -7053,18 +7053,24 @@ options {
|
|||||||
<term><command>allow-notify</command></term>
|
<term><command>allow-notify</command></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies which hosts are allowed to
|
This ACL specifies which hosts may send NOTIFY messages
|
||||||
notify this server, a slave, of zone changes in addition
|
to inform this server of changes to zones for which it
|
||||||
to the zone masters.
|
is acting as a secondary server. This is only
|
||||||
<command>allow-notify</command> may also be
|
applicable for secondary zones (i.e., type
|
||||||
specified in the
|
<literal>secondary</literal> or <literal>slave</literal>).
|
||||||
<command>zone</command> statement, in which case
|
</para>
|
||||||
it overrides the
|
<para>
|
||||||
<command>options allow-notify</command>
|
If this option is set in <command>view</command> or
|
||||||
statement. It is only meaningful
|
<command>options</command>, it is globally applied to
|
||||||
for a slave zone. If not specified, the default is to
|
all secondary zones. If set in the <command>zone</command>
|
||||||
process notify messages
|
statement, the global value is overridden.
|
||||||
only from a zone's master.
|
</para>
|
||||||
|
<para>
|
||||||
|
If not specified, the default is to process NOTIFY
|
||||||
|
messages only from the configured
|
||||||
|
<command>masters</command> for the zone.
|
||||||
|
<command>allow-notify</command> can be used to expand the
|
||||||
|
list of permitted hosts, not to reduce it.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -7199,11 +7205,16 @@ options {
|
|||||||
<term><command>allow-update</command></term>
|
<term><command>allow-update</command></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies which hosts are allowed to
|
When set in the <command>zone</command> statement for
|
||||||
submit Dynamic DNS updates for master zones. The default is
|
a master zone, specifies which hosts are allowed to
|
||||||
to deny
|
submit Dynamic DNS updates to that zone. The default
|
||||||
updates from all hosts. Note that allowing updates based
|
is to deny updates from all hosts. This can only
|
||||||
on the requestor's IP address is insecure; see
|
be set at the <command>zone</command> level, not in
|
||||||
|
<command>options</command> or <command>view</command>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Note that allowing updates based on the
|
||||||
|
requestor's IP address is insecure; see
|
||||||
<xref linkend="dynamic_update_security"/> for details.
|
<xref linkend="dynamic_update_security"/> for details.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@@ -7213,29 +7224,30 @@ options {
|
|||||||
<term><command>allow-update-forwarding</command></term>
|
<term><command>allow-update-forwarding</command></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies which hosts are allowed to
|
When set in the <command>zone</command> statement for
|
||||||
submit Dynamic DNS updates to slave zones to be forwarded to
|
a slave zone, specifies which hosts are allowed to
|
||||||
the
|
submit Dynamic DNS updates and have them be forwarded
|
||||||
master. The default is <userinput>{ none; }</userinput>,
|
to the master. The default is
|
||||||
which
|
<userinput>{ none; }</userinput>, which means that no
|
||||||
means that no update forwarding will be performed. To
|
update forwarding will be performed. This can only be
|
||||||
enable
|
set at the <command>zone</command> level, not in
|
||||||
update forwarding, specify
|
<command>options</command> or <command>view</command>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
To enable update forwarding, specify
|
||||||
<userinput>allow-update-forwarding { any; };</userinput>.
|
<userinput>allow-update-forwarding { any; };</userinput>.
|
||||||
Specifying values other than <userinput>{ none; }</userinput> or
|
in the <command>zone</command> statement.
|
||||||
<userinput>{ any; }</userinput> is usually
|
Specifying values other than <userinput>{ none; }</userinput>
|
||||||
counterproductive, since
|
or <userinput>{ any; }</userinput> is usually
|
||||||
the responsibility for update access control should rest
|
counterproductive; the responsibility for update
|
||||||
with the
|
access control should rest with the master server, not
|
||||||
master server, not the slaves.
|
the slave.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Note that enabling the update forwarding feature on a slave
|
Note that enabling the update forwarding feature on a slave
|
||||||
server
|
server may expose master servers to attacks if they rely
|
||||||
may expose master servers relying on insecure IP address
|
on insecure IP-address-based access control; see
|
||||||
based
|
<xref linkend="dynamic_update_security"/> for more details.
|
||||||
access control to attacks; see <xref linkend="dynamic_update_security"/>
|
|
||||||
for more details.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -7259,13 +7271,14 @@ options {
|
|||||||
<term xml:id="allow_transfer_term"><command>allow-transfer</command></term>
|
<term xml:id="allow_transfer_term"><command>allow-transfer</command></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies which hosts are allowed to
|
Specifies which hosts are allowed to receive zone
|
||||||
receive zone transfers from the server. <command>allow-transfer</command> may
|
transfers from the server. <command>allow-transfer</command>
|
||||||
also be specified in the <command>zone</command>
|
may also be specified in the <command>zone</command>
|
||||||
statement, in which
|
statement, in which case it overrides the
|
||||||
case it overrides the <command>options allow-transfer</command> statement.
|
<command>allow-transfer</command> statement set in
|
||||||
If not specified, the default is to allow transfers to all
|
<command>options</command> or <command>view</command>.
|
||||||
hosts.
|
If not specified, the default is to allow transfers to
|
||||||
|
all hosts.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|||||||
@@ -484,6 +484,43 @@ check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
check_non_viewacls(const cfg_obj_t *voptions, const cfg_obj_t *config,
|
||||||
|
isc_log_t *logctx)
|
||||||
|
{
|
||||||
|
const cfg_obj_t *aclobj = NULL;
|
||||||
|
const cfg_obj_t *options;
|
||||||
|
const char *where = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
static const char *acls[] = {
|
||||||
|
"allow-update", "allow-update-forwarding", NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; acls[i] != NULL; i++) {
|
||||||
|
if (voptions != NULL && aclobj == NULL) {
|
||||||
|
cfg_map_get(voptions, acls[i], &aclobj);
|
||||||
|
where = "view";
|
||||||
|
}
|
||||||
|
if (config != NULL && aclobj == NULL) {
|
||||||
|
options = NULL;
|
||||||
|
cfg_map_get(config, "options", &options);
|
||||||
|
if (options != NULL) {
|
||||||
|
cfg_map_get(options, acls[i], &aclobj);
|
||||||
|
where = "options";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aclobj != NULL) {
|
||||||
|
cfg_obj_log(aclobj, logctx, ISC_LOG_ERROR,
|
||||||
|
"'%s' can only be set per-zone, "
|
||||||
|
"not in '%s'", acls[i], where);
|
||||||
|
return (ISC_R_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned char zeros[16];
|
static const unsigned char zeros[16];
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@@ -3692,6 +3729,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||||||
if (tresult != ISC_R_SUCCESS)
|
if (tresult != ISC_R_SUCCESS)
|
||||||
result = tresult;
|
result = tresult;
|
||||||
|
|
||||||
|
tresult = check_non_viewacls(voptions, config, logctx);
|
||||||
|
if (tresult != ISC_R_SUCCESS) {
|
||||||
|
result = tresult;
|
||||||
|
}
|
||||||
|
|
||||||
tresult = check_recursionacls(actx, voptions, viewname,
|
tresult = check_recursionacls(actx, voptions, viewname,
|
||||||
config, logctx, mctx);
|
config, logctx, mctx);
|
||||||
if (tresult != ISC_R_SUCCESS)
|
if (tresult != ISC_R_SUCCESS)
|
||||||
|
|||||||
+34
-8
@@ -2791,9 +2791,8 @@ dns_adb_detach(dns_adb_t **adbx) {
|
|||||||
adb = *adbx;
|
adb = *adbx;
|
||||||
*adbx = NULL;
|
*adbx = NULL;
|
||||||
|
|
||||||
INSIST(adb->erefcnt > 0);
|
|
||||||
|
|
||||||
LOCK(&adb->reflock);
|
LOCK(&adb->reflock);
|
||||||
|
INSIST(adb->erefcnt > 0);
|
||||||
adb->erefcnt--;
|
adb->erefcnt--;
|
||||||
need_exit_check = (adb->erefcnt == 0 && adb->irefcnt == 0);
|
need_exit_check = (adb->erefcnt == 0 && adb->irefcnt == 0);
|
||||||
UNLOCK(&adb->reflock);
|
UNLOCK(&adb->reflock);
|
||||||
@@ -3407,28 +3406,44 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
|
|||||||
adb, adb->erefcnt, adb->irefcnt,
|
adb, adb->erefcnt, adb->irefcnt,
|
||||||
isc_mempool_getallocated(adb->nhmp));
|
isc_mempool_getallocated(adb->nhmp));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In TSAN mode we need to lock the locks individually, as TSAN
|
||||||
|
* can't handle more than 64 locks locked by one thread.
|
||||||
|
* In regular mode we want a consistent dump so we need to
|
||||||
|
* lock everything.
|
||||||
|
*/
|
||||||
|
#ifndef __SANITIZE_THREAD__
|
||||||
for (i = 0; i < adb->nnames; i++)
|
for (i = 0; i < adb->nnames; i++)
|
||||||
LOCK(&adb->namelocks[i]);
|
LOCK(&adb->namelocks[i]);
|
||||||
for (i = 0; i < adb->nentries; i++)
|
for (i = 0; i < adb->nentries; i++)
|
||||||
LOCK(&adb->entrylocks[i]);
|
LOCK(&adb->entrylocks[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump the names
|
* Dump the names
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < adb->nnames; i++) {
|
for (i = 0; i < adb->nnames; i++) {
|
||||||
|
#ifdef __SANITIZE_THREAD__
|
||||||
|
LOCK(&adb->namelocks[i]);
|
||||||
|
#endif
|
||||||
name = ISC_LIST_HEAD(adb->names[i]);
|
name = ISC_LIST_HEAD(adb->names[i]);
|
||||||
if (name == NULL)
|
if (name == NULL) {
|
||||||
|
#ifdef __SANITIZE_THREAD__
|
||||||
|
UNLOCK(&adb->namelocks[i]);
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
if (debug)
|
}
|
||||||
|
if (debug) {
|
||||||
fprintf(f, "; bucket %u\n", i);
|
fprintf(f, "; bucket %u\n", i);
|
||||||
|
}
|
||||||
for (;
|
for (;
|
||||||
name != NULL;
|
name != NULL;
|
||||||
name = ISC_LIST_NEXT(name, plink))
|
name = ISC_LIST_NEXT(name, plink))
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug) {
|
||||||
fprintf(f, "; name %p (flags %08x)\n",
|
fprintf(f, "; name %p (flags %08x)\n",
|
||||||
name, name->flags);
|
name, name->flags);
|
||||||
|
}
|
||||||
fprintf(f, "; ");
|
fprintf(f, "; ");
|
||||||
print_dns_name(f, &name->name);
|
print_dns_name(f, &name->name);
|
||||||
if (dns_name_countlabels(&name->target) > 0) {
|
if (dns_name_countlabels(&name->target) > 0) {
|
||||||
@@ -3456,26 +3471,37 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
|
|||||||
print_find_list(f, name);
|
print_find_list(f, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef __SANITIZE_THREAD__
|
||||||
|
UNLOCK(&adb->namelocks[i]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, ";\n; Unassociated entries\n;\n");
|
fprintf(f, ";\n; Unassociated entries\n;\n");
|
||||||
|
|
||||||
for (i = 0; i < adb->nentries; i++) {
|
for (i = 0; i < adb->nentries; i++) {
|
||||||
|
#ifdef __SANITIZE_THREAD__
|
||||||
|
LOCK(&adb->entrylocks[i]);
|
||||||
|
#endif
|
||||||
entry = ISC_LIST_HEAD(adb->entries[i]);
|
entry = ISC_LIST_HEAD(adb->entries[i]);
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
if (entry->nh == 0)
|
if (entry->nh == 0)
|
||||||
dump_entry(f, adb, entry, debug, now);
|
dump_entry(f, adb, entry, debug, now);
|
||||||
entry = ISC_LIST_NEXT(entry, plink);
|
entry = ISC_LIST_NEXT(entry, plink);
|
||||||
}
|
}
|
||||||
|
#ifdef __SANITIZE_THREAD__
|
||||||
|
UNLOCK(&adb->entrylocks[i]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __SANITIZE_THREAD__
|
||||||
/*
|
/*
|
||||||
* Unlock everything
|
* Unlock everything
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < adb->nentries; i++)
|
for (i = adb->nentries-1; i >= 0; i--)
|
||||||
UNLOCK(&adb->entrylocks[i]);
|
UNLOCK(&adb->entrylocks[i]);
|
||||||
for (i = 0; i < adb->nnames; i++)
|
for (i = adb->nnames-1; i >= 0; i--)
|
||||||
UNLOCK(&adb->namelocks[i]);
|
UNLOCK(&adb->namelocks[i]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
+29
-22
@@ -76,9 +76,10 @@ struct dns_dispatchmgr {
|
|||||||
/* locked by buffer_lock */
|
/* locked by buffer_lock */
|
||||||
dns_qid_t *qid;
|
dns_qid_t *qid;
|
||||||
isc_mutex_t buffer_lock;
|
isc_mutex_t buffer_lock;
|
||||||
unsigned int buffers; /*%< allocated buffers */
|
|
||||||
unsigned int buffersize; /*%< size of each buffer */
|
unsigned int buffersize; /*%< size of each buffer */
|
||||||
unsigned int maxbuffers; /*%< max buffers */
|
/* not locked */
|
||||||
|
atomic_uint_fast32_t buffers; /*%< allocated buffers */
|
||||||
|
atomic_uint_fast32_t maxbuffers; /*%< max buffers */
|
||||||
|
|
||||||
/* Locked internally. */
|
/* Locked internally. */
|
||||||
isc_mutex_t depool_lock;
|
isc_mutex_t depool_lock;
|
||||||
@@ -900,9 +901,8 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
|
|||||||
break;
|
break;
|
||||||
case isc_sockettype_udp:
|
case isc_sockettype_udp:
|
||||||
LOCK(&disp->mgr->buffer_lock);
|
LOCK(&disp->mgr->buffer_lock);
|
||||||
INSIST(disp->mgr->buffers > 0);
|
|
||||||
INSIST(len == disp->mgr->buffersize);
|
INSIST(len == disp->mgr->buffersize);
|
||||||
disp->mgr->buffers--;
|
INSIST(atomic_fetch_sub(&disp->mgr->buffers, 1) > 0);
|
||||||
bpool = disp->mgr->bpool;
|
bpool = disp->mgr->bpool;
|
||||||
UNLOCK(&disp->mgr->buffer_lock);
|
UNLOCK(&disp->mgr->buffer_lock);
|
||||||
isc_mempool_put(bpool, buf);
|
isc_mempool_put(bpool, buf);
|
||||||
@@ -918,17 +918,15 @@ allocate_udp_buffer(dns_dispatch_t *disp) {
|
|||||||
isc_mempool_t *bpool;
|
isc_mempool_t *bpool;
|
||||||
void *temp;
|
void *temp;
|
||||||
|
|
||||||
|
atomic_fetch_add(&disp->mgr->buffers, 1);
|
||||||
LOCK(&disp->mgr->buffer_lock);
|
LOCK(&disp->mgr->buffer_lock);
|
||||||
bpool = disp->mgr->bpool;
|
bpool = disp->mgr->bpool;
|
||||||
disp->mgr->buffers++;
|
|
||||||
UNLOCK(&disp->mgr->buffer_lock);
|
UNLOCK(&disp->mgr->buffer_lock);
|
||||||
|
|
||||||
temp = isc_mempool_get(bpool);
|
temp = isc_mempool_get(bpool);
|
||||||
|
|
||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
LOCK(&disp->mgr->buffer_lock);
|
atomic_fetch_sub(&disp->mgr->buffers, 1);
|
||||||
disp->mgr->buffers--;
|
|
||||||
UNLOCK(&disp->mgr->buffer_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (temp);
|
return (temp);
|
||||||
@@ -1050,8 +1048,9 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
|||||||
qid = mgr->qid;
|
qid = mgr->qid;
|
||||||
|
|
||||||
dispatch_log(disp, LVL(90),
|
dispatch_log(disp, LVL(90),
|
||||||
"got packet: requests %d, buffers %d, recvs %d",
|
"got packet: requests %d, buffers %lu, recvs %d",
|
||||||
disp->requests, disp->mgr->buffers, disp->recv_pending);
|
disp->requests, atomic_load(&disp->mgr->buffers),
|
||||||
|
disp->recv_pending);
|
||||||
|
|
||||||
if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) {
|
if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) {
|
||||||
/*
|
/*
|
||||||
@@ -1338,12 +1337,13 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
|
|||||||
|
|
||||||
qid = disp->qid;
|
qid = disp->qid;
|
||||||
|
|
||||||
|
|
||||||
|
LOCK(&disp->lock);
|
||||||
|
|
||||||
dispatch_log(disp, LVL(90),
|
dispatch_log(disp, LVL(90),
|
||||||
"got TCP packet: requests %d, buffers %d, recvs %d",
|
"got TCP packet: requests %d, buffers %d, recvs %d",
|
||||||
disp->requests, disp->tcpbuffers, disp->recv_pending);
|
disp->requests, disp->tcpbuffers, disp->recv_pending);
|
||||||
|
|
||||||
LOCK(&disp->lock);
|
|
||||||
|
|
||||||
INSIST(disp->recv_pending != 0);
|
INSIST(disp->recv_pending != 0);
|
||||||
disp->recv_pending = 0;
|
disp->recv_pending = 0;
|
||||||
|
|
||||||
@@ -1493,26 +1493,33 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
|||||||
isc_region_t region;
|
isc_region_t region;
|
||||||
isc_socket_t *sock;
|
isc_socket_t *sock;
|
||||||
|
|
||||||
if (disp->shutting_down == 1)
|
if (disp->shutting_down == 1) {
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
|
if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) {
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
if (disp->recv_pending != 0 && dispsock == NULL)
|
if (disp->recv_pending != 0 && dispsock == NULL) {
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
if (disp->mgr->buffers >= disp->mgr->maxbuffers)
|
if (atomic_load(&disp->mgr->buffers) >=
|
||||||
|
atomic_load(&disp->mgr->maxbuffers)) {
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
|
if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
|
||||||
dispsock == NULL)
|
dispsock == NULL) {
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
if (dispsock != NULL)
|
if (dispsock != NULL) {
|
||||||
sock = dispsock->socket;
|
sock = dispsock->socket;
|
||||||
else
|
} else {
|
||||||
sock = disp->socket;
|
sock = disp->socket;
|
||||||
|
}
|
||||||
INSIST(sock != NULL);
|
INSIST(sock != NULL);
|
||||||
|
|
||||||
switch (disp->socktype) {
|
switch (disp->socktype) {
|
||||||
@@ -1807,9 +1814,9 @@ dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp)
|
|||||||
isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock);
|
isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock);
|
||||||
isc_mempool_setfillcount(mgr->dpool, 32);
|
isc_mempool_setfillcount(mgr->dpool, 32);
|
||||||
|
|
||||||
mgr->buffers = 0;
|
atomic_store(&mgr->buffers, 0);
|
||||||
mgr->buffersize = 0;
|
mgr->buffersize = 0;
|
||||||
mgr->maxbuffers = 0;
|
atomic_store(&mgr->maxbuffers, 0);
|
||||||
mgr->bpool = NULL;
|
mgr->bpool = NULL;
|
||||||
mgr->spool = NULL;
|
mgr->spool = NULL;
|
||||||
mgr->qid = NULL;
|
mgr->qid = NULL;
|
||||||
@@ -2043,7 +2050,7 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
mgr->buffersize = buffersize;
|
mgr->buffersize = buffersize;
|
||||||
mgr->maxbuffers = maxbuffers;
|
atomic_store(&mgr->maxbuffers, maxbuffers);
|
||||||
UNLOCK(&mgr->buffer_lock);
|
UNLOCK(&mgr->buffer_lock);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ typedef enum {
|
|||||||
when doing qname
|
when doing qname
|
||||||
minimization on
|
minimization on
|
||||||
ip6.arpa. */
|
ip6.arpa. */
|
||||||
|
#define DNS_FETCHOPT_NOFORWARD 0x00080000 /*%< Do not use forwarders
|
||||||
|
if possible. */
|
||||||
|
|
||||||
/* Reserved in use by adb.c 0x00400000 */
|
/* Reserved in use by adb.c 0x00400000 */
|
||||||
#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
|
#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
|
||||||
|
|||||||
@@ -837,6 +837,7 @@ pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, const char *label,
|
|||||||
|
|
||||||
attr->type = CKA_EC_PARAMS;
|
attr->type = CKA_EC_PARAMS;
|
||||||
pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS);
|
pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS);
|
||||||
|
INSIST(pubattr != NULL);
|
||||||
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
||||||
if (attr->pValue == NULL)
|
if (attr->pValue == NULL)
|
||||||
DST_RET(ISC_R_NOMEMORY);
|
DST_RET(ISC_R_NOMEMORY);
|
||||||
@@ -846,6 +847,7 @@ pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, const char *label,
|
|||||||
|
|
||||||
attr->type = CKA_EC_POINT;
|
attr->type = CKA_EC_POINT;
|
||||||
pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT);
|
pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT);
|
||||||
|
INSIST(pubattr != NULL);
|
||||||
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
||||||
if (attr->pValue == NULL)
|
if (attr->pValue == NULL)
|
||||||
DST_RET(ISC_R_NOMEMORY);
|
DST_RET(ISC_R_NOMEMORY);
|
||||||
|
|||||||
@@ -1673,6 +1673,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
|
|||||||
|
|
||||||
attr->type = CKA_MODULUS;
|
attr->type = CKA_MODULUS;
|
||||||
pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
|
pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
|
||||||
|
INSIST(pubattr != NULL);
|
||||||
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
||||||
if (attr->pValue == NULL)
|
if (attr->pValue == NULL)
|
||||||
DST_RET(ISC_R_NOMEMORY);
|
DST_RET(ISC_R_NOMEMORY);
|
||||||
@@ -1682,6 +1683,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
|
|||||||
|
|
||||||
attr->type = CKA_PUBLIC_EXPONENT;
|
attr->type = CKA_PUBLIC_EXPONENT;
|
||||||
pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
|
pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
|
||||||
|
INSIST(pubattr != NULL);
|
||||||
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
|
||||||
if (attr->pValue == NULL)
|
if (attr->pValue == NULL)
|
||||||
DST_RET(ISC_R_NOMEMORY);
|
DST_RET(ISC_R_NOMEMORY);
|
||||||
|
|||||||
+36
-15
@@ -1919,6 +1919,15 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||||||
|
|
||||||
srtt = addrinfo->srtt;
|
srtt = addrinfo->srtt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow an additional second for the kernel to resend the SYN (or
|
||||||
|
* SYN without ECN in the case of stupid firewalls blocking ECN
|
||||||
|
* negotiation) over the current RTT estimate.
|
||||||
|
*/
|
||||||
|
if ((options & DNS_FETCHOPT_TCP) != 0) {
|
||||||
|
srtt += 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A forwarder needs to make multiple queries. Give it at least
|
* A forwarder needs to make multiple queries. Give it at least
|
||||||
* a second to do these in.
|
* a second to do these in.
|
||||||
@@ -3501,6 +3510,18 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
|
|||||||
INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
|
INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
|
||||||
INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
|
INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have DNS_FETCHOPT_NOFORWARD set and forwarding policy
|
||||||
|
* allows us to not forward - skip forwarders and go straight
|
||||||
|
* to NSes. This is currently used to make sure that priming query
|
||||||
|
* gets root servers' IP addresses in ADDITIONAL section.
|
||||||
|
*/
|
||||||
|
if ((fctx->options & DNS_FETCHOPT_NOFORWARD) != 0 &&
|
||||||
|
(fctx->fwdpolicy != dns_fwdpolicy_only))
|
||||||
|
{
|
||||||
|
goto normal_nses;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this fctx has forwarders, use them; otherwise use any
|
* If this fctx has forwarders, use them; otherwise use any
|
||||||
* selective forwarders specified in the view; otherwise use the
|
* selective forwarders specified in the view; otherwise use the
|
||||||
@@ -3586,7 +3607,7 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
|
|||||||
/*
|
/*
|
||||||
* Normal nameservers.
|
* Normal nameservers.
|
||||||
*/
|
*/
|
||||||
|
normal_nses:
|
||||||
stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;
|
stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;
|
||||||
if (fctx->restarts == 1) {
|
if (fctx->restarts == 1) {
|
||||||
/*
|
/*
|
||||||
@@ -4031,9 +4052,11 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
|
|||||||
options &= ~DNS_FETCHOPT_QMINIMIZE;
|
options &= ~DNS_FETCHOPT_QMINIMIZE;
|
||||||
fctx_increference(fctx);
|
fctx_increference(fctx);
|
||||||
task = res->buckets[bucketnum].task;
|
task = res->buckets[bucketnum].task;
|
||||||
|
fctx_stoptimer(fctx);
|
||||||
result = dns_resolver_createfetch(fctx->res, &fctx->qminname,
|
result = dns_resolver_createfetch(fctx->res, &fctx->qminname,
|
||||||
fctx->qmintype, &fctx->domain,
|
fctx->qmintype, &fctx->domain,
|
||||||
&fctx->nameservers, NULL, NULL, 0,
|
&fctx->nameservers,
|
||||||
|
NULL, NULL, 0,
|
||||||
options, 0, fctx->qc, task,
|
options, 0, fctx->qc, task,
|
||||||
resume_qmin, fctx,
|
resume_qmin, fctx,
|
||||||
&fctx->qminrrset, NULL,
|
&fctx->qminrrset, NULL,
|
||||||
@@ -4362,13 +4385,12 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) {
|
|||||||
* timer.
|
* timer.
|
||||||
*/
|
*/
|
||||||
result = fctx_starttimer(fctx);
|
result = fctx_starttimer(fctx);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS) {
|
||||||
fctx_done(fctx, result, __LINE__);
|
fctx_done(fctx, result, __LINE__);
|
||||||
else
|
} else {
|
||||||
/*
|
/* Keep trying */
|
||||||
* Keep trying.
|
|
||||||
*/
|
|
||||||
fctx_try(fctx, true, false);
|
fctx_try(fctx, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
@@ -10115,16 +10137,16 @@ prime_done(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
UNUSED(task);
|
UNUSED(task);
|
||||||
|
|
||||||
|
LOCK(&res->primelock);
|
||||||
LOCK(&res->lock);
|
LOCK(&res->lock);
|
||||||
|
|
||||||
INSIST(res->priming);
|
INSIST(res->priming);
|
||||||
res->priming = false;
|
res->priming = false;
|
||||||
LOCK(&res->primelock);
|
|
||||||
fetch = res->primefetch;
|
fetch = res->primefetch;
|
||||||
res->primefetch = NULL;
|
res->primefetch = NULL;
|
||||||
UNLOCK(&res->primelock);
|
|
||||||
|
|
||||||
UNLOCK(&res->lock);
|
UNLOCK(&res->lock);
|
||||||
|
UNLOCK(&res->primelock);
|
||||||
|
|
||||||
if (fevent->result == ISC_R_SUCCESS &&
|
if (fevent->result == ISC_R_SUCCESS &&
|
||||||
res->view->cache != NULL && res->view->hints != NULL) {
|
res->view->cache != NULL && res->view->hints != NULL) {
|
||||||
@@ -10192,12 +10214,11 @@ dns_resolver_prime(dns_resolver_t *res) {
|
|||||||
LOCK(&res->primelock);
|
LOCK(&res->primelock);
|
||||||
result = dns_resolver_createfetch(res, dns_rootname,
|
result = dns_resolver_createfetch(res, dns_rootname,
|
||||||
dns_rdatatype_ns,
|
dns_rdatatype_ns,
|
||||||
NULL, NULL, NULL, NULL, 0, 0,
|
NULL, NULL, NULL, NULL, 0,
|
||||||
0, NULL,
|
DNS_FETCHOPT_NOFORWARD, 0,
|
||||||
res->buckets[0].task,
|
NULL, res->buckets[0].task,
|
||||||
prime_done,
|
prime_done, res, rdataset,
|
||||||
res, rdataset, NULL,
|
NULL, &res->primefetch);
|
||||||
&res->primefetch);
|
|
||||||
UNLOCK(&res->primelock);
|
UNLOCK(&res->primelock);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
isc_mem_put(res->mctx, rdataset, sizeof(*rdataset));
|
isc_mem_put(res->mctx, rdataset, sizeof(*rdataset));
|
||||||
|
|||||||
+15
-11
@@ -2432,20 +2432,24 @@ dns_view_loadnta(dns_view_t *view) {
|
|||||||
void
|
void
|
||||||
dns_view_setviewcommit(dns_view_t *view) {
|
dns_view_setviewcommit(dns_view_t *view) {
|
||||||
REQUIRE(DNS_VIEW_VALID(view));
|
REQUIRE(DNS_VIEW_VALID(view));
|
||||||
|
dns_zone_t *redirect, *managed_keys;
|
||||||
|
dns_zt_t *zonetable;
|
||||||
|
|
||||||
LOCK(&view->lock);
|
LOCK(&view->lock);
|
||||||
|
redirect = view->redirect;
|
||||||
if (view->redirect != NULL) {
|
managed_keys = view->managed_keys;
|
||||||
dns_zone_setviewcommit(view->redirect);
|
zonetable = view->zonetable;
|
||||||
}
|
|
||||||
if (view->managed_keys != NULL) {
|
|
||||||
dns_zone_setviewcommit(view->managed_keys);
|
|
||||||
}
|
|
||||||
if (view->zonetable != NULL) {
|
|
||||||
dns_zt_setviewcommit(view->zonetable);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNLOCK(&view->lock);
|
UNLOCK(&view->lock);
|
||||||
|
|
||||||
|
if (redirect != NULL) {
|
||||||
|
dns_zone_setviewcommit(redirect);
|
||||||
|
}
|
||||||
|
if (managed_keys != NULL) {
|
||||||
|
dns_zone_setviewcommit(managed_keys);
|
||||||
|
}
|
||||||
|
if (zonetable != NULL) {
|
||||||
|
dns_zt_setviewcommit(zonetable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+22
-1
@@ -133,6 +133,13 @@ struct dns_xfrin_ctx {
|
|||||||
dns_tcpmsg_t tcpmsg;
|
dns_tcpmsg_t tcpmsg;
|
||||||
bool tcpmsg_valid;
|
bool tcpmsg_valid;
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Whether the zone originally had a database attached at the time this
|
||||||
|
* transfer context was created. Used by maybe_free() when making
|
||||||
|
* logging decisions.
|
||||||
|
*/
|
||||||
|
bool zone_had_db;
|
||||||
|
|
||||||
dns_db_t *db;
|
dns_db_t *db;
|
||||||
dns_dbversion_t *ver;
|
dns_dbversion_t *ver;
|
||||||
dns_diff_t diff; /*%< Pending database changes */
|
dns_diff_t diff; /*%< Pending database changes */
|
||||||
@@ -657,6 +664,10 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
|
|||||||
dns_zone_getclass(zone), xfrtype, masteraddr,
|
dns_zone_getclass(zone), xfrtype, masteraddr,
|
||||||
sourceaddr, dscp, tsigkey, &xfr));
|
sourceaddr, dscp, tsigkey, &xfr));
|
||||||
|
|
||||||
|
if (db != NULL) {
|
||||||
|
xfr->zone_had_db = true;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(xfrin_start(xfr));
|
CHECK(xfrin_start(xfr));
|
||||||
|
|
||||||
xfr->done = done;
|
xfr->done = done;
|
||||||
@@ -821,6 +832,7 @@ xfrin_create(isc_mem_t *mctx,
|
|||||||
/* tcpmsg */
|
/* tcpmsg */
|
||||||
xfr->tcpmsg_valid = false;
|
xfr->tcpmsg_valid = false;
|
||||||
|
|
||||||
|
xfr->zone_had_db = false;
|
||||||
xfr->db = NULL;
|
xfr->db = NULL;
|
||||||
if (db != NULL)
|
if (db != NULL)
|
||||||
dns_db_attach(db, &xfr->db);
|
dns_db_attach(db, &xfr->db);
|
||||||
@@ -1513,8 +1525,17 @@ maybe_free(dns_xfrin_ctx_t *xfr) {
|
|||||||
if (xfr->db != NULL)
|
if (xfr->db != NULL)
|
||||||
dns_db_detach(&xfr->db);
|
dns_db_detach(&xfr->db);
|
||||||
|
|
||||||
if (xfr->zone != NULL)
|
if (xfr->zone != NULL) {
|
||||||
|
if (!xfr->zone_had_db &&
|
||||||
|
xfr->shuttingdown &&
|
||||||
|
xfr->shutdown_result == ISC_R_SUCCESS &&
|
||||||
|
dns_zone_gettype(xfr->zone) == dns_zone_mirror)
|
||||||
|
{
|
||||||
|
dns_zone_log(xfr->zone, ISC_LOG_INFO,
|
||||||
|
"mirror zone is now in use");
|
||||||
|
}
|
||||||
dns_zone_idetach(&xfr->zone);
|
dns_zone_idetach(&xfr->zone);
|
||||||
|
}
|
||||||
|
|
||||||
isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
|
isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4440,6 +4440,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||||||
bool needdump = false;
|
bool needdump = false;
|
||||||
bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
|
bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
|
||||||
bool nomaster = false;
|
bool nomaster = false;
|
||||||
|
bool had_db = false;
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
dns_include_t *inc;
|
dns_include_t *inc;
|
||||||
|
|
||||||
@@ -4804,6 +4805,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||||||
|
|
||||||
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
|
had_db = true;
|
||||||
result = zone_replacedb(zone, db, false);
|
result = zone_replacedb(zone, db, false);
|
||||||
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -4915,6 +4917,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||||||
dns_db_issecure(db) ? " (DNSSEC signed)" : "");
|
dns_db_issecure(db) ? " (DNSSEC signed)" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!had_db && zone->type == dns_zone_mirror) {
|
||||||
|
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
|
||||||
|
"mirror zone is now in use");
|
||||||
|
}
|
||||||
|
|
||||||
zone->loadtime = loadtime;
|
zone->loadtime = loadtime;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -10838,6 +10845,12 @@ zone_unload(dns_zone_t *zone) {
|
|||||||
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
|
||||||
|
|
||||||
|
if (zone->type == dns_zone_mirror) {
|
||||||
|
dns_zone_log(zone, ISC_LOG_INFO,
|
||||||
|
"mirror zone is no longer in use; "
|
||||||
|
"reverting to normal recursion");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+27
-29
@@ -48,10 +48,11 @@ struct dns_zt {
|
|||||||
void * loaddone_arg;
|
void * loaddone_arg;
|
||||||
struct zt_load_params *loadparams;
|
struct zt_load_params *loadparams;
|
||||||
/* Locked by lock. */
|
/* Locked by lock. */
|
||||||
bool flush;
|
bool flush;
|
||||||
uint32_t references;
|
|
||||||
unsigned int loads_pending;
|
|
||||||
dns_rbt_t *table;
|
dns_rbt_t *table;
|
||||||
|
/* Atomic */
|
||||||
|
isc_refcount_t refs;
|
||||||
|
isc_refcount_t loads_pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l')
|
#define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l')
|
||||||
@@ -95,14 +96,14 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
|
|||||||
|
|
||||||
zt->mctx = NULL;
|
zt->mctx = NULL;
|
||||||
isc_mem_attach(mctx, &zt->mctx);
|
isc_mem_attach(mctx, &zt->mctx);
|
||||||
zt->references = 1;
|
isc_refcount_init(&zt->refs, 1);
|
||||||
zt->flush = false;
|
zt->flush = false;
|
||||||
zt->rdclass = rdclass;
|
zt->rdclass = rdclass;
|
||||||
zt->magic = ZTMAGIC;
|
zt->magic = ZTMAGIC;
|
||||||
zt->loaddone = NULL;
|
zt->loaddone = NULL;
|
||||||
zt->loaddone_arg = NULL;
|
zt->loaddone_arg = NULL;
|
||||||
zt->loadparams = NULL;
|
zt->loadparams = NULL;
|
||||||
zt->loads_pending = 0;
|
isc_refcount_init(&zt->loads_pending, 0);
|
||||||
*ztp = zt;
|
*ztp = zt;
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
@@ -203,9 +204,7 @@ dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp) {
|
|||||||
|
|
||||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||||
|
|
||||||
INSIST(zt->references > 0);
|
INSIST(isc_refcount_increment(&zt->refs) > 0);
|
||||||
zt->references++;
|
|
||||||
INSIST(zt->references != 0);
|
|
||||||
|
|
||||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||||
|
|
||||||
@@ -231,6 +230,7 @@ zt_destroy(dns_zt_t *zt) {
|
|||||||
static void
|
static void
|
||||||
zt_flushanddetach(dns_zt_t **ztp, bool need_flush) {
|
zt_flushanddetach(dns_zt_t **ztp, bool need_flush) {
|
||||||
bool destroy = false;
|
bool destroy = false;
|
||||||
|
int refs;
|
||||||
dns_zt_t *zt;
|
dns_zt_t *zt;
|
||||||
|
|
||||||
REQUIRE(ztp != NULL && VALID_ZT(*ztp));
|
REQUIRE(ztp != NULL && VALID_ZT(*ztp));
|
||||||
@@ -239,17 +239,16 @@ zt_flushanddetach(dns_zt_t **ztp, bool need_flush) {
|
|||||||
|
|
||||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||||
|
|
||||||
INSIST(zt->references > 0);
|
refs = isc_refcount_decrement(&zt->refs);
|
||||||
zt->references--;
|
INSIST(refs != 0);
|
||||||
if (zt->references == 0)
|
destroy = (refs == 1);
|
||||||
destroy = true;
|
zt->flush = need_flush;
|
||||||
if (need_flush)
|
|
||||||
zt->flush = true;
|
|
||||||
|
|
||||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||||
|
|
||||||
if (destroy)
|
if (destroy) {
|
||||||
zt_destroy(zt);
|
zt_destroy(zt);
|
||||||
|
}
|
||||||
|
|
||||||
*ztp = NULL;
|
*ztp = NULL;
|
||||||
}
|
}
|
||||||
@@ -332,15 +331,14 @@ asyncload(dns_zone_t *zone, void *zt_) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
struct dns_zt *zt = (dns_zt_t*) zt_;
|
struct dns_zt *zt = (dns_zt_t*) zt_;
|
||||||
REQUIRE(zone != NULL);
|
REQUIRE(zone != NULL);
|
||||||
INSIST(zt->references > 0);
|
INSIST(isc_refcount_increment(&zt->refs) > 0);
|
||||||
zt->references++;
|
isc_refcount_increment(&zt->loads_pending);
|
||||||
zt->loads_pending++;
|
|
||||||
|
|
||||||
result = dns_zone_asyncload(zone, zt->loadparams->newonly, *zt->loadparams->dl, zt);
|
result = dns_zone_asyncload(zone, zt->loadparams->newonly,
|
||||||
|
*zt->loadparams->dl, zt);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
zt->references--;
|
INSIST(isc_refcount_decrement(&zt->refs) > 1);
|
||||||
zt->loads_pending--;
|
isc_refcount_decrement(&zt->loads_pending);
|
||||||
INSIST(zt->references > 0);
|
|
||||||
}
|
}
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -530,6 +528,7 @@ dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
|
doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
|
||||||
bool destroy = false;
|
bool destroy = false;
|
||||||
|
int refs;
|
||||||
dns_zt_allloaded_t alldone = NULL;
|
dns_zt_allloaded_t alldone = NULL;
|
||||||
void *arg = NULL;
|
void *arg = NULL;
|
||||||
|
|
||||||
@@ -539,13 +538,12 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
|
|||||||
REQUIRE(VALID_ZT(zt));
|
REQUIRE(VALID_ZT(zt));
|
||||||
|
|
||||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||||
INSIST(zt->loads_pending != 0);
|
INSIST(atomic_load(&zt->loads_pending) != 0);
|
||||||
INSIST(zt->references != 0);
|
refs = isc_refcount_decrement(&zt->refs);
|
||||||
zt->references--;
|
INSIST(refs > 0);
|
||||||
if (zt->references == 0)
|
destroy = (refs == 1);
|
||||||
destroy = true;
|
|
||||||
zt->loads_pending--;
|
if (isc_refcount_decrement(&zt->loads_pending) == 1) {
|
||||||
if (zt->loads_pending == 0) {
|
|
||||||
alldone = zt->loaddone;
|
alldone = zt->loaddone;
|
||||||
arg = zt->loaddone_arg;
|
arg = zt->loaddone_arg;
|
||||||
zt->loaddone = NULL;
|
zt->loaddone = NULL;
|
||||||
|
|||||||
+33
-7
@@ -126,6 +126,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <isc/app.h>
|
#include <isc/app.h>
|
||||||
#include <isc/buffer.h>
|
#include <isc/buffer.h>
|
||||||
#include <isc/lib.h>
|
#include <isc/lib.h>
|
||||||
@@ -339,25 +345,45 @@ getaddrinfo(const char *hostname, const char *servname,
|
|||||||
|
|
||||||
port = strtol(servname, &e, 10);
|
port = strtol(servname, &e, 10);
|
||||||
if (*e == '\0') {
|
if (*e == '\0') {
|
||||||
if (socktype == 0)
|
if (socktype == 0) {
|
||||||
return (EAI_SOCKTYPE);
|
return (EAI_SOCKTYPE);
|
||||||
if (port < 0 || port > 65535)
|
}
|
||||||
|
if (port < 0 || port > 65535) {
|
||||||
return (EAI_SERVICE);
|
return (EAI_SERVICE);
|
||||||
|
}
|
||||||
port = htons((unsigned short) port);
|
port = htons((unsigned short) port);
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
WORD wVersionRequested;
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
wVersionRequested = MAKEWORD(2, 0);
|
||||||
|
|
||||||
|
err = WSAStartup(wVersionRequested, &wsaData );
|
||||||
|
if (err != 0) {
|
||||||
|
return (EAI_FAIL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
sp = getservbyname(servname, proto);
|
sp = getservbyname(servname, proto);
|
||||||
if (sp == NULL)
|
if (sp != NULL)
|
||||||
|
port = sp->s_port;
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
if (sp == NULL) {
|
||||||
return (EAI_SERVICE);
|
return (EAI_SERVICE);
|
||||||
port = sp->s_port;
|
}
|
||||||
if (socktype == 0) {
|
if (socktype == 0) {
|
||||||
if (strcmp(sp->s_proto, "tcp") == 0)
|
if (strcmp(sp->s_proto, "tcp") == 0) {
|
||||||
socktype = SOCK_STREAM;
|
socktype = SOCK_STREAM;
|
||||||
else if (strcmp(sp->s_proto, "udp") == 0)
|
} else if (strcmp(sp->s_proto, "udp") == 0) {
|
||||||
socktype = SOCK_DGRAM;
|
socktype = SOCK_DGRAM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
port = 0;
|
port = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Next, deal with just a service name, and no hostname.
|
* Next, deal with just a service name, and no hostname.
|
||||||
|
|||||||
@@ -16,3 +16,12 @@
|
|||||||
#else
|
#else
|
||||||
#include <isc/stdatomic.h>
|
#include <isc/stdatomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We define a few additional macros to make things easier
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define atomic_store_relaxed(o, v) atomic_store_explicit((o), \
|
||||||
|
(v), \
|
||||||
|
memory_order_relaxed)
|
||||||
|
#define atomic_load_relaxed(o) atomic_load_explicit((o), memory_order_relaxed)
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ struct isc_rwlock {
|
|||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
isc_mutex_t lock;
|
isc_mutex_t lock;
|
||||||
int32_t spins;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When some atomic instructions with hardware assistance are
|
* When some atomic instructions with hardware assistance are
|
||||||
@@ -51,6 +50,7 @@ struct isc_rwlock {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Read or modified atomically. */
|
/* Read or modified atomically. */
|
||||||
|
atomic_int_fast32_t spins;
|
||||||
atomic_int_fast32_t write_requests;
|
atomic_int_fast32_t write_requests;
|
||||||
atomic_int_fast32_t write_completions;
|
atomic_int_fast32_t write_completions;
|
||||||
atomic_int_fast32_t cnt_and_flag;
|
atomic_int_fast32_t cnt_and_flag;
|
||||||
@@ -60,8 +60,8 @@ struct isc_rwlock {
|
|||||||
isc_condition_t writeable;
|
isc_condition_t writeable;
|
||||||
unsigned int readers_waiting;
|
unsigned int readers_waiting;
|
||||||
|
|
||||||
/* Locked by rwlock itself. */
|
/* Locked by rwlock itself, but sometimes accessed without lock */
|
||||||
unsigned int write_granted;
|
atomic_int_fast32_t write_granted;
|
||||||
|
|
||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
unsigned int write_quota;
|
unsigned int write_quota;
|
||||||
|
|||||||
@@ -186,6 +186,10 @@
|
|||||||
#define __SANITIZE_ADDRESS__ 1
|
#define __SANITIZE_ADDRESS__ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(thread_sanitizer)
|
||||||
|
#define __SANITIZE_THREAD__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 6)
|
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 6)
|
||||||
#define STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
|
#define STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
|
||||||
#elif __has_feature(c_static_assert)
|
#elif __has_feature(c_static_assert)
|
||||||
|
|||||||
+9
-11
@@ -142,7 +142,7 @@ struct isc__mem {
|
|||||||
size_t hi_water;
|
size_t hi_water;
|
||||||
size_t lo_water;
|
size_t lo_water;
|
||||||
bool hi_called;
|
bool hi_called;
|
||||||
bool is_overmem;
|
atomic_bool is_overmem;
|
||||||
isc_mem_water_t water;
|
isc_mem_water_t water;
|
||||||
void * water_arg;
|
void * water_arg;
|
||||||
ISC_LIST(isc__mempool_t) pools;
|
ISC_LIST(isc__mempool_t) pools;
|
||||||
@@ -770,7 +770,7 @@ isc_mem_createx(size_t init_max_size, size_t target_size,
|
|||||||
ctx->hi_water = 0;
|
ctx->hi_water = 0;
|
||||||
ctx->lo_water = 0;
|
ctx->lo_water = 0;
|
||||||
ctx->hi_called = false;
|
ctx->hi_called = false;
|
||||||
ctx->is_overmem = false;
|
atomic_store_relaxed(&ctx->is_overmem, false);
|
||||||
ctx->water = NULL;
|
ctx->water = NULL;
|
||||||
ctx->water_arg = NULL;
|
ctx->water_arg = NULL;
|
||||||
ctx->common.impmagic = MEM_MAGIC;
|
ctx->common.impmagic = MEM_MAGIC;
|
||||||
@@ -1043,7 +1043,7 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
|
|||||||
ADD_TRACE(ctx, ptr, size, file, line);
|
ADD_TRACE(ctx, ptr, size, file, line);
|
||||||
|
|
||||||
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) {
|
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) {
|
||||||
ctx->is_overmem = true;
|
atomic_store_relaxed(&ctx->is_overmem, true);
|
||||||
if (!ctx->hi_called)
|
if (!ctx->hi_called)
|
||||||
call_water = true;
|
call_water = true;
|
||||||
}
|
}
|
||||||
@@ -1103,7 +1103,7 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
|
|||||||
* isc_mem_setwater() called with 0 for hi_water and lo_water.
|
* isc_mem_setwater() called with 0 for hi_water and lo_water.
|
||||||
*/
|
*/
|
||||||
if ((ctx->inuse < ctx->lo_water) || (ctx->lo_water == 0U)) {
|
if ((ctx->inuse < ctx->lo_water) || (ctx->lo_water == 0U)) {
|
||||||
ctx->is_overmem = false;
|
atomic_store_relaxed(&ctx->is_overmem, false);
|
||||||
if (ctx->hi_called)
|
if (ctx->hi_called)
|
||||||
call_water = true;
|
call_water = true;
|
||||||
}
|
}
|
||||||
@@ -1269,9 +1269,8 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
|
|||||||
mem_getstats(ctx, si[-1].u.size);
|
mem_getstats(ctx, si[-1].u.size);
|
||||||
|
|
||||||
ADD_TRACE(ctx, si, si[-1].u.size, file, line);
|
ADD_TRACE(ctx, si, si[-1].u.size, file, line);
|
||||||
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
|
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) {
|
||||||
!ctx->is_overmem) {
|
atomic_store_relaxed(&ctx->is_overmem, true);
|
||||||
ctx->is_overmem = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->hi_water != 0U && !ctx->hi_called &&
|
if (ctx->hi_water != 0U && !ctx->hi_called &&
|
||||||
@@ -1371,9 +1370,8 @@ isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
|
|||||||
* when the context was pushed over hi_water but then had
|
* when the context was pushed over hi_water but then had
|
||||||
* isc_mem_setwater() called with 0 for hi_water and lo_water.
|
* isc_mem_setwater() called with 0 for hi_water and lo_water.
|
||||||
*/
|
*/
|
||||||
if (ctx->is_overmem &&
|
if (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U) {
|
||||||
(ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
|
atomic_store_relaxed(&ctx->is_overmem, false);
|
||||||
ctx->is_overmem = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->hi_called &&
|
if (ctx->hi_called &&
|
||||||
@@ -1518,7 +1516,7 @@ isc_mem_isovermem(isc_mem_t *ctx0) {
|
|||||||
* necessary (and even if we locked the context the returned value
|
* necessary (and even if we locked the context the returned value
|
||||||
* could be different from the actual state when it's used anyway)
|
* could be different from the actual state when it's used anyway)
|
||||||
*/
|
*/
|
||||||
return (ctx->is_overmem);
|
return (atomic_load_relaxed(&ctx->is_overmem));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+48
-32
@@ -18,6 +18,10 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#if defined(sun) && (defined(__sparc) || defined(__sparc__))
|
||||||
|
#include <synch.h> /* for smt_pause(3c) */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <isc/atomic.h>
|
#include <isc/atomic.h>
|
||||||
#include <isc/magic.h>
|
#include <isc/magic.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
@@ -52,6 +56,8 @@
|
|||||||
# define isc_rwlock_pause() __asm__ __volatile__ ("hint @pause")
|
# define isc_rwlock_pause() __asm__ __volatile__ ("hint @pause")
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
# define isc_rwlock_pause() __asm__ __volatile__ ("yield")
|
# define isc_rwlock_pause() __asm__ __volatile__ ("yield")
|
||||||
|
#elif defined(sun) && (defined(__sparc) || defined(__sparc__))
|
||||||
|
# define isc_rwlock_pause() smt_pause()
|
||||||
#elif defined(__sparc) || defined(__sparc__)
|
#elif defined(__sparc) || defined(__sparc__)
|
||||||
# define isc_rwlock_pause() __asm__ __volatile__ ("pause")
|
# define isc_rwlock_pause() __asm__ __volatile__ ("pause")
|
||||||
#elif defined(__ppc__) || defined(_ARCH_PPC) || \
|
#elif defined(__ppc__) || defined(_ARCH_PPC) || \
|
||||||
@@ -77,9 +83,9 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
"write_granted=%u, write_quota=%u\n",
|
"write_granted=%u, write_quota=%u\n",
|
||||||
rwl, isc_thread_self(), operation,
|
rwl, isc_thread_self(), operation,
|
||||||
(type == isc_rwlocktype_read ? "read" : "write"),
|
(type == isc_rwlocktype_read ? "read" : "write"),
|
||||||
atomic_load_explicit(&rwl->write_requests, memory_order_relaxed),
|
atomic_load_relaxed(&rwl->write_requests),
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed),
|
atomic_load_relaxed(&rwl->write_completions),
|
||||||
atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed),
|
atomic_load_relaxed(&rwl->cnt_and_flag),
|
||||||
rwl->readers_waiting,
|
rwl->readers_waiting,
|
||||||
rwl->write_granted, rwl->write_quota);
|
rwl->write_granted, rwl->write_quota);
|
||||||
}
|
}
|
||||||
@@ -97,7 +103,7 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
|||||||
*/
|
*/
|
||||||
rwl->magic = 0;
|
rwl->magic = 0;
|
||||||
|
|
||||||
rwl->spins = 0;
|
atomic_init(&rwl->spins, 0);
|
||||||
atomic_init(&rwl->write_requests, 0);
|
atomic_init(&rwl->write_requests, 0);
|
||||||
atomic_init(&rwl->write_completions, 0);
|
atomic_init(&rwl->write_completions, 0);
|
||||||
atomic_init(&rwl->cnt_and_flag, 0);
|
atomic_init(&rwl->cnt_and_flag, 0);
|
||||||
@@ -125,9 +131,9 @@ void
|
|||||||
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||||
REQUIRE(VALID_RWLOCK(rwl));
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
|
||||||
REQUIRE(atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) ==
|
REQUIRE(atomic_load_relaxed(&rwl->write_requests) ==
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) &&
|
atomic_load_relaxed(&rwl->write_completions) &&
|
||||||
atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) == 0 && rwl->readers_waiting == 0);
|
atomic_load_relaxed(&rwl->cnt_and_flag) == 0 && rwl->readers_waiting == 0);
|
||||||
|
|
||||||
rwl->magic = 0;
|
rwl->magic = 0;
|
||||||
(void)isc_condition_destroy(&rwl->readable);
|
(void)isc_condition_destroy(&rwl->readable);
|
||||||
@@ -211,13 +217,13 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (type == isc_rwlocktype_read) {
|
if (type == isc_rwlocktype_read) {
|
||||||
if (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) !=
|
if (atomic_load_relaxed(&rwl->write_requests) !=
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed))
|
atomic_load_relaxed(&rwl->write_completions))
|
||||||
{
|
{
|
||||||
/* there is a waiting or active writer */
|
/* there is a waiting or active writer */
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
if (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) !=
|
if (atomic_load_relaxed(&rwl->write_requests) !=
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) {
|
atomic_load_relaxed(&rwl->write_completions)) {
|
||||||
rwl->readers_waiting++;
|
rwl->readers_waiting++;
|
||||||
WAIT(&rwl->readable, &rwl->lock);
|
WAIT(&rwl->readable, &rwl->lock);
|
||||||
rwl->readers_waiting--;
|
rwl->readers_waiting--;
|
||||||
@@ -230,13 +236,16 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
POST(cntflag);
|
POST(cntflag);
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & WRITER_ACTIVE) == 0)
|
if ((atomic_load_relaxed(&rwl->cnt_and_flag) &
|
||||||
|
WRITER_ACTIVE) == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* A writer is still working */
|
/* A writer is still working */
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
rwl->readers_waiting++;
|
rwl->readers_waiting++;
|
||||||
if ((atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & WRITER_ACTIVE) != 0) {
|
if ((atomic_load_relaxed(&rwl->cnt_and_flag)
|
||||||
|
& WRITER_ACTIVE) != 0) {
|
||||||
WAIT(&rwl->readable, &rwl->lock);
|
WAIT(&rwl->readable, &rwl->lock);
|
||||||
}
|
}
|
||||||
rwl->readers_waiting--;
|
rwl->readers_waiting--;
|
||||||
@@ -273,16 +282,18 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
* quota, reset the condition (race among readers doesn't
|
* quota, reset the condition (race among readers doesn't
|
||||||
* matter).
|
* matter).
|
||||||
*/
|
*/
|
||||||
rwl->write_granted = 0;
|
atomic_store_relaxed(&rwl->write_granted, 0);
|
||||||
} else {
|
} else {
|
||||||
int32_t prev_writer;
|
int32_t prev_writer;
|
||||||
|
|
||||||
/* enter the waiting queue, and wait for our turn */
|
/* enter the waiting queue, and wait for our turn */
|
||||||
prev_writer = atomic_fetch_add_explicit(&rwl->write_requests, 1,
|
prev_writer = atomic_fetch_add_explicit(&rwl->write_requests, 1,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
while (atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) != prev_writer) {
|
while (atomic_load_relaxed(&rwl->write_completions) !=
|
||||||
|
prev_writer) {
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
if (atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) != prev_writer) {
|
if (atomic_load_relaxed(&rwl->write_completions) !=
|
||||||
|
prev_writer) {
|
||||||
WAIT(&rwl->writeable, &rwl->lock);
|
WAIT(&rwl->writeable, &rwl->lock);
|
||||||
UNLOCK(&rwl->lock);
|
UNLOCK(&rwl->lock);
|
||||||
continue;
|
continue;
|
||||||
@@ -302,13 +313,14 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
|
|
||||||
/* Another active reader or writer is working. */
|
/* Another active reader or writer is working. */
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
if (atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) != 0) {
|
if (atomic_load_relaxed(&rwl->cnt_and_flag) != 0) {
|
||||||
WAIT(&rwl->writeable, &rwl->lock);
|
WAIT(&rwl->writeable, &rwl->lock);
|
||||||
}
|
}
|
||||||
UNLOCK(&rwl->lock);
|
UNLOCK(&rwl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSIST((atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & WRITER_ACTIVE));
|
INSIST((atomic_load_relaxed(&rwl->cnt_and_flag) &
|
||||||
|
WRITER_ACTIVE));
|
||||||
rwl->write_granted++;
|
rwl->write_granted++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +334,8 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||||
int32_t cnt = 0;
|
int32_t cnt = 0;
|
||||||
int32_t max_cnt = rwl->spins * 2 + 10;
|
int32_t max_cnt = atomic_load_relaxed(&rwl->spins) * 2 + 10;
|
||||||
|
int32_t spins;
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT)
|
if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT)
|
||||||
@@ -336,7 +349,9 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
isc_rwlock_pause();
|
isc_rwlock_pause();
|
||||||
} while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS);
|
} while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS);
|
||||||
|
|
||||||
rwl->spins += (cnt - rwl->spins) / 8;
|
spins = atomic_load_relaxed(&rwl->spins);
|
||||||
|
spins += (cnt - spins) / 8;
|
||||||
|
atomic_store_relaxed(&rwl->spins, spins);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -353,8 +368,8 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
|
|
||||||
if (type == isc_rwlocktype_read) {
|
if (type == isc_rwlocktype_read) {
|
||||||
/* If a writer is waiting or working, we fail. */
|
/* If a writer is waiting or working, we fail. */
|
||||||
if (atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) !=
|
if (atomic_load_relaxed(&rwl->write_requests) !=
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed))
|
atomic_load_relaxed(&rwl->write_completions))
|
||||||
return (ISC_R_LOCKBUSY);
|
return (ISC_R_LOCKBUSY);
|
||||||
|
|
||||||
/* Otherwise, be ready for reading. */
|
/* Otherwise, be ready for reading. */
|
||||||
@@ -374,8 +389,8 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
* new writers in this short period, wake them up.
|
* new writers in this short period, wake them up.
|
||||||
*/
|
*/
|
||||||
if (cntflag == READER_INCR &&
|
if (cntflag == READER_INCR &&
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) !=
|
atomic_load_relaxed(&rwl->write_completions) !=
|
||||||
atomic_load_explicit(&rwl->write_requests, memory_order_relaxed)) {
|
atomic_load_relaxed(&rwl->write_requests)) {
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
BROADCAST(&rwl->writeable);
|
BROADCAST(&rwl->writeable);
|
||||||
UNLOCK(&rwl->lock);
|
UNLOCK(&rwl->lock);
|
||||||
@@ -400,7 +415,8 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
atomic_fetch_sub_explicit(&rwl->write_completions, 1,
|
atomic_fetch_sub_explicit(&rwl->write_completions, 1,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
|
||||||
rwl->write_granted++;
|
atomic_fetch_add_explicit(&rwl->write_granted, 1,
|
||||||
|
memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ISC_RWLOCK_TRACE
|
#ifdef ISC_RWLOCK_TRACE
|
||||||
@@ -491,8 +507,8 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
* FIFO order.
|
* FIFO order.
|
||||||
*/
|
*/
|
||||||
if (prev_cnt == READER_INCR &&
|
if (prev_cnt == READER_INCR &&
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed) !=
|
atomic_load_relaxed(&rwl->write_completions) !=
|
||||||
atomic_load_explicit(&rwl->write_requests, memory_order_relaxed)) {
|
atomic_load_relaxed(&rwl->write_requests)) {
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
BROADCAST(&rwl->writeable);
|
BROADCAST(&rwl->writeable);
|
||||||
UNLOCK(&rwl->lock);
|
UNLOCK(&rwl->lock);
|
||||||
@@ -510,9 +526,9 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
|
||||||
if (rwl->write_granted >= rwl->write_quota ||
|
if (rwl->write_granted >= rwl->write_quota ||
|
||||||
(atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) ==
|
(atomic_load_relaxed(&rwl->write_requests) ==
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) ||
|
atomic_load_relaxed(&rwl->write_completions)) ||
|
||||||
(atomic_load_explicit(&rwl->cnt_and_flag, memory_order_relaxed) & ~WRITER_ACTIVE)) {
|
(atomic_load_relaxed(&rwl->cnt_and_flag) & ~WRITER_ACTIVE)) {
|
||||||
/*
|
/*
|
||||||
* We have passed the write quota, no writer is
|
* We have passed the write quota, no writer is
|
||||||
* waiting, or some readers are almost ready, pending
|
* waiting, or some readers are almost ready, pending
|
||||||
@@ -529,8 +545,8 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
UNLOCK(&rwl->lock);
|
UNLOCK(&rwl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((atomic_load_explicit(&rwl->write_requests, memory_order_relaxed) !=
|
if ((atomic_load_relaxed(&rwl->write_requests) !=
|
||||||
atomic_load_explicit(&rwl->write_completions, memory_order_relaxed)) &&
|
atomic_load_relaxed(&rwl->write_completions)) &&
|
||||||
wakeup_writers) {
|
wakeup_writers) {
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
BROADCAST(&rwl->writeable);
|
BROADCAST(&rwl->writeable);
|
||||||
|
|||||||
+72
-58
@@ -147,15 +147,16 @@ struct isc__taskmgr {
|
|||||||
atomic_uint_fast32_t tasks_running;
|
atomic_uint_fast32_t tasks_running;
|
||||||
atomic_uint_fast32_t tasks_ready;
|
atomic_uint_fast32_t tasks_ready;
|
||||||
atomic_uint_fast32_t curq;
|
atomic_uint_fast32_t curq;
|
||||||
|
atomic_uint_fast32_t tasks_count;
|
||||||
isc__taskqueue_t *queues;
|
isc__taskqueue_t *queues;
|
||||||
|
|
||||||
/* Locked by task manager lock. */
|
/* Locked by task manager lock. */
|
||||||
unsigned int default_quantum;
|
unsigned int default_quantum;
|
||||||
LIST(isc__task_t) tasks;
|
LIST(isc__task_t) tasks;
|
||||||
isc_taskmgrmode_t mode;
|
atomic_uint_fast32_t mode;
|
||||||
bool pause_requested;
|
atomic_bool pause_req;
|
||||||
bool exclusive_requested;
|
atomic_bool exclusive_req;
|
||||||
bool exiting;
|
atomic_bool exiting;
|
||||||
|
|
||||||
/* Locked by halt_lock */
|
/* Locked by halt_lock */
|
||||||
unsigned int halted;
|
unsigned int halted;
|
||||||
@@ -176,7 +177,8 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0);
|
|||||||
|
|
||||||
|
|
||||||
#define DEFAULT_DEFAULT_QUANTUM 25
|
#define DEFAULT_DEFAULT_QUANTUM 25
|
||||||
#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
|
#define FINISHED(m) (atomic_load_relaxed(&((m)->exiting)) == true && \
|
||||||
|
atomic_load(&(m)->tasks_count) == 0)
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* The following are intended for internal use (indicated by "isc__"
|
* The following are intended for internal use (indicated by "isc__"
|
||||||
@@ -228,6 +230,7 @@ task_finished(isc__task_t *task) {
|
|||||||
|
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
UNLINK(manager->tasks, task, link);
|
UNLINK(manager->tasks, task, link);
|
||||||
|
atomic_fetch_sub(&manager->tasks_count, 1);
|
||||||
UNLOCK(&manager->lock);
|
UNLOCK(&manager->lock);
|
||||||
if (FINISHED(manager)) {
|
if (FINISHED(manager)) {
|
||||||
/*
|
/*
|
||||||
@@ -303,8 +306,9 @@ isc_task_create_bound(isc_taskmgr_t *manager0, unsigned int quantum,
|
|||||||
|
|
||||||
exiting = false;
|
exiting = false;
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
if (!manager->exiting) {
|
if (!atomic_load_relaxed(&manager->exiting)) {
|
||||||
APPEND(manager->tasks, task, link);
|
APPEND(manager->tasks, task, link);
|
||||||
|
atomic_fetch_add(&manager->tasks_count, 1);
|
||||||
} else {
|
} else {
|
||||||
exiting = true;
|
exiting = true;
|
||||||
}
|
}
|
||||||
@@ -397,7 +401,8 @@ task_ready(isc__task_t *task) {
|
|||||||
XTRACE("task_ready");
|
XTRACE("task_ready");
|
||||||
LOCK(&manager->queues[task->threadid].lock);
|
LOCK(&manager->queues[task->threadid].lock);
|
||||||
push_readyq(manager, task, task->threadid);
|
push_readyq(manager, task, task->threadid);
|
||||||
if (manager->mode == isc_taskmgrmode_normal || has_privilege) {
|
if (atomic_load(&manager->mode) == isc_taskmgrmode_normal ||
|
||||||
|
has_privilege) {
|
||||||
SIGNAL(&manager->queues[task->threadid].work_available);
|
SIGNAL(&manager->queues[task->threadid].work_available);
|
||||||
}
|
}
|
||||||
UNLOCK(&manager->queues[task->threadid].lock);
|
UNLOCK(&manager->queues[task->threadid].lock);
|
||||||
@@ -512,6 +517,13 @@ isc_task_sendto(isc_task_t *task0, isc_event_t **eventp, int c) {
|
|||||||
REQUIRE(VALID_TASK(task));
|
REQUIRE(VALID_TASK(task));
|
||||||
XTRACE("isc_task_send");
|
XTRACE("isc_task_send");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
/* If task is bound ignore provided cpu. */
|
/* If task is bound ignore provided cpu. */
|
||||||
if (task->bound) {
|
if (task->bound) {
|
||||||
c = task->threadid;
|
c = task->threadid;
|
||||||
@@ -520,13 +532,6 @@ isc_task_sendto(isc_task_t *task0, isc_event_t **eventp, int c) {
|
|||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
}
|
}
|
||||||
c %= task->manager->workers;
|
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, c);
|
was_idle = task_send(task, eventp, c);
|
||||||
UNLOCK(&task->lock);
|
UNLOCK(&task->lock);
|
||||||
|
|
||||||
@@ -565,6 +570,7 @@ isc_task_sendtoanddetach(isc_task_t **taskp, isc_event_t **eventp, int c) {
|
|||||||
REQUIRE(VALID_TASK(task));
|
REQUIRE(VALID_TASK(task));
|
||||||
XTRACE("isc_task_sendanddetach");
|
XTRACE("isc_task_sendanddetach");
|
||||||
|
|
||||||
|
LOCK(&task->lock);
|
||||||
if (task->bound) {
|
if (task->bound) {
|
||||||
c = task->threadid;
|
c = task->threadid;
|
||||||
} else if (c < 0) {
|
} else if (c < 0) {
|
||||||
@@ -572,8 +578,6 @@ isc_task_sendtoanddetach(isc_task_t **taskp, isc_event_t **eventp, int c) {
|
|||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
}
|
}
|
||||||
c %= task->manager->workers;
|
c %= task->manager->workers;
|
||||||
|
|
||||||
LOCK(&task->lock);
|
|
||||||
idle1 = task_send(task, eventp, c);
|
idle1 = task_send(task, eventp, c);
|
||||||
idle2 = task_detach(task);
|
idle2 = task_detach(task);
|
||||||
UNLOCK(&task->lock);
|
UNLOCK(&task->lock);
|
||||||
@@ -902,11 +906,11 @@ static inline bool
|
|||||||
empty_readyq(isc__taskmgr_t *manager, int c) {
|
empty_readyq(isc__taskmgr_t *manager, int c) {
|
||||||
isc__tasklist_t queue;
|
isc__tasklist_t queue;
|
||||||
|
|
||||||
if (manager->mode == isc_taskmgrmode_normal)
|
if (atomic_load_relaxed(&manager->mode) == isc_taskmgrmode_normal) {
|
||||||
queue = manager->queues[c].ready_tasks;
|
queue = manager->queues[c].ready_tasks;
|
||||||
else
|
} else {
|
||||||
queue = manager->queues[c].ready_priority_tasks;
|
queue = manager->queues[c].ready_priority_tasks;
|
||||||
|
}
|
||||||
return (EMPTY(queue));
|
return (EMPTY(queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +926,7 @@ static inline isc__task_t *
|
|||||||
pop_readyq(isc__taskmgr_t *manager, int c) {
|
pop_readyq(isc__taskmgr_t *manager, int c) {
|
||||||
isc__task_t *task;
|
isc__task_t *task;
|
||||||
|
|
||||||
if (manager->mode == isc_taskmgrmode_normal) {
|
if (atomic_load_relaxed(&manager->mode) == isc_taskmgrmode_normal) {
|
||||||
task = HEAD(manager->queues[c].ready_tasks);
|
task = HEAD(manager->queues[c].ready_tasks);
|
||||||
} else {
|
} else {
|
||||||
task = HEAD(manager->queues[c].ready_priority_tasks);
|
task = HEAD(manager->queues[c].ready_priority_tasks);
|
||||||
@@ -1029,15 +1033,15 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
|||||||
* until it's been released.
|
* until it's been released.
|
||||||
*/
|
*/
|
||||||
while ((empty_readyq(manager, threadid) &&
|
while ((empty_readyq(manager, threadid) &&
|
||||||
!manager->pause_requested &&
|
!atomic_load_relaxed(&manager->pause_req) &&
|
||||||
!manager->exclusive_requested) &&
|
!atomic_load_relaxed(&manager->exclusive_req)) &&
|
||||||
!FINISHED(manager))
|
!FINISHED(manager))
|
||||||
{
|
{
|
||||||
XTHREADTRACE("wait");
|
XTHREADTRACE("wait");
|
||||||
XTHREADTRACE(manager->pause_requested
|
XTHREADTRACE(atomic_load_relaxed(&manager->pause_req)
|
||||||
? "paused"
|
? "paused"
|
||||||
: "notpaused");
|
: "notpaused");
|
||||||
XTHREADTRACE(manager->exclusive_requested
|
XTHREADTRACE(atomic_load_relaxed(&manager->exclusive_req)
|
||||||
? "excreq"
|
? "excreq"
|
||||||
: "notexcreq");
|
: "notexcreq");
|
||||||
WAIT(&manager->queues[threadid].work_available,
|
WAIT(&manager->queues[threadid].work_available,
|
||||||
@@ -1046,15 +1050,16 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
|||||||
}
|
}
|
||||||
XTHREADTRACE("working");
|
XTHREADTRACE("working");
|
||||||
|
|
||||||
if (manager->pause_requested || manager->exclusive_requested) {
|
if (atomic_load_relaxed(&manager->pause_req) ||
|
||||||
|
atomic_load_relaxed(&manager->exclusive_req)) {
|
||||||
UNLOCK(&manager->queues[threadid].lock);
|
UNLOCK(&manager->queues[threadid].lock);
|
||||||
XTHREADTRACE("halting");
|
XTHREADTRACE("halting");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Switching to exclusive mode is done as a
|
* Switching to exclusive mode is done as a
|
||||||
* 2-phase-lock, checking if we have to switch is
|
* 2-phase-lock, checking if we have to switch is
|
||||||
* done without any locks on pause_requested and
|
* done without any locks on pause_req and
|
||||||
* exclusive_requested to save time - the worst
|
* exclusive_req to save time - the worst
|
||||||
* thing that can happen is that we'll launch one
|
* thing that can happen is that we'll launch one
|
||||||
* task more and exclusive task will be postponed a
|
* task more and exclusive task will be postponed a
|
||||||
* bit.
|
* bit.
|
||||||
@@ -1066,8 +1071,8 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
|||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
manager->halted++;
|
manager->halted++;
|
||||||
BROADCAST(&manager->halt_cond);
|
BROADCAST(&manager->halt_cond);
|
||||||
while (manager->pause_requested ||
|
while (atomic_load_relaxed(&manager->pause_req) ||
|
||||||
manager->exclusive_requested)
|
atomic_load_relaxed(&manager->exclusive_req))
|
||||||
{
|
{
|
||||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||||
}
|
}
|
||||||
@@ -1260,7 +1265,8 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
|||||||
UNLOCK(&manager->queues[i].lock);
|
UNLOCK(&manager->queues[i].lock);
|
||||||
}
|
}
|
||||||
if (empty) {
|
if (empty) {
|
||||||
manager->mode = isc_taskmgrmode_normal;
|
atomic_store(&manager->mode,
|
||||||
|
isc_taskmgrmode_normal);
|
||||||
wake_all_queues(manager);
|
wake_all_queues(manager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1331,7 +1337,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
|||||||
RUNTIME_CHECK(manager != NULL);
|
RUNTIME_CHECK(manager != NULL);
|
||||||
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
||||||
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
||||||
manager->mode = isc_taskmgrmode_normal;
|
atomic_store(&manager->mode, isc_taskmgrmode_normal);
|
||||||
manager->mctx = NULL;
|
manager->mctx = NULL;
|
||||||
isc_mutex_init(&manager->lock);
|
isc_mutex_init(&manager->lock);
|
||||||
isc_mutex_init(&manager->excl_lock);
|
isc_mutex_init(&manager->excl_lock);
|
||||||
@@ -1346,6 +1352,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
|||||||
}
|
}
|
||||||
manager->default_quantum = default_quantum;
|
manager->default_quantum = default_quantum;
|
||||||
INIT_LIST(manager->tasks);
|
INIT_LIST(manager->tasks);
|
||||||
|
atomic_store(&manager->tasks_count, 0);
|
||||||
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
|
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
|
||||||
RUNTIME_CHECK(manager->queues != NULL);
|
RUNTIME_CHECK(manager->queues != NULL);
|
||||||
|
|
||||||
@@ -1355,8 +1362,8 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
|||||||
manager->exiting = false;
|
manager->exiting = false;
|
||||||
manager->excl = NULL;
|
manager->excl = NULL;
|
||||||
manager->halted = 0;
|
manager->halted = 0;
|
||||||
manager->exclusive_requested = false;
|
atomic_store_relaxed(&manager->exclusive_req, false);
|
||||||
manager->pause_requested = false;
|
atomic_store_relaxed(&manager->pause_req, false);
|
||||||
|
|
||||||
isc_mem_attach(mctx, &manager->mctx);
|
isc_mem_attach(mctx, &manager->mctx);
|
||||||
|
|
||||||
@@ -1433,13 +1440,13 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
|
|||||||
/*
|
/*
|
||||||
* Make sure we only get called once.
|
* Make sure we only get called once.
|
||||||
*/
|
*/
|
||||||
INSIST(!manager->exiting);
|
INSIST(!atomic_load(&manager->exiting));
|
||||||
manager->exiting = true;
|
atomic_store(&manager->exiting, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If privileged mode was on, turn it off.
|
* If privileged mode was on, turn it off.
|
||||||
*/
|
*/
|
||||||
manager->mode = isc_taskmgrmode_normal;
|
atomic_store(&manager->mode, isc_taskmgrmode_normal);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Post shutdown event(s) to every task (if they haven't already been
|
* Post shutdown event(s) to every task (if they haven't already been
|
||||||
@@ -1481,19 +1488,13 @@ void
|
|||||||
isc_taskmgr_setprivilegedmode(isc_taskmgr_t *manager0) {
|
isc_taskmgr_setprivilegedmode(isc_taskmgr_t *manager0) {
|
||||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||||
|
|
||||||
LOCK(&manager->lock);
|
atomic_store(&manager->mode, isc_taskmgrmode_privileged);
|
||||||
manager->mode = isc_taskmgrmode_privileged;
|
|
||||||
UNLOCK(&manager->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_taskmgrmode_t
|
isc_taskmgrmode_t
|
||||||
isc_taskmgr_mode(isc_taskmgr_t *manager0) {
|
isc_taskmgr_mode(isc_taskmgr_t *manager0) {
|
||||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||||
isc_taskmgrmode_t mode;
|
return (atomic_load(&manager->mode));
|
||||||
LOCK(&manager->lock);
|
|
||||||
mode = manager->mode;
|
|
||||||
UNLOCK(&manager->lock);
|
|
||||||
return (mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1501,14 +1502,15 @@ isc__taskmgr_pause(isc_taskmgr_t *manager0) {
|
|||||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||||
|
|
||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
while (manager->exclusive_requested || manager->pause_requested) {
|
while (atomic_load_relaxed(&manager->exclusive_req) ||
|
||||||
|
atomic_load_relaxed(&manager->pause_req)) {
|
||||||
UNLOCK(&manager->halt_lock);
|
UNLOCK(&manager->halt_lock);
|
||||||
/* This is ugly but pause is used EXCLUSIVELY in tests */
|
/* This is ugly but pause is used EXCLUSIVELY in tests */
|
||||||
isc_thread_yield();
|
isc_thread_yield();
|
||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
manager->pause_requested = true;
|
atomic_store_relaxed(&manager->pause_req, true);
|
||||||
while (manager->halted < manager->workers) {
|
while (manager->halted < manager->workers) {
|
||||||
wake_all_queues(manager);
|
wake_all_queues(manager);
|
||||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||||
@@ -1520,8 +1522,8 @@ void
|
|||||||
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
||||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
if (manager->pause_requested) {
|
if (manager->pause_req) {
|
||||||
manager->pause_requested = false;
|
manager->pause_req = false;
|
||||||
while (manager->halted > 0) {
|
while (manager->halted > 0) {
|
||||||
BROADCAST(&manager->halt_cond);
|
BROADCAST(&manager->halt_cond);
|
||||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||||
@@ -1573,16 +1575,19 @@ isc_task_beginexclusive(isc_task_t *task0) {
|
|||||||
|
|
||||||
LOCK(&manager->excl_lock);
|
LOCK(&manager->excl_lock);
|
||||||
REQUIRE(task == task->manager->excl ||
|
REQUIRE(task == task->manager->excl ||
|
||||||
(task->manager->exiting && task->manager->excl == NULL));
|
(atomic_load_relaxed(&task->manager->exiting) &&
|
||||||
|
task->manager->excl == NULL));
|
||||||
UNLOCK(&manager->excl_lock);
|
UNLOCK(&manager->excl_lock);
|
||||||
|
|
||||||
if (manager->exclusive_requested || manager->pause_requested) {
|
if (atomic_load_relaxed(&manager->exclusive_req) ||
|
||||||
|
atomic_load_relaxed(&manager->pause_req)) {
|
||||||
return (ISC_R_LOCKBUSY);
|
return (ISC_R_LOCKBUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
INSIST(!manager->exclusive_requested && !manager->pause_requested);
|
INSIST(!atomic_load_relaxed(&manager->exclusive_req) &&
|
||||||
manager->exclusive_requested = true;
|
!atomic_load_relaxed(&manager->pause_req));
|
||||||
|
atomic_store_relaxed(&manager->exclusive_req, true);
|
||||||
while (manager->halted + 1 < manager->workers) {
|
while (manager->halted + 1 < manager->workers) {
|
||||||
wake_all_queues(manager);
|
wake_all_queues(manager);
|
||||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||||
@@ -1599,8 +1604,8 @@ isc_task_endexclusive(isc_task_t *task0) {
|
|||||||
REQUIRE(VALID_TASK(task));
|
REQUIRE(VALID_TASK(task));
|
||||||
REQUIRE(task->state == task_state_running);
|
REQUIRE(task->state == task_state_running);
|
||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
REQUIRE(manager->exclusive_requested);
|
REQUIRE(atomic_load_relaxed(&manager->exclusive_req) == true);
|
||||||
manager->exclusive_requested = false;
|
atomic_store_relaxed(&manager->exclusive_req, false);
|
||||||
while (manager->halted > 0) {
|
while (manager->halted > 0) {
|
||||||
BROADCAST(&manager->halt_cond);
|
BROADCAST(&manager->halt_cond);
|
||||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||||
@@ -1685,14 +1690,19 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
|
|||||||
mgr->default_quantum));
|
mgr->default_quantum));
|
||||||
TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */
|
TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */
|
||||||
|
|
||||||
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-count"));
|
||||||
|
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||||
|
(int) atomic_load_relaxed(&mgr->tasks_count)));
|
||||||
|
TRY0(xmlTextWriterEndElement(writer)); /* tasks-count */
|
||||||
|
|
||||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"));
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"));
|
||||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||||
(int) mgr->tasks_running));
|
(int) atomic_load_relaxed(&mgr->tasks_running)));
|
||||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */
|
TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */
|
||||||
|
|
||||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready"));
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready"));
|
||||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||||
(int) mgr->tasks_ready));
|
(int) atomic_load_relaxed(&mgr->tasks_ready)));
|
||||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-ready */
|
TRY0(xmlTextWriterEndElement(writer)); /* tasks-ready */
|
||||||
|
|
||||||
TRY0(xmlTextWriterEndElement(writer)); /* thread-model */
|
TRY0(xmlTextWriterEndElement(writer)); /* thread-model */
|
||||||
@@ -1785,11 +1795,15 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) {
|
|||||||
CHECKMEM(obj);
|
CHECKMEM(obj);
|
||||||
json_object_object_add(tasks, "default-quantum", obj);
|
json_object_object_add(tasks, "default-quantum", obj);
|
||||||
|
|
||||||
obj = json_object_new_int(mgr->tasks_running);
|
obj = json_object_new_int(atomic_load_relaxed(&mgr->tasks_count));
|
||||||
|
CHECKMEM(obj);
|
||||||
|
json_object_object_add(tasks, "tasks-count", obj);
|
||||||
|
|
||||||
|
obj = json_object_new_int(atomic_load_relaxed(&mgr->tasks_running));
|
||||||
CHECKMEM(obj);
|
CHECKMEM(obj);
|
||||||
json_object_object_add(tasks, "tasks-running", obj);
|
json_object_object_add(tasks, "tasks-running", obj);
|
||||||
|
|
||||||
obj = json_object_new_int(mgr->tasks_ready);
|
obj = json_object_new_int(atomic_load_relaxed(&mgr->tasks_ready));
|
||||||
CHECKMEM(obj);
|
CHECKMEM(obj);
|
||||||
json_object_object_add(tasks, "tasks-ready", obj);
|
json_object_object_add(tasks, "tasks-ready", obj);
|
||||||
|
|
||||||
|
|||||||
+36
-31
@@ -36,6 +36,7 @@
|
|||||||
#include <isc/event.h>
|
#include <isc/event.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/strerr.h>
|
#include <isc/strerr.h>
|
||||||
|
#include <isc/atomic.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
#include <isc/task.h>
|
#include <isc/task.h>
|
||||||
#include <isc/time.h>
|
#include <isc/time.h>
|
||||||
@@ -50,7 +51,7 @@
|
|||||||
* as an event loop dispatching various events.
|
* as an event loop dispatching various events.
|
||||||
*/
|
*/
|
||||||
static pthread_t blockedthread;
|
static pthread_t blockedthread;
|
||||||
static bool is_running;
|
static atomic_bool is_running;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The application context of this module. This implementation actually
|
* The application context of this module. This implementation actually
|
||||||
@@ -70,13 +71,13 @@ typedef struct isc__appctx {
|
|||||||
/*!
|
/*!
|
||||||
* We assume that 'want_shutdown' can be read and written atomically.
|
* We assume that 'want_shutdown' can be read and written atomically.
|
||||||
*/
|
*/
|
||||||
bool want_shutdown;
|
atomic_bool want_shutdown;
|
||||||
/*
|
/*
|
||||||
* We assume that 'want_reload' can be read and written atomically.
|
* We assume that 'want_reload' can be read and written atomically.
|
||||||
*/
|
*/
|
||||||
bool want_reload;
|
atomic_bool want_reload;
|
||||||
|
|
||||||
bool blocked;
|
atomic_bool blocked;
|
||||||
|
|
||||||
isc_taskmgr_t *taskmgr;
|
isc_taskmgr_t *taskmgr;
|
||||||
isc_socketmgr_t *socketmgr;
|
isc_socketmgr_t *socketmgr;
|
||||||
@@ -91,13 +92,13 @@ static isc__appctx_t isc_g_appctx;
|
|||||||
static void
|
static void
|
||||||
exit_action(int arg) {
|
exit_action(int arg) {
|
||||||
UNUSED(arg);
|
UNUSED(arg);
|
||||||
isc_g_appctx.want_shutdown = true;
|
atomic_store(&isc_g_appctx.want_shutdown, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reload_action(int arg) {
|
reload_action(int arg) {
|
||||||
UNUSED(arg);
|
UNUSED(arg);
|
||||||
isc_g_appctx.want_reload = true;
|
atomic_store(&isc_g_appctx.want_reload, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -145,9 +146,9 @@ isc_app_ctxstart(isc_appctx_t *ctx0) {
|
|||||||
|
|
||||||
ctx->shutdown_requested = false;
|
ctx->shutdown_requested = false;
|
||||||
ctx->running = false;
|
ctx->running = false;
|
||||||
ctx->want_shutdown = false;
|
atomic_store(&ctx->want_shutdown, false);
|
||||||
ctx->want_reload = false;
|
atomic_store(&ctx->want_reload, false);
|
||||||
ctx->blocked = false;
|
atomic_store(&ctx->blocked, false);
|
||||||
|
|
||||||
#ifndef HAVE_SIGWAIT
|
#ifndef HAVE_SIGWAIT
|
||||||
/*
|
/*
|
||||||
@@ -337,7 +338,7 @@ isc_app_ctxrun(isc_appctx_t *ctx0) {
|
|||||||
* simply be made pending and we will get it when we call
|
* simply be made pending and we will get it when we call
|
||||||
* sigwait().
|
* sigwait().
|
||||||
*/
|
*/
|
||||||
while (!ctx->want_shutdown) {
|
while (!atomic_load(&ctx->want_shutdown)) {
|
||||||
#ifdef HAVE_SIGWAIT
|
#ifdef HAVE_SIGWAIT
|
||||||
if (isc_bind9) {
|
if (isc_bind9) {
|
||||||
/*
|
/*
|
||||||
@@ -357,10 +358,11 @@ isc_app_ctxrun(isc_appctx_t *ctx0) {
|
|||||||
|
|
||||||
result = sigwait(&sset, &sig);
|
result = sigwait(&sset, &sig);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
if (sig == SIGINT || sig == SIGTERM)
|
if (sig == SIGINT || sig == SIGTERM) {
|
||||||
ctx->want_shutdown = true;
|
atomic_store(&ctx->want_shutdown, true);
|
||||||
else if (sig == SIGHUP)
|
} else if (sig == SIGHUP) {
|
||||||
ctx->want_reload = true;
|
atomic_store(&ctx->want_reload, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -369,12 +371,12 @@ isc_app_ctxrun(isc_appctx_t *ctx0) {
|
|||||||
* wait until woken up.
|
* wait until woken up.
|
||||||
*/
|
*/
|
||||||
LOCK(&ctx->readylock);
|
LOCK(&ctx->readylock);
|
||||||
if (ctx->want_shutdown) {
|
if (atomic_load(&ctx->want_shutdown)) {
|
||||||
/* shutdown() won the race. */
|
/* shutdown() won the race. */
|
||||||
UNLOCK(&ctx->readylock);
|
UNLOCK(&ctx->readylock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ctx->want_reload)
|
if (!atomic_load(&ctx->want_reload))
|
||||||
WAIT(&ctx->ready, &ctx->readylock);
|
WAIT(&ctx->ready, &ctx->readylock);
|
||||||
UNLOCK(&ctx->readylock);
|
UNLOCK(&ctx->readylock);
|
||||||
}
|
}
|
||||||
@@ -412,24 +414,27 @@ isc_app_ctxrun(isc_appctx_t *ctx0) {
|
|||||||
* wait until woken up.
|
* wait until woken up.
|
||||||
*/
|
*/
|
||||||
LOCK(&ctx->readylock);
|
LOCK(&ctx->readylock);
|
||||||
if (ctx->want_shutdown) {
|
if (atomic_load(&ctx->want_shutdown)) {
|
||||||
/* shutdown() won the race. */
|
/* shutdown() won the race. */
|
||||||
UNLOCK(&ctx->readylock);
|
UNLOCK(&ctx->readylock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ctx->want_reload)
|
if (!atomic_load(&ctx->want_reload)) {
|
||||||
WAIT(&ctx->ready, &ctx->readylock);
|
WAIT(&ctx->ready, &ctx->readylock);
|
||||||
|
}
|
||||||
UNLOCK(&ctx->readylock);
|
UNLOCK(&ctx->readylock);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SIGWAIT */
|
#endif /* HAVE_SIGWAIT */
|
||||||
|
|
||||||
if (ctx->want_reload) {
|
if (atomic_load(&ctx->want_reload)) {
|
||||||
ctx->want_reload = false;
|
atomic_store(&ctx->want_reload, false);
|
||||||
return (ISC_R_RELOAD);
|
return (ISC_R_RELOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->want_shutdown && ctx->blocked)
|
if (atomic_load(&ctx->want_shutdown) &&
|
||||||
|
atomic_load(&ctx->blocked)) {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
@@ -439,16 +444,16 @@ isc_result_t
|
|||||||
isc_app_run(void) {
|
isc_app_run(void) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
is_running = true;
|
atomic_store(&is_running, true);
|
||||||
result = isc_app_ctxrun((isc_appctx_t *)&isc_g_appctx);
|
result = isc_app_ctxrun((isc_appctx_t *)&isc_g_appctx);
|
||||||
is_running = false;
|
atomic_store(&is_running, false);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isc_app_isrunning() {
|
isc_app_isrunning() {
|
||||||
return (is_running);
|
return (atomic_load(&is_running));
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@@ -473,7 +478,7 @@ isc_app_ctxshutdown(isc_appctx_t *ctx0) {
|
|||||||
if (want_kill) {
|
if (want_kill) {
|
||||||
if (isc_bind9 && ctx != &isc_g_appctx)
|
if (isc_bind9 && ctx != &isc_g_appctx)
|
||||||
/* BIND9 internal, but using multiple contexts */
|
/* BIND9 internal, but using multiple contexts */
|
||||||
ctx->want_shutdown = true;
|
atomic_store(&ctx->want_shutdown, true);
|
||||||
else {
|
else {
|
||||||
if (isc_bind9) {
|
if (isc_bind9) {
|
||||||
/* BIND9 internal, single context */
|
/* BIND9 internal, single context */
|
||||||
@@ -489,7 +494,7 @@ isc_app_ctxshutdown(isc_appctx_t *ctx0) {
|
|||||||
else {
|
else {
|
||||||
/* External, multiple contexts */
|
/* External, multiple contexts */
|
||||||
LOCK(&ctx->readylock);
|
LOCK(&ctx->readylock);
|
||||||
ctx->want_shutdown = true;
|
atomic_store(&ctx->want_shutdown, true);
|
||||||
UNLOCK(&ctx->readylock);
|
UNLOCK(&ctx->readylock);
|
||||||
SIGNAL(&ctx->ready);
|
SIGNAL(&ctx->ready);
|
||||||
}
|
}
|
||||||
@@ -527,9 +532,9 @@ isc_app_ctxsuspend(isc_appctx_t *ctx0) {
|
|||||||
if (want_kill) {
|
if (want_kill) {
|
||||||
if (isc_bind9 && ctx != &isc_g_appctx)
|
if (isc_bind9 && ctx != &isc_g_appctx)
|
||||||
/* BIND9 internal, but using multiple contexts */
|
/* BIND9 internal, but using multiple contexts */
|
||||||
ctx->want_reload = true;
|
atomic_store(&ctx->want_reload, true);
|
||||||
else {
|
else {
|
||||||
ctx->want_reload = true;
|
atomic_store(&ctx->want_reload, true);
|
||||||
if (isc_bind9) {
|
if (isc_bind9) {
|
||||||
/* BIND9 internal, single context */
|
/* BIND9 internal, single context */
|
||||||
if (kill(getpid(), SIGHUP) < 0) {
|
if (kill(getpid(), SIGHUP) < 0) {
|
||||||
@@ -544,7 +549,7 @@ isc_app_ctxsuspend(isc_appctx_t *ctx0) {
|
|||||||
else {
|
else {
|
||||||
/* External, multiple contexts */
|
/* External, multiple contexts */
|
||||||
LOCK(&ctx->readylock);
|
LOCK(&ctx->readylock);
|
||||||
ctx->want_reload = true;
|
atomic_store(&ctx->want_reload, true);
|
||||||
UNLOCK(&ctx->readylock);
|
UNLOCK(&ctx->readylock);
|
||||||
SIGNAL(&ctx->ready);
|
SIGNAL(&ctx->ready);
|
||||||
}
|
}
|
||||||
@@ -577,9 +582,9 @@ void
|
|||||||
isc_app_block(void) {
|
isc_app_block(void) {
|
||||||
sigset_t sset;
|
sigset_t sset;
|
||||||
REQUIRE(isc_g_appctx.running);
|
REQUIRE(isc_g_appctx.running);
|
||||||
REQUIRE(!isc_g_appctx.blocked);
|
REQUIRE(!atomic_load(&isc_g_appctx.blocked));
|
||||||
|
|
||||||
isc_g_appctx.blocked = true;
|
atomic_store(&isc_g_appctx.blocked, true);
|
||||||
blockedthread = pthread_self();
|
blockedthread = pthread_self();
|
||||||
RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
|
RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
|
||||||
sigaddset(&sset, SIGINT) == 0 &&
|
sigaddset(&sset, SIGINT) == 0 &&
|
||||||
|
|||||||
+62
-8
@@ -678,9 +678,11 @@ dec_stats(isc_stats_t *stats, isc_statscounter_t counterid) {
|
|||||||
static inline isc_result_t
|
static inline isc_result_t
|
||||||
watch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
watch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
int lockid = FDLOCK_ID(fd);
|
||||||
|
|
||||||
#ifdef USE_KQUEUE
|
#ifdef USE_KQUEUE
|
||||||
struct kevent evchange;
|
struct kevent evchange;
|
||||||
|
(void) lockid;
|
||||||
|
|
||||||
memset(&evchange, 0, sizeof(evchange));
|
memset(&evchange, 0, sizeof(evchange));
|
||||||
if (msg == SELECT_POKE_READ) {
|
if (msg == SELECT_POKE_READ) {
|
||||||
@@ -701,19 +703,37 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
int ret;
|
int ret;
|
||||||
int op;
|
int op;
|
||||||
|
|
||||||
|
LOCK(&thread->fdlock[lockid]);
|
||||||
oldevents = thread->epoll_events[fd];
|
oldevents = thread->epoll_events[fd];
|
||||||
if (msg == SELECT_POKE_READ) {
|
if (msg == SELECT_POKE_READ) {
|
||||||
thread->epoll_events[fd] |= EPOLLIN;
|
thread->epoll_events[fd] |= EPOLLIN;
|
||||||
} else {
|
} else {
|
||||||
thread->epoll_events[fd] |= EPOLLOUT;
|
thread->epoll_events[fd] |= EPOLLOUT;
|
||||||
}
|
}
|
||||||
|
#if __SANITIZE_THREAD__
|
||||||
|
isc__socket_t *sock = thread->fds[fd];
|
||||||
|
#endif
|
||||||
event.events = thread->epoll_events[fd];
|
event.events = thread->epoll_events[fd];
|
||||||
memset(&event.data, 0, sizeof(event.data));
|
memset(&event.data, 0, sizeof(event.data));
|
||||||
event.data.fd = fd;
|
event.data.fd = fd;
|
||||||
|
|
||||||
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
|
|
||||||
op = (oldevents == 0U) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
|
op = (oldevents == 0U) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
|
||||||
|
#if __SANITIZE_THREAD__
|
||||||
|
/*
|
||||||
|
* This is to suppress TSAN warnings about epoll_ctl operating on
|
||||||
|
* on an unlocked socket - lock it if it's lockable and not locked.
|
||||||
|
*/
|
||||||
|
bool unlock = (sock != NULL &&
|
||||||
|
isc_mutex_trylock(&sock->lock) == ISC_R_SUCCESS);
|
||||||
|
#endif
|
||||||
ret = epoll_ctl(thread->epoll_fd, op, fd, &event);
|
ret = epoll_ctl(thread->epoll_fd, op, fd, &event);
|
||||||
|
#if __SANITIZE_THREAD__
|
||||||
|
if (unlock) {
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
@@ -726,8 +746,8 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
return (result);
|
return (result);
|
||||||
#elif defined(USE_DEVPOLL)
|
#elif defined(USE_DEVPOLL)
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
int lockid = FDLOCK_ID(fd);
|
|
||||||
|
|
||||||
|
LOCK(&thread->fdlock[lockid]);
|
||||||
memset(&pfd, 0, sizeof(pfd));
|
memset(&pfd, 0, sizeof(pfd));
|
||||||
if (msg == SELECT_POKE_READ) {
|
if (msg == SELECT_POKE_READ) {
|
||||||
pfd.events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
@@ -745,6 +765,7 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
thread->fdpollinfo[fd].want_write = 1;
|
thread->fdpollinfo[fd].want_write = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
#elif defined(USE_SELECT)
|
#elif defined(USE_SELECT)
|
||||||
@@ -764,9 +785,11 @@ watch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
static inline isc_result_t
|
static inline isc_result_t
|
||||||
unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
int lockid = FDLOCK_ID(fd);
|
||||||
|
|
||||||
#ifdef USE_KQUEUE
|
#ifdef USE_KQUEUE
|
||||||
struct kevent evchange;
|
struct kevent evchange;
|
||||||
|
(void) lockid;
|
||||||
|
|
||||||
memset(&evchange, 0, sizeof(evchange));
|
memset(&evchange, 0, sizeof(evchange));
|
||||||
if (msg == SELECT_POKE_READ) {
|
if (msg == SELECT_POKE_READ) {
|
||||||
@@ -786,6 +809,7 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
int ret;
|
int ret;
|
||||||
int op;
|
int op;
|
||||||
|
|
||||||
|
LOCK(&thread->fdlock[lockid]);
|
||||||
if (msg == SELECT_POKE_READ) {
|
if (msg == SELECT_POKE_READ) {
|
||||||
thread->epoll_events[fd] &= ~(EPOLLIN);
|
thread->epoll_events[fd] &= ~(EPOLLIN);
|
||||||
} else {
|
} else {
|
||||||
@@ -795,9 +819,29 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
event.events = thread->epoll_events[fd];
|
event.events = thread->epoll_events[fd];
|
||||||
memset(&event.data, 0, sizeof(event.data));
|
memset(&event.data, 0, sizeof(event.data));
|
||||||
event.data.fd = fd;
|
event.data.fd = fd;
|
||||||
|
#if __SANITIZE_THREAD__
|
||||||
|
isc__socket_t *sock = thread->fds[fd];
|
||||||
|
#endif
|
||||||
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
|
|
||||||
|
#if __SANITIZE_THREAD__
|
||||||
|
/*
|
||||||
|
* This is to suppress TSAN warnings about epoll_ctl operating on
|
||||||
|
* on an unlocked socket - lock it if it's lockable and not locked.
|
||||||
|
*/
|
||||||
|
bool unlock = (sock != NULL &&
|
||||||
|
isc_mutex_trylock(&sock->lock) == ISC_R_SUCCESS);
|
||||||
|
#endif
|
||||||
|
|
||||||
op = (event.events == 0U) ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
|
op = (event.events == 0U) ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
|
||||||
ret = epoll_ctl(thread->epoll_fd, op, fd, &event);
|
ret = epoll_ctl(thread->epoll_fd, op, fd, &event);
|
||||||
|
|
||||||
|
#if __SANITIZE_THREAD__
|
||||||
|
if (unlock) {
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == -1 && errno != ENOENT) {
|
if (ret == -1 && errno != ENOENT) {
|
||||||
char strbuf[ISC_STRERRORSIZE];
|
char strbuf[ISC_STRERRORSIZE];
|
||||||
strerror_r(errno, strbuf, sizeof(strbuf));
|
strerror_r(errno, strbuf, sizeof(strbuf));
|
||||||
@@ -809,7 +853,6 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
#elif defined(USE_DEVPOLL)
|
#elif defined(USE_DEVPOLL)
|
||||||
struct pollfd pfds[2];
|
struct pollfd pfds[2];
|
||||||
size_t writelen = sizeof(pfds[0]);
|
size_t writelen = sizeof(pfds[0]);
|
||||||
int lockid = FDLOCK_ID(fd);
|
|
||||||
|
|
||||||
memset(pfds, 0, sizeof(pfds));
|
memset(pfds, 0, sizeof(pfds));
|
||||||
pfds[0].events = POLLREMOVE;
|
pfds[0].events = POLLREMOVE;
|
||||||
@@ -820,6 +863,8 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
* only provides a way of canceling per FD, we may need to re-poll the
|
* only provides a way of canceling per FD, we may need to re-poll the
|
||||||
* socket for the other operation.
|
* socket for the other operation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
LOCK(&thread->fdlock[lockid]);
|
||||||
if (msg == SELECT_POKE_READ &&
|
if (msg == SELECT_POKE_READ &&
|
||||||
thread->fdpollinfo[fd].want_write == 1)
|
thread->fdpollinfo[fd].want_write == 1)
|
||||||
{
|
{
|
||||||
@@ -844,6 +889,7 @@ unwatch_fd(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
thread->fdpollinfo[fd].want_write = 0;
|
thread->fdpollinfo[fd].want_write = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
#elif defined(USE_SELECT)
|
#elif defined(USE_SELECT)
|
||||||
@@ -876,17 +922,17 @@ wakeup_socket(isc__socketthread_t *thread, int fd, int msg) {
|
|||||||
|
|
||||||
INSIST(fd >= 0 && fd < (int)thread->manager->maxsocks);
|
INSIST(fd >= 0 && fd < (int)thread->manager->maxsocks);
|
||||||
|
|
||||||
|
LOCK(&thread->fdlock[lockid]);
|
||||||
if (msg == SELECT_POKE_CLOSE) {
|
if (msg == SELECT_POKE_CLOSE) {
|
||||||
/* No one should be updating fdstate, so no need to lock it */
|
|
||||||
INSIST(thread->fdstate[fd] == CLOSE_PENDING);
|
INSIST(thread->fdstate[fd] == CLOSE_PENDING);
|
||||||
thread->fdstate[fd] = CLOSED;
|
thread->fdstate[fd] = CLOSED;
|
||||||
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
(void)unwatch_fd(thread, fd, SELECT_POKE_READ);
|
(void)unwatch_fd(thread, fd, SELECT_POKE_READ);
|
||||||
(void)unwatch_fd(thread, fd, SELECT_POKE_WRITE);
|
(void)unwatch_fd(thread, fd, SELECT_POKE_WRITE);
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&thread->fdlock[lockid]);
|
|
||||||
if (thread->fdstate[fd] == CLOSE_PENDING) {
|
if (thread->fdstate[fd] == CLOSE_PENDING) {
|
||||||
UNLOCK(&thread->fdlock[lockid]);
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
|
|
||||||
@@ -1833,6 +1879,7 @@ destroy(isc__socket_t **sockp) {
|
|||||||
|
|
||||||
socket_log(sock, NULL, CREATION, "destroying");
|
socket_log(sock, NULL, CREATION, "destroying");
|
||||||
|
|
||||||
|
LOCK(&sock->lock);
|
||||||
INSIST(ISC_LIST_EMPTY(sock->connect_list));
|
INSIST(ISC_LIST_EMPTY(sock->connect_list));
|
||||||
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
||||||
INSIST(ISC_LIST_EMPTY(sock->recv_list));
|
INSIST(ISC_LIST_EMPTY(sock->recv_list));
|
||||||
@@ -1846,6 +1893,7 @@ destroy(isc__socket_t **sockp) {
|
|||||||
sock->threadid = -1;
|
sock->threadid = -1;
|
||||||
socketclose(thread, sock, fd);
|
socketclose(thread, sock, fd);
|
||||||
}
|
}
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
|
|
||||||
@@ -3153,6 +3201,7 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
|
|||||||
bool writeable)
|
bool writeable)
|
||||||
{
|
{
|
||||||
isc__socket_t *sock;
|
isc__socket_t *sock;
|
||||||
|
bool listener, connecting;
|
||||||
int lockid = FDLOCK_ID(fd);
|
int lockid = FDLOCK_ID(fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3181,9 +3230,15 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
|
|||||||
UNLOCK(&thread->fdlock[lockid]);
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
UNLOCK(&thread->fdlock[lockid]);
|
||||||
|
|
||||||
|
LOCK(&sock->lock);
|
||||||
|
listener = sock->listener;
|
||||||
|
connecting = sock->connecting;
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
|
||||||
if (readable) {
|
if (readable) {
|
||||||
if (sock->listener) {
|
if (listener) {
|
||||||
internal_accept(sock);
|
internal_accept(sock);
|
||||||
} else {
|
} else {
|
||||||
internal_recv(sock);
|
internal_recv(sock);
|
||||||
@@ -3191,14 +3246,13 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (writeable) {
|
if (writeable) {
|
||||||
if (sock->connecting) {
|
if (connecting) {
|
||||||
internal_connect(sock);
|
internal_connect(sock);
|
||||||
} else {
|
} else {
|
||||||
internal_send(sock);
|
internal_send(sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK(&thread->fdlock[lockid]);
|
|
||||||
if (isc_refcount_decrement(&sock->references) == 1) {
|
if (isc_refcount_decrement(&sock->references) == 1) {
|
||||||
destroy(&sock);
|
destroy(&sock);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -229,7 +229,7 @@ struct ns_clientmgr {
|
|||||||
#define NS_CLIENT_DROPPORT 1
|
#define NS_CLIENT_DROPPORT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LIBNS_EXTERNAL_DATA unsigned int ns_client_requests;
|
LIBNS_EXTERNAL_DATA atomic_uint_fast32_t ns_client_requests;
|
||||||
|
|
||||||
static void read_settimeout(ns_client_t *client, bool newconn);
|
static void read_settimeout(ns_client_t *client, bool newconn);
|
||||||
static void client_read(ns_client_t *client, bool newconn);
|
static void client_read(ns_client_t *client, bool newconn);
|
||||||
@@ -2246,7 +2246,7 @@ ns__client_request(isc_task_t *task, isc_event_t *event) {
|
|||||||
NS_CLIENTSTATE_READING :
|
NS_CLIENTSTATE_READING :
|
||||||
NS_CLIENTSTATE_READY));
|
NS_CLIENTSTATE_READY));
|
||||||
|
|
||||||
ns_client_requests++;
|
atomic_fetch_add(&ns_client_requests, 1);
|
||||||
|
|
||||||
if (event->ev_type == ISC_SOCKEVENT_RECVDONE) {
|
if (event->ev_type == ISC_SOCKEVENT_RECVDONE) {
|
||||||
INSIST(!TCP_CLIENT(client));
|
INSIST(!TCP_CLIENT(client));
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ typedef ISC_LIST(ns_client_t) client_list_t;
|
|||||||
*/
|
*/
|
||||||
#define NS_FAILCACHE_CD 0x01
|
#define NS_FAILCACHE_CD 0x01
|
||||||
|
|
||||||
LIBNS_EXTERNAL_DATA extern unsigned int ns_client_requests;
|
LIBNS_EXTERNAL_DATA extern atomic_uint_fast32_t ns_client_requests;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*** Functions
|
*** Functions
|
||||||
|
|||||||
Reference in New Issue
Block a user