Compare commits
84
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c7e86aa51 | ||
|
|
5c4917f66e | ||
|
|
b7f9192ff1 | ||
|
|
d9fa5d5a9a | ||
|
|
6ab0b3d51a | ||
|
|
8917d2f9b6 | ||
|
|
1a8b581510 | ||
|
|
2c823cc84f | ||
|
|
e4e753f46a | ||
|
|
228e769d75 | ||
|
|
3590a811a2 | ||
|
|
4de0a36a42 | ||
|
|
bbe83c3b2a | ||
|
|
fe745d238d | ||
|
|
f1326c124a | ||
|
|
05cb183b91 | ||
|
|
b7b62bf0b2 | ||
|
|
2c17edf417 | ||
|
|
feba3113c4 | ||
|
|
18194962f2 | ||
|
|
d3786c0cf1 | ||
|
|
1c2f8ab09f | ||
|
|
2f7613333f | ||
|
|
0ff879f145 | ||
|
|
77332eb2c8 | ||
|
|
a8836b381f | ||
|
|
4f9bfe1460 | ||
|
|
7b0ba6eb10 | ||
|
|
6adcd739ca | ||
|
|
0147acd7b6 | ||
|
|
e48b2424aa | ||
|
|
784e64f238 | ||
|
|
ed52ffba38 | ||
|
|
9b6df37303 | ||
|
|
4a992c7a18 | ||
|
|
a1a5559a8a | ||
|
|
f3f7b7df5d | ||
|
|
7443bd5cc7 | ||
|
|
c6ba51cfc4 | ||
|
|
82c418abfa | ||
|
|
b3f06729e5 | ||
|
|
a2254f01c4 | ||
|
|
42e1fb8322 | ||
|
|
7417b79c7a | ||
|
|
85555f29d7 | ||
|
|
754f7588c6 | ||
|
|
20b446cdc3 | ||
|
|
1f3502f564 | ||
|
|
b5cfc1c056 | ||
|
|
43279de8e6 | ||
|
|
7a605b4d05 | ||
|
|
5b448996e5 | ||
|
|
9643a62dd5 | ||
|
|
7c3f419d66 | ||
|
|
8b159c33ac | ||
|
|
9e6f6156f7 | ||
|
|
8648b7cdb2 | ||
|
|
796b38fe0c | ||
|
|
78a6b2689b | ||
|
|
741bc11bdb | ||
|
|
4a26f7d149 | ||
|
|
27a9be3034 | ||
|
|
bb061abbb9 | ||
|
|
63b702d0d0 | ||
|
|
1beba0fa59 | ||
|
|
e1c4a69197 | ||
|
|
684a44b469 | ||
|
|
0cd10c7763 | ||
|
|
4227b7969b | ||
|
|
ccf7bbab5d | ||
|
|
3b1bd3f48b | ||
|
|
aafb804eb8 | ||
|
|
05c6a29c87 | ||
|
|
6d8d06e82e | ||
|
|
fd8788eb94 | ||
|
|
42f0e25a4c | ||
|
|
8d6dc8613a | ||
|
|
dcc0835a3a | ||
|
|
f75a9e32be | ||
|
|
16908ec3d9 | ||
|
|
402f067fc0 | ||
|
|
938fc81493 | ||
|
|
df709dcf8a | ||
|
|
05f2ba973f |
+49
-14
@@ -29,6 +29,9 @@ variables:
|
||||
TARBALL_COMPRESSOR: xz
|
||||
TARBALL_EXTENSION: xz
|
||||
|
||||
# limit jobs when debugging cppcheck
|
||||
DEBUG_CPPCHECK: 1
|
||||
|
||||
stages:
|
||||
- precheck
|
||||
- build
|
||||
@@ -176,7 +179,7 @@ stages:
|
||||
- configure
|
||||
- ltmain.sh
|
||||
- m4/libtool.m4
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
|
||||
.configure: &configure |
|
||||
${CONFIGURE} \
|
||||
@@ -208,7 +211,10 @@ stages:
|
||||
- autoreconf:sid:amd64
|
||||
artifacts:
|
||||
untracked: true
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
.windows_build: &windows_build_job
|
||||
stage: build
|
||||
@@ -238,7 +244,10 @@ stages:
|
||||
- autoreconf:sid:amd64
|
||||
artifacts:
|
||||
untracked: true
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
.setup_interfaces: &setup_interfaces |
|
||||
if [ "$(id -u)" -eq "0" ]; then
|
||||
@@ -261,8 +270,11 @@ stages:
|
||||
- test -s bin/tests/system/systests.output
|
||||
artifacts:
|
||||
untracked: true
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
when: on_failure
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
.kyua_report: &kyua_report_html |
|
||||
kyua --logfile /dev/null report-html \
|
||||
@@ -288,7 +300,7 @@ stages:
|
||||
- 'If (Test-Path C:/CrashDumps/*) { dir C:/CrashDumps; Throw }'
|
||||
artifacts:
|
||||
untracked: true
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
when: on_failure
|
||||
only:
|
||||
- schedules
|
||||
@@ -309,14 +321,19 @@ stages:
|
||||
- kyua.log
|
||||
- kyua.results
|
||||
- kyua_html/
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
when: on_failure
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
.cppcheck_args: &run_cppcheck |
|
||||
cppcheck --enable=warning,performance,portability,information,missingInclude \
|
||||
--dump \
|
||||
--include=config.h \
|
||||
--quiet \
|
||||
--std=c11 \
|
||||
--library=std.cfg \
|
||||
--language=c \
|
||||
--project=compile_commands.json \
|
||||
--error-exitcode=2 \
|
||||
@@ -325,6 +342,7 @@ stages:
|
||||
--output-file=cppcheck.results \
|
||||
--relative-paths="$CI_PROJECT_DIR" \
|
||||
--inline-suppr \
|
||||
-U DOXYGEN \
|
||||
--suppressions-list=util/suppressions.txt
|
||||
|
||||
.cppcheck_report: &cppcheck_report_html |
|
||||
@@ -343,11 +361,12 @@ stages:
|
||||
after_script:
|
||||
- *cppcheck_report_html
|
||||
artifacts:
|
||||
untracked: true
|
||||
paths:
|
||||
- compile_commands.json
|
||||
- cppcheck.results
|
||||
- cppcheck_html/
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
when: on_failure
|
||||
|
||||
### Job Definitions
|
||||
@@ -364,8 +383,11 @@ misc:sid:amd64:
|
||||
- sh util/checklibs.sh > checklibs.out
|
||||
- sh util/tabify-changes < CHANGES > CHANGES.tmp
|
||||
- diff -urNap CHANGES CHANGES.tmp
|
||||
- rm CHANGES.tmp
|
||||
- perl util/check-changes CHANGES
|
||||
- test ! -f CHANGES.SE || sh util/tabify-changes < CHANGES.SE > CHANGES.tmp
|
||||
- test ! -f CHANGES.SE || diff -urNap CHANGES.SE CHANGES.tmp
|
||||
- test ! -f CHANGES.SE || perl util/check-changes master=0 CHANGES.SE
|
||||
- rm CHANGES.tmp
|
||||
- perl -w util/merge_copyrights
|
||||
- diff -urNap util/copyrights util/newcopyrights
|
||||
- rm util/newcopyrights
|
||||
@@ -378,7 +400,7 @@ misc:sid:amd64:
|
||||
paths:
|
||||
- util/newcopyrights
|
||||
- checklibs.out
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
when: on_failure
|
||||
|
||||
🐞:sid:amd64:
|
||||
@@ -422,7 +444,10 @@ docs:sid:amd64:
|
||||
artifacts:
|
||||
paths:
|
||||
- doc/arm/
|
||||
expire_in: "1 month"
|
||||
expire_in: "1 day"
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
push:docs:sid:amd64:
|
||||
<<: *debian_sid_amd64_image
|
||||
@@ -629,8 +654,11 @@ scan-build:buster:amd64:
|
||||
artifacts:
|
||||
paths:
|
||||
- scan-build.reports/
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
when: on_failure
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
# Jobs for regular GCC builds on Debian Sid (amd64)
|
||||
|
||||
@@ -641,6 +669,7 @@ gcc:sid:amd64:
|
||||
EXTRA_CONFIGURE: "--enable-dnstap --with-libidn2"
|
||||
RUN_MAKE_INSTALL: 1
|
||||
MAKE: bear make
|
||||
DEBUG_CPPCHECK: 0
|
||||
<<: *debian_sid_amd64_image
|
||||
<<: *build_job
|
||||
|
||||
@@ -895,7 +924,7 @@ system:tsan:buster:amd64:
|
||||
after_script:
|
||||
- find bin -name 'tsan.*' -exec python3 util/parse_tsan.py {} \;
|
||||
artifacts:
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
paths:
|
||||
- bin/tests/system/*/tsan.*
|
||||
- bin/tests/system/*/*/tsan.*
|
||||
@@ -917,7 +946,7 @@ unit:tsan:buster:amd64:
|
||||
after_script:
|
||||
- find lib -name 'tsan.*' -exec python3 util/parse_tsan.py {} \;
|
||||
artifacts:
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
paths:
|
||||
- lib/*/tests/tsan.*
|
||||
- tsan/
|
||||
@@ -1126,6 +1155,9 @@ system:msvc:windows:amd64:
|
||||
dependencies:
|
||||
- msvc:windows:amd64
|
||||
needs: ["msvc:windows:amd64"]
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
msvc-debug:windows:amd64:
|
||||
<<: *windows_build_job
|
||||
@@ -1143,6 +1175,9 @@ system:msvc-debug:windows:amd64:
|
||||
dependencies:
|
||||
- msvc-debug:windows:amd64
|
||||
needs: ["msvc-debug:windows:amd64"]
|
||||
except:
|
||||
variables:
|
||||
- $DEBUG_CPPCHECK == "1"
|
||||
|
||||
# Job producing a release tarball
|
||||
|
||||
@@ -1184,4 +1219,4 @@ release:sid:amd64:
|
||||
artifacts:
|
||||
paths:
|
||||
- "*.tar.gz"
|
||||
expire_in: "1 week"
|
||||
expire_in: "1 day"
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
5350. [bug] When a view was configured with class CHAOS, the
|
||||
server could crash while processing a query for a
|
||||
non-existent record. [GL #1540]
|
||||
|
||||
5349. [bug] Fix a race in task_pause/unpause. [GL #1571]
|
||||
|
||||
5348. [bug] dnssec-settime -Psync was not being honoured.
|
||||
[GL !2893]
|
||||
|
||||
--- 9.15.8 released ---
|
||||
|
||||
5347. [bug] Fixed a bug that could cause an intermittent crash
|
||||
|
||||
+1
-1
@@ -150,7 +150,7 @@ releases. New features include:
|
||||
- "rndc modzone" reconfigures a single zone, without requiring the entire
|
||||
server to be reconfigured.
|
||||
- "rndc showzone" displays the current configuration of a zone.
|
||||
- "rndc managed-keys" can be used to check the status of RFC 5001 managed
|
||||
- "rndc managed-keys" can be used to check the status of RFC 5011 managed
|
||||
trust anchors, or to force trust anchors to be refreshed.
|
||||
- "max-cache-size" can now be set to a percentage of available memory. The
|
||||
default is 90%.
|
||||
|
||||
+28
-22
@@ -308,7 +308,7 @@ nslookup -query=hinfo -timeout=10
|
||||
The class specifies the protocol group of the information.
|
||||
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = IN; abbreviation = cl)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -318,10 +318,10 @@ nslookup -query=hinfo -timeout=10
|
||||
<term><constant><replaceable><optional>no</optional></replaceable>debug</constant></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Turn on or off the display of the full response packet and
|
||||
any intermediate response packets when searching.
|
||||
Turn on or off the display of the full response packet and
|
||||
any intermediate response packets when searching.
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = nodebug; abbreviation = <optional>no</optional>deb)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -332,9 +332,9 @@ nslookup -query=hinfo -timeout=10
|
||||
<listitem>
|
||||
<para>
|
||||
Turn debugging mode on or off. This displays more about
|
||||
what nslookup is doing.
|
||||
what nslookup is doing.
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = nod2)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -358,7 +358,7 @@ nslookup -query=hinfo -timeout=10
|
||||
names in the domain search list to the request until an
|
||||
answer is received.
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = search)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -370,7 +370,7 @@ nslookup -query=hinfo -timeout=10
|
||||
<para>
|
||||
Change the default TCP/UDP name server port to <replaceable>value</replaceable>.
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = 53; abbreviation = po)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -389,9 +389,15 @@ nslookup -query=hinfo -timeout=10
|
||||
<para>
|
||||
Change the type of the information query.
|
||||
</para>
|
||||
<para>
|
||||
(Default = A; abbreviations = q, ty)
|
||||
<para>
|
||||
(Default = A and then AAAA; abbreviations = q, ty)
|
||||
</para>
|
||||
<para>
|
||||
<emphasis role="bold">Note:</emphasis> It is
|
||||
only possible to specify one query type, only
|
||||
the default behavior looks up both when an
|
||||
alternative is not specified.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -403,7 +409,7 @@ nslookup -query=hinfo -timeout=10
|
||||
have the
|
||||
information.
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = recurse; abbreviation = [no]rec)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -413,9 +419,9 @@ nslookup -query=hinfo -timeout=10
|
||||
<term><constant>ndots=</constant><replaceable>number</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the number of dots (label separators) in a domain
|
||||
that will disable searching. Absolute names always
|
||||
stop searching.
|
||||
Set the number of dots (label separators) in a domain
|
||||
that will disable searching. Absolute names always
|
||||
stop searching.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -446,7 +452,7 @@ nslookup -query=hinfo -timeout=10
|
||||
Always use a virtual circuit when sending requests to the
|
||||
server.
|
||||
</para>
|
||||
<para>
|
||||
<para>
|
||||
(Default = novc)
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -456,15 +462,15 @@ nslookup -query=hinfo -timeout=10
|
||||
<term><constant><replaceable><optional>no</optional></replaceable>fail</constant></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Try the next nameserver if a nameserver responds with
|
||||
SERVFAIL or a referral (nofail) or terminate query
|
||||
(fail) on such a response.
|
||||
</para>
|
||||
<para>
|
||||
Try the next nameserver if a nameserver responds with
|
||||
SERVFAIL or a referral (nofail) or terminate query
|
||||
(fail) on such a response.
|
||||
</para>
|
||||
<para>
|
||||
(Default = nofail)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
+1
-8
@@ -141,7 +141,6 @@ static bool nonearest = false;
|
||||
static bool nosoa = false;
|
||||
static bool notcp = false;
|
||||
static bool sigvalinsecs = false;
|
||||
static unsigned int delay = 0;
|
||||
|
||||
/*
|
||||
* -4 and -6
|
||||
@@ -638,14 +637,10 @@ parse_T_opt(char *option) {
|
||||
/*
|
||||
* force the server to behave (or misbehave) in
|
||||
* specified ways for testing purposes.
|
||||
* delay=xxxx: delay client responses by xxxx ms to
|
||||
* simulate remote servers.
|
||||
* dscp=x: check that dscp values are as
|
||||
* expected and assert otherwise.
|
||||
*/
|
||||
if (!strncmp(option, "delay=", 6)) {
|
||||
delay = atoi(option + 6);
|
||||
} else if (!strcmp(option, "dropedns")) {
|
||||
if (!strcmp(option, "dropedns")) {
|
||||
dropedns = true;
|
||||
} else if (!strncmp(option, "dscp=", 5)) {
|
||||
isc_dscp_check_value = atoi(option + 5);
|
||||
@@ -1318,8 +1313,6 @@ setup(void) {
|
||||
ns_server_setoption(sctx, NS_SERVER_NOTCP, true);
|
||||
if (sigvalinsecs)
|
||||
ns_server_setoption(sctx, NS_SERVER_SIGVALINSECS, true);
|
||||
|
||||
named_g_server->sctx->delay = delay;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -14,6 +14,12 @@ SYSTEMTESTTOP=..
|
||||
|
||||
DIGOPTS="+tcp +nosea +nostat +noquest +nocomm +nocmd -p ${PORT}"
|
||||
|
||||
wait_for_serial() (
|
||||
$DIG $DIGOPTS "@$1" "$2" SOA > "$4"
|
||||
serial=$(awk '$4 == "SOA" { print $7 }' "$4")
|
||||
[ "$3" -eq "${serial:--1}" ]
|
||||
)
|
||||
|
||||
status=0
|
||||
n=0
|
||||
|
||||
@@ -91,11 +97,13 @@ digcomp dig.ns1.test$n postupdate.good || ret=1
|
||||
test $ret -eq 0 || echo_i "failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG $DIGOPTS soa dynamic @10.53.0.2 | grep 2000042408 > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo_i "wait for zone to transfer ($n)"
|
||||
retry_quiet 20 wait_for_serial 10.53.0.2 dynamic 2000042408 dig.ns2.test$n || ret=1
|
||||
|
||||
test $ret -eq 0 || echo_i "failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "check SOA owner case is transfered to slave ($n)"
|
||||
@@ -121,11 +129,13 @@ digcomp dig.ns1.test$n postns1.good || ret=1
|
||||
test $ret -eq 0 || echo_i "failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9
|
||||
do
|
||||
$DIG $DIGOPTS soa dynamic @10.53.0.2 | grep 2000042409 > /dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo_i "wait for zone to transfer ($n)"
|
||||
retry_quiet 20 wait_for_serial 10.53.0.2 dynamic 2000042409 dig.ns2.test$n || ret=1
|
||||
|
||||
test $ret -eq 0 || echo_i "failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "check A owner case is transfered to slave ($n)"
|
||||
|
||||
@@ -378,14 +378,14 @@ nextpartpeek() {
|
||||
_search_log() (
|
||||
msg="$1"
|
||||
file="$2"
|
||||
nextpart "$file" | grep -F "$msg" > /dev/null
|
||||
nextpart "$file" | grep -F -e "$msg" > /dev/null
|
||||
)
|
||||
|
||||
# _search_log_peek: look for message $1 in file $2 with nextpartpeek().
|
||||
_search_log_peek() (
|
||||
msg="$1"
|
||||
file="$2"
|
||||
nextpartpeek "$file" | grep -F "$msg" > /dev/null
|
||||
nextpartpeek "$file" | grep -F -e "$msg" > /dev/null
|
||||
)
|
||||
|
||||
# wait_for_log: wait until message $2 in file $3 appears. Bail out after
|
||||
|
||||
@@ -3671,11 +3671,19 @@ dig_with_opts . dnskey +ednsopt=KEY-TAG:fffe +ednsopt=KEY-TAG:fffd @10.53.0.1 >
|
||||
grep "trust-anchor-telemetry './IN' from .* 65534" ns1/named.run > /dev/null || ret=1
|
||||
grep "trust-anchor-telemetry './IN' from .* 65533" ns1/named.run > /dev/null && ret=1
|
||||
$PERL $SYSTEMTESTTOP/stop.pl dnssec ns1 || ret=1
|
||||
nextpart ns1/named.run > /dev/null
|
||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} dnssec ns1 || ret=1
|
||||
n=$(($n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "waiting for root server to finish reloading ($n)"
|
||||
ret=0
|
||||
wait_for_log 20 "all zones loaded" ns1/named.run || ret=1
|
||||
n=$(($n+1))
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "check that the view is logged in messages from the validator when using views ($n)"
|
||||
ret=0
|
||||
grep "view rec: *validat" ns4/named.run > /dev/null || ret=1
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
rm -f */named.conf
|
||||
rm -f */named.memstats
|
||||
rm -f */named.run
|
||||
rm -f */named.run.prev
|
||||
rm -f */named.stats
|
||||
rm -f dig.out*
|
||||
rm -f dnstap.out dnstap.hex
|
||||
|
||||
@@ -35,7 +35,21 @@ do
|
||||
status=`expr $status + $ret`
|
||||
done
|
||||
|
||||
echo_i "wait for servers to finish loading"
|
||||
ret=0
|
||||
wait_for_log 20 "all zones loaded" ns1/named.run || ret=1
|
||||
wait_for_log 20 "all zones loaded" ns2/named.run || ret=1
|
||||
wait_for_log 20 "all zones loaded" ns3/named.run || ret=1
|
||||
wait_for_log 20 "all zones loaded" ns4/named.run || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
# both the 'a.example/A' lookup and the './NS' lookup to ns1
|
||||
# need tocomplete before reopening/rolling for the counts to
|
||||
# be correct.
|
||||
|
||||
$DIG $DIGOPTS @10.53.0.3 a.example > dig.out
|
||||
wait_for_log 20 "(./NS): query_reset" ns1/named.run || true
|
||||
|
||||
# check three different dnstap reopen/roll methods:
|
||||
# ns1: dnstap-reopen; ns2: dnstap -reopen; ns3: dnstap -roll
|
||||
@@ -71,6 +85,7 @@ EOF
|
||||
$RNDCCMD -s 10.53.0.1 stop | sed 's/^/ns1 /' | cat_i
|
||||
$RNDCCMD -s 10.53.0.2 stop | sed 's/^/ns2 /' | cat_i
|
||||
$RNDCCMD -s 10.53.0.3 stop | sed 's/^/ns3 /' | cat_i
|
||||
|
||||
sleep 1
|
||||
|
||||
echo_i "checking initial message counts"
|
||||
|
||||
@@ -1351,6 +1351,7 @@ $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} inline ns3
|
||||
# receive_secure_serial() should refrain from introducing any zone changes.
|
||||
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --halt --port ${CONTROLPORT} inline ns3
|
||||
ensure_sigs_only_in_journal delayedkeys ns3/delayedkeys.db.signed
|
||||
nextpart ns3/named.run > /dev/null
|
||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} inline ns3
|
||||
# We can now test whether the secure zone journal was correctly processed:
|
||||
# unless the records contained in it were scheduled for resigning, no resigning
|
||||
|
||||
@@ -540,7 +540,9 @@ n=`expr $n + 1`
|
||||
echo_i "checking that a mirror zone can be deleted using rndc ($n)"
|
||||
ret=0
|
||||
# Remove the mirror zone added in the previous test.
|
||||
nextpart ns3/named.run > /dev/null
|
||||
$RNDCCMD 10.53.0.3 delzone verify-addzone > rndc.out.ns3.test$n 2>&1 || ret=1
|
||||
wait_for_log 20 "zone verify-addzone/IN: mirror zone is no longer in use; reverting to normal recursion" ns3/named.run || ret=1
|
||||
# Check whether the mirror zone was removed.
|
||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||
grep "NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1
|
||||
|
||||
@@ -172,7 +172,7 @@ n=$((n+1))
|
||||
echo_i "remove untrusted standby key, check timer restarts ($n)"
|
||||
ret=0
|
||||
mkeys_sync_on 2 || ret=1
|
||||
t1=$(grep "trust pending" ns2/managed-keys.bind)
|
||||
t1=$(grep "trust pending" ns2/managed-keys.bind) || true
|
||||
$SETTIME -D now -K ns1 "$standby1" > /dev/null
|
||||
mkeys_loadkeys_on 1 || ret=1
|
||||
# Less than a second may have passed since the last time ns2 received a
|
||||
@@ -182,7 +182,7 @@ mkeys_loadkeys_on 1 || ret=1
|
||||
sleep 1
|
||||
mkeys_refresh_on 2 || ret=1
|
||||
mkeys_sync_on 2 || ret=1
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind)
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind) || true
|
||||
# trust pending date must be different
|
||||
[ -n "$t2" ] || ret=1
|
||||
[ "$t1" = "$t2" ] && ret=1
|
||||
@@ -220,7 +220,7 @@ count=$(grep -c "remove at" rndc.out.$n) || true
|
||||
count=$(grep -c "trust pending" rndc.out.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
# pending date moved forward for the standby key
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind)
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind) || true
|
||||
[ -n "$t2" ] || ret=1
|
||||
[ "$t1" = "$t2" ] && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
@@ -254,7 +254,7 @@ count=$(grep -c "remove at" rndc.out.$n) || true
|
||||
count=$(grep -c "trust pending" rndc.out.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
# pending date moved forward for the standby key
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind)
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind) || true
|
||||
[ -n "$t2" ] || ret=1
|
||||
[ "$t1" = "$t2" ] && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
@@ -292,7 +292,7 @@ count=$(grep -c "remove at" rndc.out.$n) || true
|
||||
count=$(grep -c "trust pending" rndc.out.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
# pending date moved forward for the standby key
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind)
|
||||
t2=$(grep "trust pending" ns2/managed-keys.bind) || true
|
||||
[ -n "$t2" ] || ret=1
|
||||
[ "$t1" = "$t2" ] && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
@@ -571,7 +571,7 @@ ret=0
|
||||
# set using -T mkeytimers).
|
||||
mkeys_refresh_on 2 || ret=1
|
||||
mkeys_status_on 2 > rndc.out.1.$n 2>&1 || ret=1
|
||||
t1=$(grep 'next refresh:' rndc.out.1.$n)
|
||||
t1=$(grep 'next refresh:' rndc.out.1.$n) || true
|
||||
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port "${CONTROLPORT}" mkeys ns1
|
||||
rm -f ns1/root.db.signed.jnl
|
||||
cp ns1/root.db ns1/root.db.signed
|
||||
@@ -594,7 +594,7 @@ count=$(grep -c "trust" rndc.out.2.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
count=$(grep -c "trusted since" rndc.out.2.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
t2=$(grep 'next refresh:' rndc.out.2.$n)
|
||||
t2=$(grep 'next refresh:' rndc.out.2.$n) || true
|
||||
[ "$t1" = "$t2" ] && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
@@ -605,7 +605,7 @@ ret=0
|
||||
# Refresh keys first to prevent previous checks from influencing this one
|
||||
mkeys_refresh_on 2 || ret=1
|
||||
mkeys_status_on 2 > rndc.out.1.$n 2>&1 || ret=1
|
||||
t1=$(grep 'next refresh:' rndc.out.1.$n)
|
||||
t1=$(grep 'next refresh:' rndc.out.1.$n) || true
|
||||
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port "${CONTROLPORT}" mkeys ns1
|
||||
rm -f ns1/root.db.signed.jnl
|
||||
cat ns1/K*.key >> ns1/root.db.signed
|
||||
@@ -632,7 +632,7 @@ count=$(grep -c "trust" rndc.out.2.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
count=$(grep -c "trusted since" rndc.out.2.$n) || true
|
||||
[ "$count" -eq 1 ] || ret=1
|
||||
t2=$(grep 'next refresh:' rndc.out.2.$n)
|
||||
t2=$(grep 'next refresh:' rndc.out.2.$n) || true
|
||||
[ "$t1" = "$t2" ] && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
@@ -682,7 +682,7 @@ echo_i "check that trust-anchor-telemetry queries contain the correct key ($n)"
|
||||
ret=0
|
||||
# convert the hexadecimal key from the TAT query into decimal and
|
||||
# compare against the known key.
|
||||
tathex=$(grep "query '_ta-[0-9a-f][0-9a-f]*/NULL/IN' approved" ns1/named.run | awk '{print $6; exit 0}' | sed -e 's/(_ta-\([0-9a-f][0-9a-f]*\)):/\1/')
|
||||
tathex=$(grep "query '_ta-[0-9a-f][0-9a-f]*/NULL/IN' approved" ns1/named.run | awk '{print $6; exit 0}' | sed -e 's/(_ta-\([0-9a-f][0-9a-f]*\)):/\1/') || true
|
||||
tatkey=$($PERL -e 'printf("%d\n", hex(@ARGV[0]));' "$tathex")
|
||||
realkey=$(rndccmd 10.53.0.2 secroots - | sed -n 's#.*SHA256/\([0-9][0-9]*\) ; .*managed.*#\1#p')
|
||||
[ "$tatkey" -eq "$realkey" ] || ret=1
|
||||
|
||||
@@ -11,6 +11,7 @@ rm -f dig.out.*
|
||||
rm -f ns*/named.memstats
|
||||
rm -f ns*/named.run
|
||||
rm -f ns*/named.stats
|
||||
rm -f ns*/named.stats.prev
|
||||
rm -f ns*/named.lock
|
||||
rm -f ns*/named.conf
|
||||
rm -f ns*/managed-keys.bind*
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
$SHELL ./clean.sh
|
||||
|
||||
copy_setports ns1/named.conf.in ns1/named.conf
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
copy_setports ns3/named.conf.in ns3/named.conf
|
||||
copy_setports ns4/named.conf.in ns4/named.conf
|
||||
|
||||
touch ns2/named.stats
|
||||
|
||||
@@ -36,8 +36,11 @@ status=`expr $status + $ret`
|
||||
echo_i "checking that dig added padding ($n)"
|
||||
ret=0
|
||||
n=`expr $n + 1`
|
||||
nextpart ns2/named.stats > /dev/null
|
||||
$RNDCCMD 10.53.0.2 stats
|
||||
grep "EDNS padding option received" ns2/named.stats > /dev/null || ret=1
|
||||
wait_for_log_peek 5 "--- Statistics Dump ---" ns2/named.stats || ret=1
|
||||
nextpart ns2/named.stats | grep "EDNS padding option received" > /dev/null || ret=1
|
||||
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
@@ -88,28 +91,30 @@ status=`expr $status + $ret`
|
||||
echo_i "checking that a TCP and padding server config enables padding ($n)"
|
||||
ret=0
|
||||
n=`expr $n + 1`
|
||||
nextpart ns2/named.stats > /dev/null
|
||||
$RNDCCMD 10.53.0.2 stats
|
||||
opad=`grep "EDNS padding option received" ns2/named.stats | \
|
||||
tail -1 | awk '{ print $1}'`
|
||||
wait_for_log_peek 5 "--- Statistics Dump ---" ns2/named.stats || ret=1
|
||||
opad=`nextpart ns2/named.stats | awk '/EDNS padding option received/ { print $1}'`
|
||||
$DIG $DIGOPTS foo.example @10.53.0.3 > dig.out.test$n
|
||||
$RNDCCMD 10.53.0.2 stats
|
||||
npad=`grep "EDNS padding option received" ns2/named.stats | \
|
||||
tail -1 | awk '{ print $1}'`
|
||||
if [ "$opad" -eq "$npad" ]; then ret=1; fi
|
||||
wait_for_log_peek 5 "--- Statistics Dump ---" ns2/named.stats || ret=1
|
||||
npad=`nextpart ns2/named.stats | awk '/EDNS padding option received/ { print $1}'`
|
||||
if [ "$opad" -eq "$npad" ]; then echo_i "error: opad ($opad) == npad ($npad)"; ret=1; fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo_i "checking that a padding server config should enforce TCP ($n)"
|
||||
ret=0
|
||||
n=`expr $n + 1`
|
||||
nextpart ns2/named.stats > /dev/null
|
||||
$RNDCCMD 10.53.0.2 stats
|
||||
opad=`grep "EDNS padding option received" ns2/named.stats | \
|
||||
tail -1 | awk '{ print $1}'`
|
||||
wait_for_log_peek 5 "--- Statistics Dump ---" ns2/named.stats || ret=1
|
||||
opad=`nextpart ns2/named.stats | awk '/EDNS padding option received/ { print $1}'`
|
||||
$DIG $DIGOPTS foo.example @10.53.0.4 > dig.out.test$n
|
||||
$RNDCCMD 10.53.0.2 stats
|
||||
npad=`grep "EDNS padding option received" ns2/named.stats | \
|
||||
tail -1 | awk '{ print $1}'`
|
||||
if [ "$opad" -ne "$npad" ]; then ret=1; fi
|
||||
wait_for_log_peek 5 "--- Statistics Dump ---" ns2/named.stats || ret=1
|
||||
npad=`nextpart ns2/named.stats | awk '/EDNS padding option received/ { print $1}'`
|
||||
if [ "$opad" -ne "$npad" ]; then echo_i "error: opad ($opad) != npad ($npad)"; ret=1; fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
############################################################################
|
||||
# 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.
|
||||
############################################################################
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# This tool acts as a TCP/UDP proxy and delays all incoming packets by 500
|
||||
# miliseconds.
|
||||
#
|
||||
# We use it to check pipelining - a client sents 8 questions over a
|
||||
# pipelined connection - that require asking a normal (examplea) and a
|
||||
# slow-responding (exampleb) servers:
|
||||
# a.examplea
|
||||
# a.exampleb
|
||||
# b.examplea
|
||||
# b.exampleb
|
||||
# c.examplea
|
||||
# c.exampleb
|
||||
# d.examplea
|
||||
# d.exampleb
|
||||
#
|
||||
# If pipelining works properly the answers will be returned out of order
|
||||
# with all answers from examplea returned first, and then all answers
|
||||
# from exampleb.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import select
|
||||
import signal
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
import struct
|
||||
|
||||
DELAY = 0.5
|
||||
THREADS = []
|
||||
|
||||
def log(msg):
|
||||
print(datetime.datetime.now().strftime('%d-%b-%Y %H:%M:%S.%f ') + msg)
|
||||
|
||||
|
||||
def sigterm(*_):
|
||||
log('SIGTERM received, shutting down')
|
||||
for thread in THREADS:
|
||||
thread.close()
|
||||
thread.join()
|
||||
os.remove('ans.pid')
|
||||
sys.exit(0)
|
||||
|
||||
class TCPDelayer(threading.Thread):
|
||||
""" For a given TCP connection conn we open a connection to (ip, port),
|
||||
and then we delay each incoming packet by DELAY by putting it in a
|
||||
queue.
|
||||
In the pipelined test TCP should not be used, but it's here for
|
||||
completnes.
|
||||
"""
|
||||
def __init__(self, conn, ip, port):
|
||||
threading.Thread.__init__(self)
|
||||
self.conn = conn
|
||||
self.cconn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.cconn.connect((ip, port))
|
||||
self.queue = []
|
||||
self.running = True
|
||||
|
||||
def close(self):
|
||||
self.running = False
|
||||
|
||||
def run(self):
|
||||
while self.running:
|
||||
curr_timeout = 0.5
|
||||
try:
|
||||
curr_timeout = self.queue[0][0]-time.time()
|
||||
except StopIteration:
|
||||
pass
|
||||
if curr_timeout > 0:
|
||||
if curr_timeout == 0:
|
||||
curr_timeout = 0.5
|
||||
rfds, _, _ = select.select([self.conn, self.cconn], [], [], curr_timeout)
|
||||
if self.conn in rfds:
|
||||
data = self.conn.recv(65535)
|
||||
if not data:
|
||||
return
|
||||
self.queue.append((time.time() + DELAY, data))
|
||||
if self.cconn in rfds:
|
||||
data = self.cconn.recv(65535)
|
||||
if not data == 0:
|
||||
return
|
||||
self.conn.send(data)
|
||||
try:
|
||||
while self.queue[0][0]-time.time() < 0:
|
||||
_, data = self.queue.pop(0)
|
||||
self.cconn.send(data)
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
class UDPDelayer(threading.Thread):
|
||||
""" Every incoming UDP packet is put in a queue for DELAY time, then
|
||||
it's sent to (ip, port). We remember the query id to send the
|
||||
response we get to a proper source, responsed are not delayed.
|
||||
"""
|
||||
def __init__(self, usock, ip, port):
|
||||
threading.Thread.__init__(self)
|
||||
self.sock = usock
|
||||
self.csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.dst = (ip, port)
|
||||
self.queue = []
|
||||
self.qid_mapping = {}
|
||||
self.running = True
|
||||
|
||||
def close(self):
|
||||
self.running = False
|
||||
|
||||
def run(self):
|
||||
while self.running:
|
||||
curr_timeout = 0.5
|
||||
if self.queue:
|
||||
curr_timeout = self.queue[0][0]-time.time()
|
||||
if curr_timeout >= 0:
|
||||
if curr_timeout == 0:
|
||||
curr_timeout = 0.5
|
||||
rfds, _, _ = select.select([self.sock, self.csock], [], [], curr_timeout)
|
||||
if self.sock in rfds:
|
||||
data, addr = self.sock.recvfrom(65535)
|
||||
if not data:
|
||||
return
|
||||
self.queue.append((time.time() + DELAY, data))
|
||||
qid = struct.unpack('>H', data[:2])[0]
|
||||
log('Received a query from %s, queryid %d' % (str(addr), qid))
|
||||
self.qid_mapping[qid] = addr
|
||||
if self.csock in rfds:
|
||||
data, addr = self.csock.recvfrom(65535)
|
||||
if not data:
|
||||
return
|
||||
qid = struct.unpack('>H', data[:2])[0]
|
||||
dst = self.qid_mapping.get(qid)
|
||||
if dst is not None:
|
||||
self.sock.sendto(data, dst)
|
||||
log('Received a response from %s, queryid %d, sending to %s' % (str(addr), qid, str(dst)))
|
||||
while self.queue and self.queue[0][0]-time.time() < 0:
|
||||
_, data = self.queue.pop(0)
|
||||
qid = struct.unpack('>H', data[:2])[0]
|
||||
log('Sending a query to %s, queryid %d' % (str(self.dst), qid))
|
||||
self.csock.sendto(data, self.dst)
|
||||
|
||||
def main():
|
||||
signal.signal(signal.SIGTERM, sigterm)
|
||||
signal.signal(signal.SIGINT, sigterm)
|
||||
|
||||
with open('ans.pid', 'w') as pidfile:
|
||||
print(os.getpid(), file=pidfile)
|
||||
|
||||
listenip = '10.53.0.5'
|
||||
serverip = '10.53.0.2'
|
||||
|
||||
try:
|
||||
port = int(os.environ['PORT'])
|
||||
except KeyError:
|
||||
port = 5300
|
||||
|
||||
log('Listening on %s:%d' % (listenip, port))
|
||||
|
||||
usock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
usock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
usock.bind((listenip, port))
|
||||
thread = UDPDelayer(usock, serverip, port)
|
||||
thread.start()
|
||||
THREADS.append(thread)
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.bind((listenip, port))
|
||||
sock.listen(1)
|
||||
|
||||
while True:
|
||||
(clientsock, _) = sock.accept()
|
||||
log('Accepted connection from %s' % clientsock)
|
||||
thread = TCPDelayer(clientsock, serverip, port)
|
||||
thread.start()
|
||||
THREADS.append(thread)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -19,7 +19,7 @@ $TTL 300
|
||||
a.root-servers.nil. A 10.53.0.1
|
||||
|
||||
examplea. NS ns2.examplea.
|
||||
ns2.examplea. A 10.53.0.2
|
||||
ns2.examplea. A 10.53.0.5
|
||||
|
||||
exampleb. NS ns3.exampleb.
|
||||
ns3.exampleb. A 10.53.0.3
|
||||
|
||||
@@ -17,7 +17,7 @@ examplea IN SOA mname1. . (
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
examplea. NS ns2.examplea.
|
||||
ns2.examplea. A 10.53.0.2
|
||||
ns2.examplea. A 10.53.0.5
|
||||
|
||||
$ORIGIN examplea.
|
||||
a A 10.0.1.1
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
-m record,size,mctx -c named.conf -d 99 -D pipelined-ns3 -X named.lock -g -T delay=200
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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.
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
if test -n "$PYTHON"
|
||||
then
|
||||
if $PYTHON -c "import dns" 2> /dev/null
|
||||
then
|
||||
:
|
||||
else
|
||||
echo_i "This test requires the dnspython module." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo_i "This test requires Python and the dnspython module." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,5 @@
|
||||
$TTL 3600
|
||||
@ CHAOS SOA @ @ 1970010100 86400 600 86400 300
|
||||
@ CHAOS NS @
|
||||
version CHAOS TXT "CH 1.0"
|
||||
hostname CHAOS TXT "unknown"
|
||||
@@ -46,7 +46,10 @@ server fd92:7065:b8e:ffff::1000 {
|
||||
* "globalcache" before the recursive "default"/IN view is configured.
|
||||
*/
|
||||
view "class" chaos {
|
||||
match-clients { none; };
|
||||
zone "chaostest" CHAOS {
|
||||
type master;
|
||||
file "chaostest.db";
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -805,5 +805,13 @@ grep "running as: .* -m record,size,mctx " ns1/named.run > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking NXDOMAIN is returned when querying non existing domain in CH class ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS @10.53.0.1 id.hostname txt ch > dig.ns1.out.${n} || ret=1
|
||||
grep "status: NXDOMAIN" dig.ns1.out.${n} > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
||||
@@ -55,6 +55,9 @@ cksk4=`$REVOKE $cksk3`
|
||||
echo_i "setting up sync key"
|
||||
cksk5=`$KEYGEN -q -a rsasha1 -fk -P now+1mo -A now+1mo -Psync now $czone`
|
||||
|
||||
echo_i "and future sync key"
|
||||
cksk6=`$KEYGEN -q -a rsasha1 -fk -P now+1mo -A now+1mo -Psync now+1mo $czone`
|
||||
|
||||
echo_i "generating parent keys"
|
||||
pzsk=`$KEYGEN -q -a rsasha1 $pzone`
|
||||
pksk=`$KEYGEN -q -a rsasha1 -fk $pzone`
|
||||
@@ -348,6 +351,7 @@ awk 'BEGIN { r=1 } $2 == "CDS" { r=0 } END { exit r }' $cfile.signed || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
# this also checks that the future sync record is not yet published
|
||||
echo_i "checking sync record deletion"
|
||||
ret=0
|
||||
$SETTIME -P now -A now -Dsync now ${cksk5} > /dev/null
|
||||
|
||||
@@ -56,6 +56,24 @@ if [ -n "${FAILED_TESTS}" ]; then
|
||||
status=1
|
||||
fi
|
||||
|
||||
CRASHED_TESTS=`find . -name 'core*' -or -name '*.core' | cut -d'/' -f2 | sort -u | sed -e 's/^/I: /'`
|
||||
if [ -n "${CRASHED_TESTS}" ]; then
|
||||
echoinfo "I:Core dumps were found for the following system tests:"
|
||||
echoinfo "${CRASHED_TESTS}"
|
||||
fi
|
||||
|
||||
ASSERTION_FAILED_TESTS=`find . -name named.run | xargs grep "assertion failure" | cut -d'/' -f2 | sort -u | sed -e 's/^/I: /'`
|
||||
if [ -n "${ASSERTION_FAILED_TESTS}" ]; then
|
||||
echoinfo "I:Assertion failures were detected for the following system tests:"
|
||||
echoinfo "${ASSERTION_FAILED_TESTS}"
|
||||
fi
|
||||
|
||||
TSAN_REPORT_TESTS=`find . -name 'tsan.*' | cut -d'/' -f2 | sort -u | sed -e 's/^/I: /'`
|
||||
if [ -n "${TSAN_REPORT_TESTS}" ]; then
|
||||
echoinfo "I:ThreadSanitizer reported issues for the following system tests:"
|
||||
echoinfo "${TSAN_REPORT_TESTS}"
|
||||
fi
|
||||
|
||||
RESULTS_FOUND=`grep -c 'R:[a-z0-9_-][a-z0-9_-]*:[A-Z][A-Z]*' systests.output`
|
||||
TESTS_RUN=`echo "${SUBDIRS}" | wc -w`
|
||||
if [ "${RESULTS_FOUND}" -ne "${TESTS_RUN}" ]; then
|
||||
|
||||
@@ -9300,6 +9300,11 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
|
||||
Specifying <command>version none</command>
|
||||
disables processing of the queries.
|
||||
</para>
|
||||
<para>
|
||||
Setting <command>version</command> to any value
|
||||
(including <literal>none</literal>) will also
|
||||
disable queries for <literal>authors.bind TXT CH</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ int main(int argc, char **argv)
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
target = target ? target + 1 : argv[0];
|
||||
target = (target != NULL) ? target + 1 : argv[0];
|
||||
if (strncmp(target, "lt-", 3) == 0) {
|
||||
target += 3;
|
||||
}
|
||||
|
||||
+7
-22
@@ -1340,13 +1340,7 @@ dns_client_startresolve(dns_client_t *client, const dns_name_t *name,
|
||||
ISC_LIST_INIT(event->answerlist);
|
||||
|
||||
rctx = isc_mem_get(mctx, sizeof(*rctx));
|
||||
if (rctx == NULL)
|
||||
result = ISC_R_NOMEMORY;
|
||||
else {
|
||||
isc_mutex_init(&rctx->lock);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
isc_mutex_init(&rctx->lock);
|
||||
|
||||
result = getrdataset(mctx, &rdataset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -1748,13 +1742,7 @@ dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
|
||||
action, arg, sizeof(*event));
|
||||
|
||||
ctx = isc_mem_get(client->mctx, sizeof(*ctx));
|
||||
if (ctx == NULL)
|
||||
result = ISC_R_NOMEMORY;
|
||||
else {
|
||||
isc_mutex_init(&ctx->lock);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
isc_mutex_init(&ctx->lock);
|
||||
|
||||
ctx->client = client;
|
||||
ISC_LINK_INIT(ctx, link);
|
||||
@@ -1787,14 +1775,11 @@ dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
|
||||
|
||||
isc_refcount_decrement(&client->references);
|
||||
|
||||
cleanup:
|
||||
if (ctx != NULL) {
|
||||
LOCK(&client->lock);
|
||||
ISC_LIST_UNLINK(client->reqctxs, ctx, link);
|
||||
UNLOCK(&client->lock);
|
||||
isc_mutex_destroy(&ctx->lock);
|
||||
isc_mem_put(client->mctx, ctx, sizeof(*ctx));
|
||||
}
|
||||
LOCK(&client->lock);
|
||||
ISC_LIST_UNLINK(client->reqctxs, ctx, link);
|
||||
UNLOCK(&client->lock);
|
||||
isc_mutex_destroy(&ctx->lock);
|
||||
isc_mem_put(client->mctx, ctx, sizeof(*ctx));
|
||||
if (event != NULL)
|
||||
isc_event_free(ISC_EVENT_PTR(&event));
|
||||
isc_task_detach(&tclone);
|
||||
|
||||
+10
-11
@@ -648,6 +648,7 @@ syncpublish(dst_key_t *key, isc_stdtime_t now) {
|
||||
isc_stdtime_t when;
|
||||
dst_key_state_t state;
|
||||
int major, minor;
|
||||
bool publish;
|
||||
|
||||
/*
|
||||
* Is this an old-style key?
|
||||
@@ -670,18 +671,16 @@ syncpublish(dst_key_t *key, isc_stdtime_t now) {
|
||||
}
|
||||
|
||||
/* If no kasp state, check timings. */
|
||||
publish = false;
|
||||
result = dst_key_gettime(key, DST_TIME_SYNCPUBLISH, &when);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (false);
|
||||
if (result == ISC_R_SUCCESS && when <= now) {
|
||||
publish = true;
|
||||
}
|
||||
result = dst_key_gettime(key, DST_TIME_SYNCDELETE, &when);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (true);
|
||||
if (result == ISC_R_SUCCESS && when < now) {
|
||||
publish = false;
|
||||
}
|
||||
if (when <= now) {
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
return (publish);
|
||||
}
|
||||
|
||||
/*%<
|
||||
@@ -1825,14 +1824,14 @@ publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, const dns_name_t *origin,
|
||||
RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey));
|
||||
dst_key_format(key->key, keystr, sizeof(keystr));
|
||||
|
||||
report("Fetching %s (%s) from key %s.\n",
|
||||
report("Fetching %s (%s) from key %s.",
|
||||
keystr, key->ksk ? (key->zsk ? "CSK" : "KSK") : "ZSK",
|
||||
key->source == dns_keysource_user ? "file" : "repository");
|
||||
|
||||
if (key->prepublish && ttl > key->prepublish) {
|
||||
isc_stdtime_t now;
|
||||
|
||||
report("Key %s: Delaying activation to match the DNSKEY TTL.\n",
|
||||
report("Key %s: Delaying activation to match the DNSKEY TTL.",
|
||||
keystr, ttl);
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
@@ -1857,7 +1856,7 @@ remove_key(dns_diff_t *diff, dns_dnsseckey_t *key, const dns_name_t *origin,
|
||||
char alg[80];
|
||||
|
||||
dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg));
|
||||
report("Removing %s key %d/%s from DNSKEY RRset.\n",
|
||||
report("Removing %s key %d/%s from DNSKEY RRset.",
|
||||
reason, dst_key_id(key->key), alg);
|
||||
|
||||
RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey));
|
||||
|
||||
@@ -130,7 +130,7 @@ static isc_result_t
|
||||
write_data(FILE *file, unsigned char *datap, void *arg, uint64_t *crc) {
|
||||
isc_result_t result;
|
||||
size_t ret = 0;
|
||||
data_holder_t *data = (data_holder_t *)datap;
|
||||
data_holder_t *data;
|
||||
data_holder_t temp;
|
||||
off_t where;
|
||||
|
||||
@@ -138,7 +138,8 @@ write_data(FILE *file, unsigned char *datap, void *arg, uint64_t *crc) {
|
||||
|
||||
REQUIRE(file != NULL);
|
||||
REQUIRE(crc != NULL);
|
||||
REQUIRE(data != NULL);
|
||||
REQUIRE(datap != NULL);
|
||||
data = (data_holder_t *)datap;
|
||||
REQUIRE((data->len == 0 && data->data == NULL) ||
|
||||
(data->len != 0 && data->data != NULL));
|
||||
|
||||
|
||||
+13
-5
@@ -1245,8 +1245,9 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
ztoptions |= DNS_ZTFIND_NOEXACT;
|
||||
result = dns_zt_find(view->zonetable, name, ztoptions,
|
||||
NULL, &zone);
|
||||
} else
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
UNLOCK(&view->lock);
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
|
||||
result = dns_zone_getdb(zone, &db);
|
||||
@@ -1261,12 +1262,15 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
* We have a cache; try it.
|
||||
*/
|
||||
dns_db_attach(view->cachedb, &db);
|
||||
} else {
|
||||
} else if (use_hints && view->hints != NULL) {
|
||||
/*
|
||||
* Maybe we have hints...
|
||||
*/
|
||||
try_hints = true;
|
||||
goto finish;
|
||||
} else {
|
||||
result = DNS_R_NXDOMAIN;
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
/*
|
||||
@@ -1287,6 +1291,7 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
result = ISC_R_SUCCESS;
|
||||
else if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (use_cache && view->cachedb != NULL && db != view->hints) {
|
||||
/*
|
||||
* We found an answer, but the cache may be better.
|
||||
@@ -1327,13 +1332,16 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
* have a zone delegation, so use it.
|
||||
*/
|
||||
use_zone = true;
|
||||
} else {
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (use_hints && view->hints != NULL) {
|
||||
/*
|
||||
* Maybe we have hints...
|
||||
*/
|
||||
try_hints = true;
|
||||
result = ISC_R_SUCCESS;
|
||||
} else {
|
||||
result = DNS_R_NXDOMAIN;
|
||||
}
|
||||
result = ISC_R_SUCCESS;
|
||||
} else {
|
||||
/*
|
||||
* Something bad happened.
|
||||
@@ -1358,7 +1366,7 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
if (sigrdataset != NULL &&
|
||||
dns_rdataset_isassociated(&zrdataset))
|
||||
dns_rdataset_clone(&zsigrdataset, sigrdataset);
|
||||
} else if (try_hints && use_hints && view->hints != NULL) {
|
||||
} else if (try_hints) {
|
||||
/*
|
||||
* We've found nothing so far, but we have hints.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -19576,7 +19576,8 @@ keydone(isc_task_t *task, isc_event_t *event) {
|
||||
commit = true;
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
|
||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|
|
||||
DNS_ZONEFLG_NEEDNOTIFY);
|
||||
zone_needdump(zone, 30);
|
||||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
|
||||
@@ -1215,15 +1215,15 @@ verify_nsec3_chains(const vctx_t *vctx, isc_mem_t *mctx) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (first == NULL || newchain(first, e)) {
|
||||
if (prev != NULL) {
|
||||
if (!checknext(vctx, prev, first)) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (prev != first) {
|
||||
free_element(mctx, prev);
|
||||
}
|
||||
}
|
||||
if (first != NULL) {
|
||||
if (prev != NULL) {
|
||||
if (!checknext(vctx, prev, first)) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (prev != first) {
|
||||
free_element(mctx, prev);
|
||||
}
|
||||
}
|
||||
free_element(mctx, first);
|
||||
}
|
||||
prev = first = e;
|
||||
|
||||
+260
-152
@@ -20,6 +20,7 @@
|
||||
#include <isc/httpd.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/task.h>
|
||||
@@ -33,9 +34,6 @@
|
||||
/*%
|
||||
* TODO:
|
||||
*
|
||||
* o Put in better checks to make certain things are passed in correctly.
|
||||
* This includes a magic number for externally-visible structures,
|
||||
* checking for NULL-ness before dereferencing, etc.
|
||||
* o Make the URL processing external functions which will fill-in a buffer
|
||||
* structure we provide, or return an error and we will render a generic
|
||||
* page and close the client.
|
||||
@@ -44,16 +42,6 @@
|
||||
#define MSHUTTINGDOWN(cm) ((cm->flags & ISC_HTTPDMGR_FLAGSHUTTINGDOWN) != 0)
|
||||
#define MSETSHUTTINGDOWN(cm) (cm->flags |= ISC_HTTPDMGR_FLAGSHUTTINGDOWN)
|
||||
|
||||
#ifdef DEBUG_HTTPD
|
||||
#define ENTER(x) do { fprintf(stderr, "ENTER %s\n", (x)); } while (0)
|
||||
#define EXIT(x) do { fprintf(stderr, "EXIT %s\n", (x)); } while (0)
|
||||
#define NOTICE(x) do { fprintf(stderr, "NOTICE %s\n", (x)); } while (0)
|
||||
#else
|
||||
#define ENTER(x) do { } while(0)
|
||||
#define EXIT(x) do { } while(0)
|
||||
#define NOTICE(x) do { } while(0)
|
||||
#endif
|
||||
|
||||
#define HTTP_RECVLEN 1024
|
||||
#define HTTP_SENDGROW 1024
|
||||
#define HTTP_SEND_MAXLEN 10240
|
||||
@@ -61,10 +49,19 @@
|
||||
#define HTTPD_CLOSE 0x0001 /* Got a Connection: close header */
|
||||
#define HTTPD_FOUNDHOST 0x0002 /* Got a Host: header */
|
||||
#define HTTPD_KEEPALIVE 0x0004 /* Got a Connection: Keep-Alive */
|
||||
#define HTTPD_ACCEPT_DEFLATE 0x0008
|
||||
#define HTTPD_ACCEPT_DEFLATE 0x0008
|
||||
|
||||
#define HTTPD_MAGIC ISC_MAGIC('H', 't', 'p', 'd')
|
||||
#define VALID_HTTPD(m) ISC_MAGIC_VALID(m, HTTPD_MAGIC)
|
||||
|
||||
#define HTTPDMGR_MAGIC ISC_MAGIC('H', 'p', 'd', 'm')
|
||||
#define VALID_HTTPDMGR(m) ISC_MAGIC_VALID(m, HTTPDMGR_MAGIC)
|
||||
|
||||
|
||||
/*% http client */
|
||||
struct isc_httpd {
|
||||
unsigned int magic; /* HTTPD_MAGIC */
|
||||
isc_refcount_t references;
|
||||
isc_httpdmgr_t *mgr; /*%< our parent */
|
||||
ISC_LINK(isc_httpd_t) link;
|
||||
unsigned int state;
|
||||
@@ -96,8 +93,8 @@ struct isc_httpd {
|
||||
* to the client.
|
||||
*
|
||||
* The bufflist is the list of buffers we are currently transmitting.
|
||||
* The headerbuffer is where we render our headers to. If we run out of
|
||||
* space when rendering a header, we will change the size of our
|
||||
* The headerbuffer is where we render our headers to. If we run out
|
||||
* of space when rendering a header, we will change the size of our
|
||||
* buffer. We will not free it until we are finished, and will
|
||||
* allocate an additional HTTP_SENDGROW bytes per header space grow.
|
||||
*
|
||||
@@ -126,6 +123,8 @@ struct isc_httpd {
|
||||
|
||||
/*% lightweight socket manager for httpd output */
|
||||
struct isc_httpdmgr {
|
||||
unsigned int magic; /* HTTPDMGR_MAGIC */
|
||||
isc_refcount_t references;
|
||||
isc_mem_t *mctx;
|
||||
isc_socket_t *sock; /*%< listening socket */
|
||||
isc_task_t *task; /*%< owning task */
|
||||
@@ -203,48 +202,122 @@ struct isc_httpdmgr {
|
||||
static void isc_httpd_accept(isc_task_t *, isc_event_t *);
|
||||
static void isc_httpd_recvdone(isc_task_t *, isc_event_t *);
|
||||
static void isc_httpd_senddone(isc_task_t *, isc_event_t *);
|
||||
static void destroy_client(isc_httpd_t **);
|
||||
static isc_result_t process_request(isc_httpd_t *, int);
|
||||
static void httpdmgr_destroy(isc_httpdmgr_t *);
|
||||
static isc_result_t grow_headerspace(isc_httpd_t *);
|
||||
static void reset_client(isc_httpd_t *httpd);
|
||||
|
||||
static isc_httpdaction_t render_404;
|
||||
static isc_httpdaction_t render_500;
|
||||
|
||||
#if ENABLE_AFL
|
||||
static void (*finishhook)(void) = NULL;
|
||||
#endif /* ENABLE_AFL */
|
||||
|
||||
static void maybe_destroy_httpd(isc_httpd_t *);
|
||||
static void destroy_httpd(isc_httpd_t *);
|
||||
static void maybe_destroy_httpdmgr(isc_httpdmgr_t *);
|
||||
static void destroy_httpdmgr(isc_httpdmgr_t *);
|
||||
|
||||
static void
|
||||
destroy_client(isc_httpd_t **httpdp) {
|
||||
isc_httpd_t *httpd = *httpdp;
|
||||
isc_httpdmgr_t *httpdmgr = httpd->mgr;
|
||||
isc_httpdmgr_attach(isc_httpdmgr_t *, isc_httpdmgr_t **);
|
||||
static void
|
||||
isc_httpdmgr_detach(isc_httpdmgr_t **);
|
||||
|
||||
static void
|
||||
maybe_destroy_httpd(isc_httpd_t *httpd) {
|
||||
if (isc_refcount_decrement(&httpd->references) == 1) {
|
||||
destroy_httpd(httpd);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_buffer(isc_mem_t *mctx, isc_buffer_t *buffer) {
|
||||
isc_region_t r;
|
||||
|
||||
*httpdp = NULL;
|
||||
isc_buffer_region(buffer, &r);
|
||||
if (r.length > 0) {
|
||||
isc_mem_put(mctx, r.base, r.length);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_httpd(isc_httpd_t *httpd) {
|
||||
isc_httpdmgr_t *httpdmgr;
|
||||
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
httpdmgr = httpd->mgr;
|
||||
REQUIRE(VALID_HTTPDMGR(httpdmgr));
|
||||
|
||||
/*
|
||||
* Unlink before calling isc_socket_detach so
|
||||
* isc_httpdmgr_shutdown does not dereference a NULL pointer
|
||||
* when calling isc_socket_cancel().
|
||||
*/
|
||||
LOCK(&httpdmgr->lock);
|
||||
|
||||
isc_socket_detach(&httpd->sock);
|
||||
ISC_LIST_UNLINK(httpdmgr->running, httpd, link);
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
||||
isc_buffer_region(&httpd->headerbuffer, &r);
|
||||
if (r.length > 0) {
|
||||
isc_mem_put(httpdmgr->mctx, r.base, r.length);
|
||||
}
|
||||
httpd->magic = 0;
|
||||
isc_refcount_destroy(&httpd->references);
|
||||
isc_socket_detach(&httpd->sock);
|
||||
|
||||
isc_buffer_region(&httpd->compbuffer, &r);
|
||||
if (r.length > 0) {
|
||||
isc_mem_put(httpdmgr->mctx, r.base, r.length);
|
||||
}
|
||||
|
||||
free_buffer(httpdmgr->mctx, &httpd->headerbuffer);
|
||||
free_buffer(httpdmgr->mctx, &httpd->compbuffer);
|
||||
|
||||
isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t));
|
||||
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
||||
if (finishhook != NULL)
|
||||
#if ENABLE_AFL
|
||||
if (finishhook != NULL) {
|
||||
finishhook();
|
||||
}
|
||||
#endif /* ENABLE_AFL */
|
||||
|
||||
httpdmgr_destroy(httpdmgr);
|
||||
isc_httpdmgr_detach(&httpdmgr);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
httpdmgr_socket_accept(isc_task_t *task, isc_httpdmgr_t* httpdmgr)
|
||||
{
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
/* decremented in isc_httpd_accept */
|
||||
isc_refcount_increment(&httpdmgr->references);
|
||||
result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept,
|
||||
httpdmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(isc_refcount_decrement(&httpdmgr->references) > 1);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
static inline void
|
||||
httpd_socket_recv(isc_httpd_t *httpd, isc_region_t *region, isc_task_t *task)
|
||||
{
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
/* decremented in isc_httpd_recvdone */
|
||||
(void)isc_refcount_increment(&httpd->references);
|
||||
result = isc_socket_recv(httpd->sock, region, 1, task,
|
||||
isc_httpd_recvdone, httpd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(isc_refcount_decrement(&httpd->references) > 1);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
httpd_socket_send(isc_httpd_t *httpd, isc_region_t *region, isc_task_t *task)
|
||||
{
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
/* decremented in isc_httpd_senddone */
|
||||
(void)isc_refcount_increment(&httpd->references);
|
||||
result = isc_socket_send(httpd->sock, region, task,
|
||||
isc_httpd_senddone, httpd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(isc_refcount_decrement(&httpd->references) > 1);
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -264,22 +337,25 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
|
||||
httpdmgr = isc_mem_get(mctx, sizeof(isc_httpdmgr_t));
|
||||
|
||||
*httpdmgr = (isc_httpdmgr_t){
|
||||
.timermgr = tmgr, /* XXXMLG no attach function? */
|
||||
.client_ok = client_ok,
|
||||
.ondestroy = ondestroy,
|
||||
.cb_arg = cb_arg,
|
||||
.render_404 = render_404,
|
||||
.render_500 = render_500
|
||||
};
|
||||
|
||||
isc_mutex_init(&httpdmgr->lock);
|
||||
httpdmgr->mctx = NULL;
|
||||
isc_mem_attach(mctx, &httpdmgr->mctx);
|
||||
httpdmgr->sock = NULL;
|
||||
isc_socket_attach(sock, &httpdmgr->sock);
|
||||
httpdmgr->task = NULL;
|
||||
isc_task_attach(task, &httpdmgr->task);
|
||||
httpdmgr->timermgr = tmgr; /* XXXMLG no attach function? */
|
||||
httpdmgr->client_ok = client_ok;
|
||||
httpdmgr->ondestroy = ondestroy;
|
||||
httpdmgr->cb_arg = cb_arg;
|
||||
httpdmgr->flags = 0;
|
||||
|
||||
ISC_LIST_INIT(httpdmgr->running);
|
||||
ISC_LIST_INIT(httpdmgr->urls);
|
||||
|
||||
isc_refcount_init(&httpdmgr->references, 1);
|
||||
|
||||
/* XXXMLG ignore errors on isc_socket_listen() */
|
||||
result = isc_socket_listen(sock, SOMAXCONN);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@@ -291,17 +367,21 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
|
||||
(void)isc_socket_filter(sock, "httpready");
|
||||
|
||||
result = isc_socket_accept(sock, task, isc_httpd_accept, httpdmgr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
httpdmgr->magic = HTTPDMGR_MAGIC;
|
||||
|
||||
httpdmgr->render_404 = render_404;
|
||||
httpdmgr->render_500 = render_500;
|
||||
|
||||
result = httpdmgr_socket_accept(task, httpdmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*httpdmgrp = httpdmgr;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
httpdmgr->magic = 0;
|
||||
isc_refcount_decrement(&httpdmgr->references);
|
||||
isc_refcount_destroy(&httpdmgr->references);
|
||||
isc_task_detach(&httpdmgr->task);
|
||||
isc_socket_detach(&httpdmgr->sock);
|
||||
isc_mem_detach(&httpdmgr->mctx);
|
||||
@@ -311,30 +391,43 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
|
||||
}
|
||||
|
||||
static void
|
||||
httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) {
|
||||
isc_mem_t *mctx;
|
||||
isc_httpdmgr_attach(isc_httpdmgr_t *source, isc_httpdmgr_t **targetp) {
|
||||
REQUIRE(VALID_HTTPDMGR(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
static void
|
||||
isc_httpdmgr_detach(isc_httpdmgr_t **httpdmgrp) {
|
||||
REQUIRE(httpdmgrp != NULL && VALID_HTTPDMGR(*httpdmgrp));
|
||||
isc_httpdmgr_t *httpdmgr = *httpdmgrp;
|
||||
*httpdmgrp = NULL;
|
||||
|
||||
maybe_destroy_httpdmgr(httpdmgr);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_destroy_httpdmgr(isc_httpdmgr_t *httpdmgr) {
|
||||
if (isc_refcount_decrement(&httpdmgr->references) == 1) {
|
||||
destroy_httpdmgr(httpdmgr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_httpdmgr(isc_httpdmgr_t *httpdmgr) {
|
||||
isc_httpdurl_t *url;
|
||||
|
||||
ENTER("httpdmgr_destroy");
|
||||
isc_refcount_destroy(&httpdmgr->references);
|
||||
|
||||
LOCK(&httpdmgr->lock);
|
||||
|
||||
if (!MSHUTTINGDOWN(httpdmgr)) {
|
||||
NOTICE("httpdmgr_destroy not shutting down yet");
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
return;
|
||||
}
|
||||
httpdmgr->magic = 0;
|
||||
|
||||
/*
|
||||
* If all clients are not shut down, don't do anything yet.
|
||||
*/
|
||||
if (!ISC_LIST_EMPTY(httpdmgr->running)) {
|
||||
NOTICE("httpdmgr_destroy clients still active");
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
NOTICE("httpdmgr_destroy detaching socket, task, and timermgr");
|
||||
INSIST(MSHUTTINGDOWN(httpdmgr));
|
||||
INSIST(ISC_LIST_EMPTY(httpdmgr->running));
|
||||
|
||||
isc_socket_detach(&httpdmgr->sock);
|
||||
isc_task_detach(&httpdmgr->task);
|
||||
@@ -355,13 +448,10 @@ httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) {
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
isc_mutex_destroy(&httpdmgr->lock);
|
||||
|
||||
if (httpdmgr->ondestroy != NULL)
|
||||
if (httpdmgr->ondestroy != NULL) {
|
||||
(httpdmgr->ondestroy)(httpdmgr->cb_arg);
|
||||
|
||||
mctx = httpdmgr->mctx;
|
||||
isc_mem_putanddetach(&mctx, httpdmgr, sizeof(isc_httpdmgr_t));
|
||||
|
||||
EXIT("httpdmgr_destroy");
|
||||
}
|
||||
isc_mem_putanddetach(&httpdmgr->mctx, httpdmgr, sizeof(isc_httpdmgr_t));
|
||||
}
|
||||
|
||||
#define LENGTHOK(s) (httpd->recvbuf - (s) < (int)httpd->recvlen)
|
||||
@@ -440,8 +530,6 @@ process_request(isc_httpd_t *httpd, int length) {
|
||||
char *p;
|
||||
int delim;
|
||||
|
||||
ENTER("request");
|
||||
|
||||
httpd->recvlen += length;
|
||||
|
||||
httpd->recvbuf[httpd->recvlen] = 0;
|
||||
@@ -591,37 +679,70 @@ process_request(isc_httpd_t *httpd, int length) {
|
||||
&& ((httpd->flags & HTTPD_FOUNDHOST) == 0))
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
EXIT("request");
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
isc_httpd_accept(isc_task_t *task, isc_event_t *ev) {
|
||||
isc_result_t result;
|
||||
isc_httpdmgr_t *httpdmgr = ev->ev_arg;
|
||||
isc_httpd_create(isc_httpdmgr_t *httpdmgr, isc_socket_t *sock,
|
||||
isc_httpd_t **httpdp)
|
||||
{
|
||||
isc_httpd_t *httpd;
|
||||
char *headerdata;
|
||||
|
||||
REQUIRE(VALID_HTTPDMGR(httpdmgr));
|
||||
REQUIRE(httpdp != NULL && *httpdp == NULL);
|
||||
|
||||
httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t));
|
||||
|
||||
*httpd = (isc_httpd_t){
|
||||
.sock = sock
|
||||
};
|
||||
|
||||
isc_httpdmgr_attach(httpdmgr, &httpd->mgr);
|
||||
|
||||
isc_refcount_init(&httpd->references, 1);
|
||||
ISC_HTTPD_SETRECV(httpd);
|
||||
isc_socket_setname(httpd->sock, "httpd", NULL);
|
||||
|
||||
/*
|
||||
* Initialize the buffer for our headers.
|
||||
*/
|
||||
headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW);
|
||||
isc_buffer_init(&httpd->headerbuffer, headerdata, HTTP_SENDGROW);
|
||||
|
||||
isc_buffer_initnull(&httpd->compbuffer);
|
||||
isc_buffer_initnull(&httpd->bodybuffer);
|
||||
reset_client(httpd);
|
||||
|
||||
ISC_LINK_INIT(httpd, link);
|
||||
ISC_LIST_APPEND(httpdmgr->running, httpd, link);
|
||||
|
||||
httpd->magic = HTTPD_MAGIC;
|
||||
|
||||
*httpdp = httpd;
|
||||
}
|
||||
|
||||
static void
|
||||
isc_httpd_accept(isc_task_t *task, isc_event_t *ev) {
|
||||
isc_httpdmgr_t *httpdmgr = ev->ev_arg;
|
||||
isc_httpd_t *httpd = NULL;
|
||||
isc_region_t r;
|
||||
isc_socket_newconnev_t *nev = (isc_socket_newconnev_t *)ev;
|
||||
isc_sockaddr_t peeraddr;
|
||||
char *headerdata;
|
||||
|
||||
ENTER("accept");
|
||||
REQUIRE(VALID_HTTPDMGR(httpdmgr));
|
||||
|
||||
LOCK(&httpdmgr->lock);
|
||||
if (MSHUTTINGDOWN(httpdmgr)) {
|
||||
NOTICE("accept shutting down, goto out");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nev->result == ISC_R_CANCELED) {
|
||||
NOTICE("accept canceled, goto out");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nev->result != ISC_R_SUCCESS) {
|
||||
/* XXXMLG log failure */
|
||||
NOTICE("accept returned failure, goto requeue");
|
||||
goto requeue;
|
||||
}
|
||||
|
||||
@@ -632,51 +753,25 @@ isc_httpd_accept(isc_task_t *task, isc_event_t *ev) {
|
||||
goto requeue;
|
||||
}
|
||||
|
||||
httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t));
|
||||
|
||||
httpd->mgr = httpdmgr;
|
||||
ISC_LINK_INIT(httpd, link);
|
||||
ISC_LIST_APPEND(httpdmgr->running, httpd, link);
|
||||
ISC_HTTPD_SETRECV(httpd);
|
||||
httpd->sock = nev->newsocket;
|
||||
isc_socket_setname(httpd->sock, "httpd", NULL);
|
||||
httpd->flags = 0;
|
||||
|
||||
/*
|
||||
* Initialize the buffer for our headers.
|
||||
*/
|
||||
headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW);
|
||||
isc_buffer_init(&httpd->headerbuffer, headerdata, HTTP_SENDGROW);
|
||||
|
||||
isc_buffer_initnull(&httpd->compbuffer);
|
||||
isc_buffer_initnull(&httpd->bodybuffer);
|
||||
httpd->sendbuffer = NULL;
|
||||
reset_client(httpd);
|
||||
isc_httpd_create(httpdmgr, nev->newsocket, &httpd);
|
||||
|
||||
r.base = (unsigned char *)httpd->recvbuf;
|
||||
r.length = HTTP_RECVLEN - 1;
|
||||
result = isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone,
|
||||
httpd);
|
||||
/* FIXME!!! */
|
||||
POST(result);
|
||||
NOTICE("accept queued recv on socket");
|
||||
|
||||
httpd_socket_recv(httpd, &r, task);
|
||||
|
||||
requeue:
|
||||
result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept,
|
||||
httpdmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/* XXXMLG what to do? Log failure... */
|
||||
NOTICE("accept could not reaccept due to failure");
|
||||
}
|
||||
(void)httpdmgr_socket_accept(task, httpdmgr);
|
||||
|
||||
out:
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
||||
httpdmgr_destroy(httpdmgr);
|
||||
if (httpd != NULL) {
|
||||
maybe_destroy_httpd(httpd);
|
||||
}
|
||||
maybe_destroy_httpdmgr(httpdmgr);
|
||||
|
||||
isc_event_free(&ev);
|
||||
|
||||
EXIT("accept");
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -828,30 +923,25 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
bool is_compressed = false;
|
||||
char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
|
||||
|
||||
ENTER("recv");
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
INSIST(ISC_HTTPD_ISRECV(httpd));
|
||||
|
||||
if (sev->result != ISC_R_SUCCESS) {
|
||||
NOTICE("recv destroying client");
|
||||
destroy_client(&httpd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = process_request(httpd, sev->n);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
if (httpd->recvlen >= HTTP_RECVLEN - 1) {
|
||||
destroy_client(&httpd);
|
||||
goto out;
|
||||
}
|
||||
r.base = (unsigned char *)httpd->recvbuf + httpd->recvlen;
|
||||
r.length = HTTP_RECVLEN - httpd->recvlen - 1;
|
||||
/* check return code? */
|
||||
(void)isc_socket_recv(httpd->sock, &r, 1, task,
|
||||
isc_httpd_recvdone, httpd);
|
||||
|
||||
httpd_socket_recv(httpd, &r, task);
|
||||
goto out;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
destroy_client(&httpd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -864,13 +954,16 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
isc_buffer_initnull(&httpd->bodybuffer);
|
||||
isc_time_now(&now);
|
||||
isc_time_formathttptimestamp(&now, datebuf, sizeof(datebuf));
|
||||
LOCK(&httpd->mgr->lock);
|
||||
url = ISC_LIST_HEAD(httpd->mgr->urls);
|
||||
while (url != NULL) {
|
||||
if (strcmp(httpd->url, url->url) == 0)
|
||||
break;
|
||||
url = ISC_LIST_NEXT(url, link);
|
||||
}
|
||||
if (url == NULL)
|
||||
UNLOCK(&httpd->mgr->lock);
|
||||
|
||||
if (url == NULL) {
|
||||
result = httpd->mgr->render_404(httpd->url, NULL,
|
||||
httpd->querystring,
|
||||
NULL, NULL,
|
||||
@@ -880,7 +973,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
&httpd->bodybuffer,
|
||||
&httpd->freecb,
|
||||
&httpd->freecb_arg);
|
||||
else
|
||||
} else {
|
||||
result = url->action(httpd->url, url,
|
||||
httpd->querystring,
|
||||
httpd->headers,
|
||||
@@ -888,6 +981,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
&httpd->retcode, &httpd->retmsg,
|
||||
&httpd->mimetype, &httpd->bodybuffer,
|
||||
&httpd->freecb, &httpd->freecb_arg);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
result = httpd->mgr->render_500(httpd->url, url,
|
||||
httpd->querystring,
|
||||
@@ -911,8 +1005,9 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
#endif
|
||||
|
||||
isc_httpd_response(httpd);
|
||||
if ((httpd->flags & HTTPD_KEEPALIVE) != 0)
|
||||
if ((httpd->flags & HTTPD_KEEPALIVE) != 0) {
|
||||
isc_httpd_addheader(httpd, "Connection", "Keep-Alive");
|
||||
}
|
||||
isc_httpd_addheader(httpd, "Content-Type", httpd->mimetype);
|
||||
isc_httpd_addheader(httpd, "Date", datebuf);
|
||||
isc_httpd_addheader(httpd, "Expires", datebuf);
|
||||
@@ -934,7 +1029,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
if (is_compressed == true) {
|
||||
isc_httpd_addheader(httpd, "Content-Encoding", "deflate");
|
||||
isc_httpd_addheaderuint(httpd, "Content-Length",
|
||||
isc_buffer_usedlength(&httpd->compbuffer));
|
||||
isc_buffer_usedlength(&httpd->compbuffer));
|
||||
} else {
|
||||
isc_httpd_addheaderuint(httpd, "Content-Length",
|
||||
isc_buffer_usedlength(&httpd->bodybuffer));
|
||||
@@ -958,23 +1053,22 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
|
||||
*/
|
||||
isc_buffer_usedregion(httpd->sendbuffer, &r);
|
||||
|
||||
/* check return code? */
|
||||
(void)isc_socket_send(httpd->sock, &r, task,
|
||||
isc_httpd_senddone, httpd);
|
||||
httpd_socket_send(httpd, &r, task);
|
||||
|
||||
out:
|
||||
maybe_destroy_httpd(httpd);
|
||||
isc_event_free(&ev);
|
||||
EXIT("recv");
|
||||
}
|
||||
|
||||
void
|
||||
isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdmgrp) {
|
||||
isc_httpdmgr_t *httpdmgr;
|
||||
isc_httpd_t *httpd;
|
||||
|
||||
REQUIRE(httpdmgrp != NULL);
|
||||
httpdmgr = *httpdmgrp;
|
||||
*httpdmgrp = NULL;
|
||||
|
||||
ENTER("isc_httpdmgr_shutdown");
|
||||
REQUIRE(VALID_HTTPDMGR(httpdmgr));
|
||||
|
||||
LOCK(&httpdmgr->lock);
|
||||
|
||||
@@ -991,7 +1085,8 @@ isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdmgrp) {
|
||||
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
||||
EXIT("isc_httpdmgr_shutdown");
|
||||
maybe_destroy_httpdmgr(httpdmgr);
|
||||
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -1019,6 +1114,8 @@ isc_httpd_response(isc_httpd_t *httpd) {
|
||||
isc_result_t result;
|
||||
unsigned int needlen;
|
||||
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
needlen = strlen(httpd->protocol) + 1; /* protocol + space */
|
||||
needlen += 3 + 1; /* room for response code, always 3 bytes */
|
||||
needlen += strlen(httpd->retmsg) + 2; /* return msg + CRLF */
|
||||
@@ -1035,15 +1132,16 @@ isc_httpd_response(isc_httpd_t *httpd) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_httpd_addheader(isc_httpd_t *httpd, const char *name,
|
||||
const char *val)
|
||||
{
|
||||
isc_httpd_addheader(isc_httpd_t *httpd, const char *name, const char *val) {
|
||||
isc_result_t result;
|
||||
unsigned int needlen;
|
||||
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
needlen = strlen(name); /* name itself */
|
||||
if (val != NULL)
|
||||
if (val != NULL) {
|
||||
needlen += 2 + strlen(val); /* :<space> and val */
|
||||
}
|
||||
needlen += 2; /* CRLF */
|
||||
|
||||
while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) {
|
||||
@@ -1065,6 +1163,8 @@ isc_result_t
|
||||
isc_httpd_endheaders(isc_httpd_t *httpd) {
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
while (isc_buffer_availablelength(&httpd->headerbuffer) < 2) {
|
||||
result = grow_headerspace(httpd);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -1080,6 +1180,8 @@ isc_httpd_addheaderuint(isc_httpd_t *httpd, const char *name, int val) {
|
||||
unsigned int needlen;
|
||||
char buf[sizeof "18446744073709551616"];
|
||||
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d", val);
|
||||
|
||||
needlen = strlen(name); /* name itself */
|
||||
@@ -1102,7 +1204,8 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) {
|
||||
isc_region_t r;
|
||||
isc_socketevent_t *sev = (isc_socketevent_t *)ev;
|
||||
|
||||
ENTER("senddone");
|
||||
REQUIRE(VALID_HTTPD(httpd));
|
||||
|
||||
INSIST(ISC_HTTPD_ISSEND(httpd));
|
||||
|
||||
isc_buffer_free(&httpd->sendbuffer);
|
||||
@@ -1120,34 +1223,28 @@ isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) {
|
||||
b = &httpd->bodybuffer;
|
||||
httpd->freecb(b, httpd->freecb_arg);
|
||||
}
|
||||
NOTICE("senddone free callback performed");
|
||||
}
|
||||
|
||||
if (sev->result != ISC_R_SUCCESS) {
|
||||
destroy_client(&httpd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((httpd->flags & HTTPD_CLOSE) != 0) {
|
||||
destroy_client(&httpd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ISC_HTTPD_SETRECV(httpd);
|
||||
|
||||
NOTICE("senddone restarting recv on socket");
|
||||
|
||||
reset_client(httpd);
|
||||
|
||||
r.base = (unsigned char *)httpd->recvbuf;
|
||||
r.length = HTTP_RECVLEN - 1;
|
||||
/* check return code? */
|
||||
(void)isc_socket_recv(httpd->sock, &r, 1, task,
|
||||
isc_httpd_recvdone, httpd);
|
||||
|
||||
httpd_socket_recv(httpd, &r, task);
|
||||
|
||||
out:
|
||||
maybe_destroy_httpd(httpd);
|
||||
isc_event_free(&ev);
|
||||
EXIT("senddone");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1178,6 +1275,8 @@ isc_result_t
|
||||
isc_httpdmgr_addurl(isc_httpdmgr_t *httpdmgr, const char *url,
|
||||
isc_httpdaction_t *func, void *arg)
|
||||
{
|
||||
/* REQUIRE(VALID_HTTPDMGR(httpdmgr)); Dummy function */
|
||||
|
||||
return (isc_httpdmgr_addurl2(httpdmgr, url, false, func, arg));
|
||||
}
|
||||
|
||||
@@ -1188,6 +1287,8 @@ isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url,
|
||||
{
|
||||
isc_httpdurl_t *item;
|
||||
|
||||
REQUIRE(VALID_HTTPDMGR(httpdmgr));
|
||||
|
||||
if (url == NULL) {
|
||||
httpdmgr->render_404 = func;
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -1203,7 +1304,10 @@ isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url,
|
||||
isc_time_now(&item->loadtime);
|
||||
|
||||
ISC_LINK_INIT(item, link);
|
||||
|
||||
LOCK(&httpdmgr->lock);
|
||||
ISC_LIST_APPEND(httpdmgr->urls, item, link);
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -1211,5 +1315,9 @@ isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url,
|
||||
void
|
||||
isc_httpd_setfinishhook(void (*fn)(void))
|
||||
{
|
||||
#if ENABLE_AFL
|
||||
finishhook = fn;
|
||||
#else /* ENABLE_AFL */
|
||||
UNUSED(fn);
|
||||
#endif /* ENABLE_AFL */
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ struct isc_httpdurl {
|
||||
char *url;
|
||||
isc_httpdaction_t *action;
|
||||
void *action_arg;
|
||||
bool isstatic;
|
||||
bool isstatic;
|
||||
isc_time_t loadtime;
|
||||
ISC_LINK(isc_httpdurl_t) link;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
/*%
|
||||
* Performance
|
||||
*/
|
||||
#ifdef CPPCHECK
|
||||
#define ISC_LIKELY(x) (x)
|
||||
#define ISC_UNLIKELY(x) (x)
|
||||
#else
|
||||
#ifdef HAVE_BUILTIN_EXPECT
|
||||
#define ISC_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define ISC_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
@@ -22,5 +26,6 @@
|
||||
#define ISC_LIKELY(x) (x)
|
||||
#define ISC_UNLIKELY(x) (x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* ISC_LIKELY_H */
|
||||
|
||||
@@ -285,12 +285,17 @@ extern void mock_assert(const int result, const char* const expression,
|
||||
#ifdef UNIT_TESTING
|
||||
|
||||
#define RUNTIME_CHECK(expression) \
|
||||
mock_assert((int)(expression), #expression, __FILE__, __LINE__)
|
||||
((!(expression)) ? \
|
||||
(mock_assert(0, #expression, __FILE__, __LINE__), abort()) : (void)0)
|
||||
|
||||
#else /* UNIT_TESTING */
|
||||
|
||||
#ifndef CPPCHECK
|
||||
/*% Runtime Check */
|
||||
#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond)
|
||||
#else
|
||||
#define RUNTIME_CHECK(e) if (!(e)) abort()
|
||||
#endif
|
||||
|
||||
#endif /* UNIT_TESTING */
|
||||
|
||||
|
||||
@@ -603,6 +603,13 @@ isc__nmsocket_prep_destroy(isc_nmsocket_t *sock);
|
||||
* if there are no remaining references or active handles.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc__nmsocket_active(isc_nmsocket_t *sock);
|
||||
/*%<
|
||||
* Determine whether 'sock' is active by checking 'sock->active'
|
||||
* or, for child sockets, 'sock->parent->active'.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
/*%<
|
||||
|
||||
@@ -681,7 +681,7 @@ isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event) {
|
||||
uv_async_send(&worker->async);
|
||||
}
|
||||
|
||||
static bool
|
||||
bool
|
||||
isc__nmsocket_active(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
if (sock->parent != NULL) {
|
||||
@@ -1158,7 +1158,7 @@ nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
|
||||
|
||||
void
|
||||
isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_nmsocket_t *sock = NULL, *tmp = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
||||
@@ -1199,8 +1199,14 @@ isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporarily reference the socket to ensure that it can't
|
||||
* be deleted by another thread while we're deactivating the
|
||||
* handle.
|
||||
*/
|
||||
isc_nmsocket_attach(sock, &tmp);
|
||||
nmhandle_deactivate(sock, handle);
|
||||
nmsocket_maybe_destroy(sock);
|
||||
isc_nmsocket_detach(&tmp);
|
||||
}
|
||||
|
||||
void *
|
||||
|
||||
@@ -419,7 +419,7 @@ stoplistening(isc_nmsocket_t *sock) {
|
||||
event = isc__nm_get_ievent(sock->mgr, netievent_tcpchildstop);
|
||||
isc_nmsocket_attach(&sock->children[i], &event->sock);
|
||||
|
||||
if (i == sock->tid) {
|
||||
if (isc_nm_tid() == sock->children[i].tid) {
|
||||
isc__nm_async_tcpchildstop(&sock->mgr->workers[i],
|
||||
(isc__netievent_t *) event);
|
||||
isc__nm_put_ievent(sock->mgr, event);
|
||||
|
||||
@@ -470,8 +470,7 @@ isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
|
||||
if (sock->outer == NULL) {
|
||||
/* The socket is closed, just issue the callback */
|
||||
cb(handle, ISC_R_FAILURE, cbarg);
|
||||
/* The socket is closed */
|
||||
return (ISC_R_NOTCONNECTED);
|
||||
}
|
||||
|
||||
|
||||
+24
-8
@@ -122,6 +122,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->iface != NULL);
|
||||
REQUIRE(sock->parent != NULL);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
uv_udp_init(&worker->loop, &sock->uv_handle.udp);
|
||||
uv_handle_set_data(&sock->uv_handle.handle, NULL);
|
||||
@@ -164,7 +165,8 @@ udp_close_cb(uv_handle_t *handle) {
|
||||
|
||||
static void
|
||||
stop_udp_child(isc_nmsocket_t *sock) {
|
||||
INSIST(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
uv_udp_recv_stop(&sock->uv_handle.udp);
|
||||
uv_close((uv_handle_t *) &sock->uv_handle.udp, udp_close_cb);
|
||||
@@ -179,19 +181,25 @@ stop_udp_child(isc_nmsocket_t *sock) {
|
||||
|
||||
static void
|
||||
stoplistening(isc_nmsocket_t *sock) {
|
||||
REQUIRE(sock->type == isc_nm_udplistener);
|
||||
|
||||
/*
|
||||
* Socket is already closing; there's nothing to do.
|
||||
*/
|
||||
if (uv_is_closing((uv_handle_t *) &sock->uv_handle.udp)) {
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
INSIST(sock->type == isc_nm_udplistener);
|
||||
/*
|
||||
* Mark it inactive now so that all sends will be ignored
|
||||
* and we won't try to stop listening again.
|
||||
*/
|
||||
atomic_store(&sock->active, false);
|
||||
|
||||
for (int i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_udpstop_t *event = NULL;
|
||||
|
||||
if (i == sock->tid) {
|
||||
if (isc_nm_tid() == sock->children[i].tid) {
|
||||
stop_udp_child(&sock->children[i]);
|
||||
continue;
|
||||
}
|
||||
@@ -358,7 +366,11 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
|
||||
/*
|
||||
* Simulate a firewall blocking UDP packets bigger than
|
||||
* 'maxudp' bytes.
|
||||
* 'maxudp' bytes, for testing purposes.
|
||||
*
|
||||
* The client would ordinarily have unreferenced the handle
|
||||
* in the callback, but that won't happen in this case, so
|
||||
* we need to do so here.
|
||||
*/
|
||||
if (maxudp != 0 && region->length > maxudp) {
|
||||
isc_nmhandle_unref(handle);
|
||||
@@ -371,8 +383,12 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
} else if (sock->type == isc_nm_udplistener) {
|
||||
psock = sock;
|
||||
} else {
|
||||
isc_nmhandle_unref(handle);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
@@ -425,7 +441,7 @@ isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
||||
REQUIRE(worker->id == ievent->sock->tid);
|
||||
|
||||
if (atomic_load(&ievent->sock->active)) {
|
||||
if (isc__nmsocket_active(ievent->sock)) {
|
||||
udp_send_direct(ievent->sock, ievent->req, &ievent->peer);
|
||||
} else {
|
||||
ievent->req->cb.send(ievent->req->handle,
|
||||
|
||||
@@ -103,10 +103,10 @@ void isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_destroy(mp) \
|
||||
(RUNTIME_CHECK(pthread_mutex_destroy((&(mp)->mutex)) == 0))
|
||||
RUNTIME_CHECK(pthread_mutex_destroy((&(mp)->mutex)) == 0)
|
||||
#else
|
||||
#define isc_mutex_destroy(mp) \
|
||||
(RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0))
|
||||
RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)
|
||||
#endif
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
|
||||
+31
-11
@@ -78,13 +78,17 @@
|
||||
***/
|
||||
|
||||
typedef enum {
|
||||
task_state_idle, task_state_ready, task_state_paused,
|
||||
task_state_running, task_state_done
|
||||
task_state_idle, /* not doing anything, events queue empty */
|
||||
task_state_ready, /* waiting in worker's queue */
|
||||
task_state_paused, /* not running, paused */
|
||||
task_state_pausing, /* running, waiting to be paused */
|
||||
task_state_running, /* actively processing events */
|
||||
task_state_done /* shutting down, no events or references */
|
||||
} task_state_t;
|
||||
|
||||
#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
|
||||
static const char *statenames[] = {
|
||||
"idle", "ready", "running", "done",
|
||||
"idle", "ready", "paused", "pausing", "running", "done",
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -381,6 +385,7 @@ task_shutdown(isc__task_t *task) {
|
||||
}
|
||||
INSIST(task->state == task_state_ready ||
|
||||
task->state == task_state_paused ||
|
||||
task->state == task_state_pausing ||
|
||||
task->state == task_state_running);
|
||||
|
||||
/*
|
||||
@@ -502,7 +507,8 @@ task_send(isc__task_t *task, isc_event_t **eventp, int c) {
|
||||
}
|
||||
INSIST(task->state == task_state_ready ||
|
||||
task->state == task_state_running ||
|
||||
task->state == task_state_paused);
|
||||
task->state == task_state_paused ||
|
||||
task->state == task_state_pausing);
|
||||
ENQUEUE(task->events, event, ev_link);
|
||||
task->nevents++;
|
||||
*eventp = NULL;
|
||||
@@ -1200,10 +1206,12 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
finished = true;
|
||||
task->state = task_state_done;
|
||||
} else {
|
||||
/* It might be paused */
|
||||
if (task->state ==
|
||||
task_state_running) {
|
||||
task->state = task_state_idle;
|
||||
} else if (task->state ==
|
||||
task_state_pausing) {
|
||||
task->state = task_state_paused;
|
||||
}
|
||||
}
|
||||
done = true;
|
||||
@@ -1226,6 +1234,9 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
*/
|
||||
task->state = task_state_ready;
|
||||
requeue = true;
|
||||
} else if (task->state ==
|
||||
task_state_pausing) {
|
||||
task->state = task_state_paused;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
@@ -1682,8 +1693,12 @@ isc_task_pause(isc_task_t *task0) {
|
||||
INSIST(task->state == task_state_idle ||
|
||||
task->state == task_state_ready ||
|
||||
task->state == task_state_running);
|
||||
running = (task->state == task_state_running);
|
||||
task->state = task_state_paused;
|
||||
if (task->state == task_state_running) {
|
||||
running = true;
|
||||
task->state = task_state_pausing;
|
||||
} else {
|
||||
task->state = task_state_paused;
|
||||
}
|
||||
UNLOCK(&task->lock);
|
||||
|
||||
if (running) {
|
||||
@@ -1706,13 +1721,18 @@ isc_task_unpause(isc_task_t *task0) {
|
||||
REQUIRE(ISCAPI_TASK_VALID(task0));
|
||||
|
||||
LOCK(&task->lock);
|
||||
INSIST(task->state == task_state_paused);
|
||||
if (!EMPTY(task->events)) {
|
||||
task->state = task_state_ready;
|
||||
was_idle = true;
|
||||
INSIST(task->state == task_state_paused ||
|
||||
task->state == task_state_pausing);
|
||||
/* If the task was pausing we can't reschedule it */
|
||||
if (task->state == task_state_pausing) {
|
||||
task->state = task_state_running;
|
||||
} else {
|
||||
task->state = task_state_idle;
|
||||
}
|
||||
if (task->state == task_state_idle && !EMPTY(task->events)) {
|
||||
task->state = task_state_ready;
|
||||
was_idle = true;
|
||||
}
|
||||
UNLOCK(&task->lock);
|
||||
|
||||
if (was_idle) {
|
||||
|
||||
@@ -48,7 +48,7 @@ static isc_condition_t cv;
|
||||
|
||||
atomic_int_fast32_t counter;
|
||||
static int active[10];
|
||||
static atomic_bool done;
|
||||
static atomic_bool done, done2;
|
||||
|
||||
static int
|
||||
_setup(void **state) {
|
||||
@@ -429,6 +429,83 @@ privilege_drop(void **state) {
|
||||
assert_null(task2);
|
||||
}
|
||||
|
||||
static void
|
||||
sleep_cb(isc_task_t *task, isc_event_t *event) {
|
||||
UNUSED(task);
|
||||
int p = *(int*)event->ev_arg;
|
||||
if (p == 1) {
|
||||
/*
|
||||
* Signal the main thread that we're running, so that
|
||||
* it can trigger the race.
|
||||
*/
|
||||
LOCK(&lock);
|
||||
atomic_store(&done2, true);
|
||||
SIGNAL(&cv);
|
||||
UNLOCK(&lock);
|
||||
/*
|
||||
* Wait for the operations in the main thread to be finished.
|
||||
*/
|
||||
LOCK(&lock);
|
||||
while (!atomic_load(&done)) {
|
||||
WAIT(&cv, &lock);
|
||||
}
|
||||
UNLOCK(&lock);
|
||||
} else {
|
||||
/*
|
||||
* Wait for the operations in the main thread to be finished.
|
||||
*/
|
||||
LOCK(&lock);
|
||||
atomic_store(&done2, true);
|
||||
SIGNAL(&cv);
|
||||
UNLOCK(&lock);
|
||||
}
|
||||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
static void
|
||||
pause_unpause(void **state) {
|
||||
isc_result_t result;
|
||||
isc_task_t *task = NULL;
|
||||
isc_event_t *event1,*event2 = NULL;
|
||||
UNUSED(state);
|
||||
atomic_store(&done, false);
|
||||
atomic_store(&done2, false);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
event1 = isc_event_allocate(test_mctx, task, ISC_TASKEVENT_TEST,
|
||||
sleep_cb, &(int){1}, sizeof (isc_event_t));
|
||||
assert_non_null(event1);
|
||||
event2 = isc_event_allocate(test_mctx, task, ISC_TASKEVENT_TEST,
|
||||
sleep_cb, &(int){2}, sizeof (isc_event_t));
|
||||
assert_non_null(event2);
|
||||
isc_task_send(task, &event1);
|
||||
isc_task_send(task, &event2);
|
||||
/* Wait for event1 to be running */
|
||||
LOCK(&lock);
|
||||
while (!atomic_load(&done2)) {
|
||||
WAIT(&cv, &lock);
|
||||
}
|
||||
UNLOCK(&lock);
|
||||
/* Pause-unpause-detach is what causes the race */
|
||||
isc_task_pause(task);
|
||||
isc_task_unpause(task);
|
||||
isc_task_detach(&task);
|
||||
/* Signal event1 to finish */
|
||||
LOCK(&lock);
|
||||
atomic_store(&done2, false);
|
||||
atomic_store(&done, true);
|
||||
SIGNAL(&cv);
|
||||
UNLOCK(&lock);
|
||||
/* Wait for event2 to finish */
|
||||
LOCK(&lock);
|
||||
while (!atomic_load(&done2)) {
|
||||
WAIT(&cv, &lock);
|
||||
}
|
||||
UNLOCK(&lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic task functions:
|
||||
*/
|
||||
@@ -1482,6 +1559,7 @@ main(int argc, char **argv) {
|
||||
cmocka_unit_test_setup_teardown(purgeevent, _setup2, _teardown),
|
||||
cmocka_unit_test_setup_teardown(purgeevent_notpurge,
|
||||
_setup, _teardown),
|
||||
cmocka_unit_test_setup_teardown(pause_unpause, _setup, _teardown),
|
||||
};
|
||||
int c;
|
||||
|
||||
|
||||
+19
-13
@@ -239,7 +239,7 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
|
||||
isc_task_t *task, isc_taskaction_t action, void *arg,
|
||||
isc_timer_t **timerp)
|
||||
{
|
||||
isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
|
||||
isc__timermgr_t *manager;
|
||||
isc__timer_t *timer;
|
||||
isc_result_t result;
|
||||
isc_time_t now;
|
||||
@@ -252,7 +252,8 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
|
||||
* in 'timerp'.
|
||||
*/
|
||||
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
REQUIRE(VALID_MANAGER(manager0));
|
||||
manager = (isc__timermgr_t *)manager0;
|
||||
REQUIRE(task != NULL);
|
||||
REQUIRE(action != NULL);
|
||||
if (expires == NULL)
|
||||
@@ -352,7 +353,7 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type,
|
||||
const isc_time_t *expires, const isc_interval_t *interval,
|
||||
bool purge)
|
||||
{
|
||||
isc__timer_t *timer = (isc__timer_t *)timer0;
|
||||
isc__timer_t *timer;
|
||||
isc_time_t now;
|
||||
isc__timermgr_t *manager;
|
||||
isc_result_t result;
|
||||
@@ -363,7 +364,8 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type,
|
||||
* are purged from its task's event queue.
|
||||
*/
|
||||
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
REQUIRE(VALID_TIMER(timer0));
|
||||
timer = (isc__timer_t *)timer0;
|
||||
manager = timer->manager;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
@@ -425,10 +427,11 @@ isc_timer_reset(isc_timer_t *timer0, isc_timertype_t type,
|
||||
|
||||
isc_timertype_t
|
||||
isc_timer_gettype(isc_timer_t *timer0) {
|
||||
isc__timer_t *timer = (isc__timer_t *)timer0;
|
||||
isc__timer_t *timer;
|
||||
isc_timertype_t t;
|
||||
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
REQUIRE(VALID_TIMER(timer0));
|
||||
timer = (isc__timer_t *)timer0;
|
||||
|
||||
LOCK(&timer->lock);
|
||||
t = timer->type;
|
||||
@@ -439,7 +442,7 @@ isc_timer_gettype(isc_timer_t *timer0) {
|
||||
|
||||
isc_result_t
|
||||
isc_timer_touch(isc_timer_t *timer0) {
|
||||
isc__timer_t *timer = (isc__timer_t *)timer0;
|
||||
isc__timer_t *timer;
|
||||
isc_result_t result;
|
||||
isc_time_t now;
|
||||
|
||||
@@ -447,7 +450,8 @@ isc_timer_touch(isc_timer_t *timer0) {
|
||||
* Set the last-touched time of 'timer' to the current time.
|
||||
*/
|
||||
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
REQUIRE(VALID_TIMER(timer0));
|
||||
timer = (isc__timer_t *)timer0;
|
||||
|
||||
LOCK(&timer->lock);
|
||||
|
||||
@@ -470,13 +474,14 @@ isc_timer_touch(isc_timer_t *timer0) {
|
||||
|
||||
void
|
||||
isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
|
||||
isc__timer_t *timer = (isc__timer_t *)timer0;
|
||||
isc__timer_t *timer;
|
||||
|
||||
/*
|
||||
* Attach *timerp to timer.
|
||||
*/
|
||||
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
REQUIRE(VALID_TIMER(timer0));
|
||||
timer = (isc__timer_t *)timer0;
|
||||
REQUIRE(timerp != NULL && *timerp == NULL);
|
||||
isc_refcount_increment(&timer->references);
|
||||
|
||||
@@ -661,8 +666,8 @@ static void
|
||||
set_index(void *what, unsigned int index) {
|
||||
isc__timer_t *timer;
|
||||
|
||||
REQUIRE(VALID_TIMER(what));
|
||||
timer = what;
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
|
||||
timer->index = index;
|
||||
}
|
||||
@@ -707,9 +712,10 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
||||
|
||||
void
|
||||
isc_timermgr_poke(isc_timermgr_t *manager0) {
|
||||
isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
|
||||
isc__timermgr_t *manager;
|
||||
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
REQUIRE(VALID_MANAGER(manager0));
|
||||
manager = (isc__timermgr_t *)manager0;
|
||||
|
||||
SIGNAL(&manager->wakeup);
|
||||
}
|
||||
|
||||
+21
-1
@@ -381,8 +381,9 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
|
||||
r.base[1] = client->message->id & 0xff;
|
||||
|
||||
result = client_sendpkg(client, &buffer);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
done:
|
||||
if (client->tcpbuf != NULL) {
|
||||
@@ -392,6 +393,7 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
|
||||
}
|
||||
|
||||
ns_client_drop(client, result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -596,6 +598,10 @@ ns_client_send(ns_client_t *client) {
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
result = client_sendpkg(client, &tcpbuffer);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/* We won't get a callback to clean it up */
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
switch (isc_sockaddr_pf(&client->peeraddr)) {
|
||||
case AF_INET:
|
||||
@@ -629,6 +635,10 @@ ns_client_send(ns_client_t *client) {
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
result = client_sendpkg(client, &buffer);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/* We won't get a callback to clean it up */
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
switch (isc_sockaddr_pf(&client->peeraddr)) {
|
||||
case AF_INET:
|
||||
@@ -2333,6 +2343,16 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
|
||||
isc_task_detach(&client->task);
|
||||
}
|
||||
|
||||
if (client->manager != NULL) {
|
||||
clientmgr_detach(&client->manager);
|
||||
}
|
||||
if (client->mctx != NULL) {
|
||||
isc_mem_detach(&client->mctx);
|
||||
}
|
||||
if (client->sctx != NULL) {
|
||||
ns_server_detach(&client->sctx);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@ struct ns_server {
|
||||
|
||||
/*% Test options and other configurables */
|
||||
uint32_t options;
|
||||
unsigned int delay;
|
||||
|
||||
dns_acl_t *blackholeacl;
|
||||
dns_acl_t *keepresporder;
|
||||
|
||||
+2
-4
@@ -1663,8 +1663,6 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
||||
xfrout_fail(xfr, result, "send");
|
||||
} else if (xfr->end_of_stream == false) {
|
||||
sendstream(xfr);
|
||||
/* Return now so we don't unref the handle */
|
||||
return;
|
||||
} else {
|
||||
/* End of zone transfer stream. */
|
||||
uint64_t msecs, persec;
|
||||
@@ -1690,9 +1688,9 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
||||
(unsigned int) persec);
|
||||
|
||||
xfrout_ctx_destroy(&xfr);
|
||||
/* We're done, unreference the handle */
|
||||
isc_nmhandle_unref(handle);
|
||||
}
|
||||
|
||||
isc_nmhandle_unref(handle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ export CMOCKA_MESSAGE_OUTPUT
|
||||
GDB="$(command -v gdb)"
|
||||
|
||||
kyua_report() {
|
||||
${KYUA} --logfile /dev/null report --results-file "${KYUA_RESULT:-LATEST}"
|
||||
${KYUA} --logfile /dev/null report --verbose --results-file "${KYUA_RESULT:-LATEST}"
|
||||
}
|
||||
|
||||
status=0
|
||||
@@ -36,7 +36,7 @@ then
|
||||
# Use kyua-debug(1) facility to gather additional data on failed tests.
|
||||
# Some runs will just show verbose information from the run, some will
|
||||
# show backtrace via gdb(1).
|
||||
broken_tests="$(kyua_report | awk '/Broken tests/ { flag=1; next } /Summary/ { flag=0 } flag' | awk '{ print $1 }')"
|
||||
broken_tests=$(kyua_report | awk '$2 == "->" && ( $3 == "broken:" || $3 == "failed:" ) { print $1 }')
|
||||
if [ -n "${CI}" ] && [ "$(id -u)" -eq 0 ] && [ -n "${broken_tests}" ] && [ -n "${GDB}" ]; then
|
||||
if grep '^#define USE_LIBTOOL 1$' "${TOP}/config.h" >/dev/null; then
|
||||
# kyua debug command misidentifies broken binary when libtool is used
|
||||
|
||||
+2
-1
@@ -868,11 +868,12 @@
|
||||
./bin/tests/system/pending/ns2/sign.sh SH 2009,2010,2012,2014,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/pending/setup.sh SH 2009,2012,2014,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/pending/tests.sh SH 2009,2010,2012,2015,2016,2018,2019,2020
|
||||
./bin/tests/system/pipelined/ans5/ans.py PYTHON 2020
|
||||
./bin/tests/system/pipelined/clean.sh SH 2014,2015,2016,2018,2019,2020
|
||||
./bin/tests/system/pipelined/input X 2014,2015,2018,2019,2020
|
||||
./bin/tests/system/pipelined/inputb X 2014,2015,2018,2019,2020
|
||||
./bin/tests/system/pipelined/ns3/named.args X 2014,2015,2018,2019,2020
|
||||
./bin/tests/system/pipelined/pipequeries.c C 2014,2015,2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/pipelined/prereq.sh SH 2020
|
||||
./bin/tests/system/pipelined/ref X 2014,2015,2018,2019,2020
|
||||
./bin/tests/system/pipelined/refb X 2014,2015,2018,2019,2020
|
||||
./bin/tests/system/pipelined/setup.sh SH 2014,2015,2016,2017,2018,2019,2020
|
||||
|
||||
Reference in New Issue
Block a user