diff options
Diffstat (limited to 'usr.sbin/unbound')
-rw-r--r-- | usr.sbin/unbound/testcode/fake_event.c | 21 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/replay.h | 3 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/streamtcp.1 | 6 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/streamtcp.c | 26 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/unitauth.c | 16 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/unitldns.c | 20 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/unitmain.c | 3 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/unitmsgparse.c | 23 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/unitverify.c | 51 | ||||
-rw-r--r-- | usr.sbin/unbound/util/edns.c | 83 | ||||
-rw-r--r-- | usr.sbin/unbound/util/edns.h | 62 | ||||
-rw-r--r-- | usr.sbin/unbound/util/rtt.c | 3 | ||||
-rw-r--r-- | usr.sbin/unbound/util/tcp_conn_limit.c | 194 | ||||
-rw-r--r-- | usr.sbin/unbound/util/tcp_conn_limit.h | 130 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_kcache.c | 2 |
15 files changed, 594 insertions, 49 deletions
diff --git a/usr.sbin/unbound/testcode/fake_event.c b/usr.sbin/unbound/testcode/fake_event.c index 80e3685c09e..777ed7355ed 100644 --- a/usr.sbin/unbound/testcode/fake_event.c +++ b/usr.sbin/unbound/testcode/fake_event.c @@ -374,8 +374,11 @@ answer_callback_from_entry(struct replay_runtime* runtime, c.fd = -1; c.buffer = sldns_buffer_new(runtime->bufsize); c.type = comm_udp; - if(pend->transport == transport_tcp) + if(pend->transport == transport_tcp) { c.type = comm_tcp; + c.tcp_timeout_msec = 30000; + c.tcp_keepalive = runtime->tcp_seen_keepalive; + } fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len, pend->tcp_pkt_counter); repinfo.c = &c; @@ -423,6 +426,8 @@ answer_check_it(struct replay_runtime* runtime) else runtime->answer_list = ans->next; if(!ans->next) runtime->answer_last = prev; + if(ans->repinfo.c->tcp_keepalive) + runtime->tcp_seen_keepalive = 1; delete_replay_answer(ans); return; } else { @@ -452,9 +457,12 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo) repinfo.c->fd = -1; repinfo.c->ev = (struct internal_event*)runtime; repinfo.c->buffer = sldns_buffer_new(runtime->bufsize); - if(todo->match->match_transport == transport_tcp) + if(todo->match->match_transport == transport_tcp) { repinfo.c->type = comm_tcp; - else repinfo.c->type = comm_udp; + repinfo.c->tcp_timeout_msec = 30000; + repinfo.c->tcp_keepalive = runtime->tcp_seen_keepalive; + } else + repinfo.c->type = comm_udp; fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0); log_info("testbound: incoming QUERY"); log_pkt("query pkt", todo->match->reply_list->reply_pkt, @@ -488,8 +496,11 @@ fake_pending_callback(struct replay_runtime* runtime, cb = p->callback; c.buffer = sldns_buffer_new(runtime->bufsize); c.type = comm_udp; - if(p->transport == transport_tcp) + if(p->transport == transport_tcp) { c.type = comm_tcp; + c.tcp_timeout_msec = 30000; + c.tcp_keepalive = runtime->tcp_seen_keepalive; + } if(todo->evt_type == repevt_back_reply && todo->match) { fill_buffer_with_reply(c.buffer, todo->match, p->pkt, p->pkt_len, p->tcp_pkt_counter); @@ -856,6 +867,8 @@ run_scenario(struct replay_runtime* runtime) struct listen_dnsport* listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports), size_t bufsize, int ATTR_UNUSED(tcp_accept_count), + int ATTR_UNUSED(tcp_idle_timeout), + struct tcl_list* ATTR_UNUSED(tcp_conn_limit), void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv), comm_point_callback_type* cb, void* cb_arg) { diff --git a/usr.sbin/unbound/testcode/replay.h b/usr.sbin/unbound/testcode/replay.h index 81f0a2c275b..0cce0b49010 100644 --- a/usr.sbin/unbound/testcode/replay.h +++ b/usr.sbin/unbound/testcode/replay.h @@ -303,6 +303,9 @@ struct replay_runtime { /** the current time in microseconds */ struct timeval now_tv; + /** has TCP connection seen a keepalive? */ + int tcp_seen_keepalive; + /** signal handler callback */ void (*sig_cb)(int, void*); /** signal handler user arg */ diff --git a/usr.sbin/unbound/testcode/streamtcp.1 b/usr.sbin/unbound/testcode/streamtcp.1 index 7c738d9d278..526c8e1699d 100644 --- a/usr.sbin/unbound/testcode/streamtcp.1 +++ b/usr.sbin/unbound/testcode/streamtcp.1 @@ -12,6 +12,8 @@ .RB [ \-unsh ] .RB [ \-f .IR ipaddr[@port] ] +.RB [ \-d +.IR secs ] .I name .I type .I class @@ -50,6 +52,10 @@ Print program usage. .TP .B \-f \fIipaddr[@port] Specify the server to send the queries to. If not specified localhost (127.0.0.1) is used. +.TP +.B \-d \fIsecs +Delay after the connection before sending query. This tests the timeout +on the other side, eg. if shorter the connection is closed. .SH "EXAMPLES" .LP Some examples of use. diff --git a/usr.sbin/unbound/testcode/streamtcp.c b/usr.sbin/unbound/testcode/streamtcp.c index 0a636395fd3..497e3d2888f 100644 --- a/usr.sbin/unbound/testcode/streamtcp.c +++ b/usr.sbin/unbound/testcode/streamtcp.c @@ -44,6 +44,8 @@ #include <getopt.h> #endif #include <signal.h> +#include <stdlib.h> +#include <unistd.h> #include "util/locks.h" #include "util/log.h" #include "util/net_help.h" @@ -71,6 +73,7 @@ static void usage(char* argv[]) printf("-f server what ipaddr@portnr to send the queries to\n"); printf("-u use UDP. No retries are attempted.\n"); printf("-n do not wait for an answer.\n"); + printf("-d secs delay after connection before sending query\n"); printf("-s use ssl\n"); printf("-h this help text\n"); exit(1); @@ -275,7 +278,8 @@ static int get_random(void) /** send the TCP queries and print answers */ static void -send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs) +send_em(const char* svr, int udp, int usessl, int noanswer, int delay, + int num, char** qs) { sldns_buffer* buf = sldns_buffer_new(65553); int fd = open_svr(svr, udp); @@ -310,6 +314,13 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs) } } for(i=0; i<num; i+=3) { + if (delay != 0) { +#ifdef HAVE_SLEEP + sleep((unsigned)delay); +#else + Sleep(delay*1000); +#endif + } printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]); write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i], qs[i+1], qs[i+2]); @@ -358,6 +369,7 @@ int main(int argc, char** argv) int udp = 0; int noanswer = 0; int usessl = 0; + int delay = 0; #ifdef USE_WINSOCK WSADATA wsa_data; @@ -382,7 +394,7 @@ int main(int argc, char** argv) if(argc == 1) { usage(argv); } - while( (c=getopt(argc, argv, "f:hnsu")) != -1) { + while( (c=getopt(argc, argv, "f:hnsud:")) != -1) { switch(c) { case 'f': svr = optarg; @@ -396,6 +408,14 @@ int main(int argc, char** argv) case 's': usessl = 1; break; + case 'd': + if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) { + printf("error parsing delay, " + "number expected: %s\n", optarg); + return 1; + } + delay = atoi(optarg); + break; case 'h': case '?': default: @@ -426,7 +446,7 @@ int main(int argc, char** argv) (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif } - send_em(svr, udp, usessl, noanswer, argc, argv); + send_em(svr, udp, usessl, noanswer, delay, argc, argv); checklock_stop(); #ifdef USE_WINSOCK WSACleanup(); diff --git a/usr.sbin/unbound/testcode/unitauth.c b/usr.sbin/unbound/testcode/unitauth.c index 4b538ef6268..c162e7ef964 100644 --- a/usr.sbin/unbound/testcode/unitauth.c +++ b/usr.sbin/unbound/testcode/unitauth.c @@ -111,8 +111,9 @@ static const char* zone_example_com = /* just an RRSIG rrset with nothing else, 2 rrsigs */ "z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" "z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" -#if 0 /* comparison of file does not work on this part because duplicates */ +#if 1 /* comparison of file does not work on this part because duplicates */ /* are removed and the rrsets are reordered */ +"end_of_check.z6.example.com. 3600 IN A 10.0.0.10\n" /* first rrsig, then A record */ "z6.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" "z6.example.com. 3600 IN A 10.0.0.10\n" @@ -131,6 +132,12 @@ static const char* zone_example_com = "z9.example.com. 3600 IN A 10.0.0.10\n" "z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" "z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" +/* different covered types, first RRSIGs then, RRs, then another RRSIG */ +"zz10.example.com. 3600 IN RRSIG AAAA 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" +"zz10.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" +"zz10.example.com. 3600 IN A 10.0.0.10\n" +"zz10.example.com. 3600 IN RRSIG CNAME 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n" +"zz10.example.com. 3600 IN AAAA ::11\n" #endif /* if0 for duplicates and reordering */ ; @@ -550,11 +557,16 @@ checkfile(char* f1, char *f2) cp2 = fgets(buf2, (int)sizeof(buf2), i2); if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2))) fatal_exit("fgets failed: %s", strerror(errno)); + if(strncmp(buf1, "end_of_check", 12) == 0) { + fclose(i1); + fclose(i2); + return; + } if(strcmp(buf1, buf2) != 0) { log_info("in files %s and %s:%d", f1, f2, line); log_info("'%s'", buf1); log_info("'%s'", buf2); - fatal_exit("files are not eqaul"); + fatal_exit("files are not equal"); } } unit_assert(feof(i1) && feof(i2)); diff --git a/usr.sbin/unbound/testcode/unitldns.c b/usr.sbin/unbound/testcode/unitldns.c index e27e46eaa92..66f75617037 100644 --- a/usr.sbin/unbound/testcode/unitldns.c +++ b/usr.sbin/unbound/testcode/unitldns.c @@ -199,15 +199,25 @@ rr_test_file(const char* input, const char* check) free(back); } +#define xstr(s) str(s) +#define str(s) #s + +#define SRCDIRSTR xstr(SRCDIR) + /** read rrs to and from string, to and from wireformat */ static void rr_tests(void) { - rr_test_file("testdata/test_ldnsrr.1", "testdata/test_ldnsrr.c1"); - rr_test_file("testdata/test_ldnsrr.2", "testdata/test_ldnsrr.c2"); - rr_test_file("testdata/test_ldnsrr.3", "testdata/test_ldnsrr.c3"); - rr_test_file("testdata/test_ldnsrr.4", "testdata/test_ldnsrr.c4"); - rr_test_file("testdata/test_ldnsrr.5", "testdata/test_ldnsrr.c5"); + rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.1", + SRCDIRSTR "/testdata/test_ldnsrr.c1"); + rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.2", + SRCDIRSTR "/testdata/test_ldnsrr.c2"); + rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.3", + SRCDIRSTR "/testdata/test_ldnsrr.c3"); + rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.4", + SRCDIRSTR "/testdata/test_ldnsrr.c4"); + rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.5", + SRCDIRSTR "/testdata/test_ldnsrr.c5"); } void diff --git a/usr.sbin/unbound/testcode/unitmain.c b/usr.sbin/unbound/testcode/unitmain.c index fecde80cc3d..e28be8c833a 100644 --- a/usr.sbin/unbound/testcode/unitmain.c +++ b/usr.sbin/unbound/testcode/unitmain.c @@ -404,12 +404,13 @@ config_tag_test(void) #include "util/rtt.h" #include "util/timehist.h" +#include "iterator/iterator.h" #include "libunbound/unbound.h" /** test RTT code */ static void rtt_test(void) { - int init = 376; + int init = UNKNOWN_SERVER_NICENESS; int i; struct rtt_info r; unit_show_func("util/rtt.c", "rtt_timeout"); diff --git a/usr.sbin/unbound/testcode/unitmsgparse.c b/usr.sbin/unbound/testcode/unitmsgparse.c index 627d10b78ec..c0b38bac76e 100644 --- a/usr.sbin/unbound/testcode/unitmsgparse.c +++ b/usr.sbin/unbound/testcode/unitmsgparse.c @@ -495,6 +495,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc, fclose(in); } +#define xstr(s) str(s) +#define str(s) #s + +#define SRCDIRSTR xstr(SRCDIR) + void msgparse_test(void) { time_t origttl = MAX_NEG_TTL; @@ -509,27 +514,27 @@ void msgparse_test(void) unit_show_feature("message parse"); simpletest(pkt, &alloc, out); /* plain hex dumps, like pcat */ - testfromfile(pkt, &alloc, out, "testdata/test_packets.1"); - testfromfile(pkt, &alloc, out, "testdata/test_packets.2"); - testfromfile(pkt, &alloc, out, "testdata/test_packets.3"); + testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.1"); + testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.2"); + testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.3"); /* like from drill -w - */ - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.4"); - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.5"); + testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.4"); + testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.5"); matches_nolocation = 1; /* RR order not important for the next test */ - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6"); + testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.6"); check_rrsigs = 1; - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7"); + testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.7"); check_rrsigs = 0; matches_nolocation = 0; check_formerr_gone = 1; - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8"); + testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.8"); check_formerr_gone = 0; check_rrsigs = 1; check_nosameness = 1; - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.9"); + testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.9"); check_nosameness = 0; check_rrsigs = 0; diff --git a/usr.sbin/unbound/testcode/unitverify.c b/usr.sbin/unbound/testcode/unitverify.c index 95676e10490..9e101324960 100644 --- a/usr.sbin/unbound/testcode/unitverify.c +++ b/usr.sbin/unbound/testcode/unitverify.c @@ -497,65 +497,70 @@ nsec3_hash_test(const char* fname) sldns_buffer_free(buf); } +#define xstr(s) str(s) +#define str(s) #s + +#define SRCDIRSTR xstr(SRCDIR) + void verify_test(void) { unit_show_feature("signature verify"); #ifdef USE_SHA1 - verifytest_file("testdata/test_signatures.1", "20070818005004"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004"); #endif #if defined(USE_DSA) && defined(USE_SHA1) - verifytest_file("testdata/test_signatures.2", "20080414005004"); - verifytest_file("testdata/test_signatures.3", "20080416005004"); - verifytest_file("testdata/test_signatures.4", "20080416005004"); - verifytest_file("testdata/test_signatures.5", "20080416005004"); - verifytest_file("testdata/test_signatures.6", "20080416005004"); - verifytest_file("testdata/test_signatures.7", "20070829144150"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150"); #endif /* USE_DSA */ #ifdef USE_SHA1 - verifytest_file("testdata/test_signatures.8", "20070829144150"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150"); #endif #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2) - verifytest_file("testdata/test_sigs.rsasha256", "20070829144150"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256", "20070829144150"); # ifdef USE_SHA1 - verifytest_file("testdata/test_sigs.sha1_and_256", "20070829144150"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150"); # endif - verifytest_file("testdata/test_sigs.rsasha256_draft", "20090101000000"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256_draft", "20090101000000"); #endif #if (defined(HAVE_EVP_SHA512) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2) - verifytest_file("testdata/test_sigs.rsasha512_draft", "20070829144150"); - verifytest_file("testdata/test_signatures.9", "20171215000000"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha512_draft", "20070829144150"); + verifytest_file(SRCDIRSTR "/testdata/test_signatures.9", "20171215000000"); #endif #ifdef USE_SHA1 - verifytest_file("testdata/test_sigs.hinfo", "20090107100022"); - verifytest_file("testdata/test_sigs.revoked", "20080414005004"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004"); #endif #ifdef USE_GOST if(sldns_key_EVP_load_gost_id()) - verifytest_file("testdata/test_sigs.gost", "20090807060504"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost", "20090807060504"); else printf("Warning: skipped GOST, openssl does not provide gost.\n"); #endif #ifdef USE_ECDSA /* test for support in case we use libNSS and ECC is removed */ if(dnskey_algo_id_is_supported(LDNS_ECDSAP256SHA256)) { - verifytest_file("testdata/test_sigs.ecdsa_p256", "20100908100439"); - verifytest_file("testdata/test_sigs.ecdsa_p384", "20100908100439"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.ecdsa_p256", "20100908100439"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.ecdsa_p384", "20100908100439"); } - dstest_file("testdata/test_ds.sha384"); + dstest_file(SRCDIRSTR "/testdata/test_ds.sha384"); #endif #ifdef USE_ED25519 if(dnskey_algo_id_is_supported(LDNS_ED25519)) { - verifytest_file("testdata/test_sigs.ed25519", "20170530140439"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.ed25519", "20170530140439"); } #endif #ifdef USE_ED448 if(dnskey_algo_id_is_supported(LDNS_ED448)) { - verifytest_file("testdata/test_sigs.ed448", "20180408143630"); + verifytest_file(SRCDIRSTR "/testdata/test_sigs.ed448", "20180408143630"); } #endif #ifdef USE_SHA1 - dstest_file("testdata/test_ds.sha1"); + dstest_file(SRCDIRSTR "/testdata/test_ds.sha1"); #endif nsectest(); - nsec3_hash_test("testdata/test_nsec3_hash.1"); + nsec3_hash_test(SRCDIRSTR "/testdata/test_nsec3_hash.1"); } diff --git a/usr.sbin/unbound/util/edns.c b/usr.sbin/unbound/util/edns.c new file mode 100644 index 00000000000..2c4e4a1fd27 --- /dev/null +++ b/usr.sbin/unbound/util/edns.c @@ -0,0 +1,83 @@ +/* + * util/edns.c - handle base EDNS options. + * + * Copyright (c) 2018, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains functions for base EDNS options. + */ + +#include "config.h" + +#include "util/config_file.h" +#include "util/netevent.h" +#include "util/regional.h" +#include "util/data/msgparse.h" +#include "util/data/msgreply.h" + +static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in, + struct comm_point* c, struct regional* region) +{ + if(c->type == comm_udp) + return 1; + + /* To respond with a Keepalive option, the client connection + * must have received one message with a TCP Keepalive EDNS option, + * and that option must have 0 length data. Subsequent messages + * sent on that connection will have a TCP Keepalive option. + */ + if(c->tcp_keepalive || + edns_opt_list_find(edns_in->opt_list, LDNS_EDNS_KEEPALIVE)) { + int keepalive = c->tcp_timeout_msec / 100; + uint8_t data[2]; + data[0] = (uint8_t)((keepalive >> 8) & 0xff); + data[1] = (uint8_t)(keepalive & 0xff); + if(!edns_opt_list_append(&edns_out->opt_list, LDNS_EDNS_KEEPALIVE, + sizeof(data), data, region)) + return 0; + c->tcp_keepalive = 1; + } + return 1; +} + +int apply_edns_options(struct edns_data* edns_out, struct edns_data* edns_in, + struct config_file* cfg, struct comm_point* c, struct regional* region) +{ + if(cfg->do_tcp_keepalive && + !edns_keepalive(edns_out, edns_in, c, region)) + return 0; + + return 1; +} diff --git a/usr.sbin/unbound/util/edns.h b/usr.sbin/unbound/util/edns.h new file mode 100644 index 00000000000..a4ee7def634 --- /dev/null +++ b/usr.sbin/unbound/util/edns.h @@ -0,0 +1,62 @@ +/* + * util/edns.h - handle base EDNS options. + * + * Copyright (c) 2018, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains functions for base EDNS options. + */ + +#ifndef UTIL_EDNS_H +#define UTIL_EDNS_H + +struct edns_data; +struct config_file; +struct comm_point; +struct regional; + +/** + * Apply common EDNS options. + * + * @param edns_out: initialised edns information with outbound edns. + * @param edns_in: initialised edns information with received edns. + * @param cfg: configuration. + * @param c: comm channel. + * @param region: the region to allocate the edns options in. + */ +int apply_edns_options(struct edns_data* edns_out, struct edns_data* edns_in, + struct config_file* cfg, struct comm_point* c, struct regional* region); + +#endif diff --git a/usr.sbin/unbound/util/rtt.c b/usr.sbin/unbound/util/rtt.c index 5d86f13378e..f51576fb57f 100644 --- a/usr.sbin/unbound/util/rtt.c +++ b/usr.sbin/unbound/util/rtt.c @@ -41,6 +41,7 @@ */ #include "config.h" #include "util/rtt.h" +#include "iterator/iterator.h" /* overwritten by config: infra_cache_min_rtt: */ int RTT_MIN_TIMEOUT = 50; @@ -61,7 +62,7 @@ void rtt_init(struct rtt_info* rtt) { rtt->srtt = 0; - rtt->rttvar = 94; + rtt->rttvar = UNKNOWN_SERVER_NICENESS/4; rtt->rto = calc_rto(rtt); /* default value from the book is 0 + 4*0.75 = 3 seconds */ /* first RTO is 0 + 4*0.094 = 0.376 seconds */ diff --git a/usr.sbin/unbound/util/tcp_conn_limit.c b/usr.sbin/unbound/util/tcp_conn_limit.c new file mode 100644 index 00000000000..d7d86a5407b --- /dev/null +++ b/usr.sbin/unbound/util/tcp_conn_limit.c @@ -0,0 +1,194 @@ +/* + * daemon/tcp_conn_limit.c - client TCP connection limit storage for the server. + * + * Copyright (c) 2018, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file helps the server discard excess TCP connections. + */ +#include "config.h" +#include "util/regional.h" +#include "util/log.h" +#include "util/config_file.h" +#include "util/net_help.h" +#include "util/tcp_conn_limit.h" +#include "services/localzone.h" +#include "sldns/str2wire.h" + +struct tcl_list* +tcl_list_create(void) +{ + struct tcl_list* tcl = (struct tcl_list*)calloc(1, + sizeof(struct tcl_list)); + if(!tcl) + return NULL; + tcl->region = regional_create(); + if(!tcl->region) { + tcl_list_delete(tcl); + return NULL; + } + return tcl; +} + +static void +tcl_list_free_node(rbnode_type* node, void* ATTR_UNUSED(arg)) +{ + struct tcl_addr* n = (struct tcl_addr*) node; + lock_quick_destroy(&n->lock); +#ifdef THREADS_DISABLED + (void)n; +#endif +} + +void +tcl_list_delete(struct tcl_list* tcl) +{ + if(!tcl) + return; + traverse_postorder(&tcl->tree, tcl_list_free_node, NULL); + regional_destroy(tcl->region); + free(tcl); +} + +/** insert new address into tcl_list structure */ +static struct tcl_addr* +tcl_list_insert(struct tcl_list* tcl, struct sockaddr_storage* addr, + socklen_t addrlen, int net, uint32_t limit, + int complain_duplicates) +{ + struct tcl_addr* node = regional_alloc_zero(tcl->region, + sizeof(struct tcl_addr)); + if(!node) + return NULL; + lock_quick_init(&node->lock); + node->limit = limit; + if(!addr_tree_insert(&tcl->tree, &node->node, addr, addrlen, net)) { + if(complain_duplicates) + verbose(VERB_QUERY, "duplicate tcl address ignored."); + } + return node; +} + +/** apply tcl_list string */ +static int +tcl_list_str_cfg(struct tcl_list* tcl, const char* str, const char* s2, + int complain_duplicates) +{ + struct sockaddr_storage addr; + int net; + socklen_t addrlen; + uint32_t limit; + if(atoi(s2) < 0) { + log_err("bad connection limit %s", s2); + return 0; + } + limit = (uint32_t)atoi(s2); + if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) { + log_err("cannot parse connection limit netblock: %s", str); + return 0; + } + if(!tcl_list_insert(tcl, &addr, addrlen, net, limit, + complain_duplicates)) { + log_err("out of memory"); + return 0; + } + return 1; +} + +/** read tcl_list config */ +static int +read_tcl_list(struct tcl_list* tcl, struct config_file* cfg) +{ + struct config_str2list* p; + for(p = cfg->tcp_connection_limits; p; p = p->next) { + log_assert(p->str && p->str2); + if(!tcl_list_str_cfg(tcl, p->str, p->str2, 1)) + return 0; + } + return 1; +} + +int +tcl_list_apply_cfg(struct tcl_list* tcl, struct config_file* cfg) +{ + regional_free_all(tcl->region); + addr_tree_init(&tcl->tree); + if(!read_tcl_list(tcl, cfg)) + return 0; + addr_tree_init_parents(&tcl->tree); + return 1; +} + +int +tcl_new_connection(struct tcl_addr* tcl) +{ + if(tcl) { + int res = 1; + lock_quick_lock(&tcl->lock); + if(tcl->count >= tcl->limit) + res = 0; + else + tcl->count++; + lock_quick_unlock(&tcl->lock); + return res; + } + return 1; +} + +void +tcl_close_connection(struct tcl_addr* tcl) +{ + if(tcl) { + lock_quick_lock(&tcl->lock); + log_assert(tcl->count > 0); + tcl->count--; + lock_quick_unlock(&tcl->lock); + } +} + +struct tcl_addr* +tcl_addr_lookup(struct tcl_list* tcl, struct sockaddr_storage* addr, + socklen_t addrlen) +{ + return (struct tcl_addr*)addr_tree_lookup(&tcl->tree, + addr, addrlen); +} + +size_t +tcl_list_get_mem(struct tcl_list* tcl) +{ + if(!tcl) return 0; + return sizeof(*tcl) + regional_get_mem(tcl->region); +} diff --git a/usr.sbin/unbound/util/tcp_conn_limit.h b/usr.sbin/unbound/util/tcp_conn_limit.h new file mode 100644 index 00000000000..4fb71a32803 --- /dev/null +++ b/usr.sbin/unbound/util/tcp_conn_limit.h @@ -0,0 +1,130 @@ +/* + * daemon/tcp_conn_limit.h - client TCP connection limit storage for the server. + * + * Copyright (c) 2018, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file keeps track of the limit on the number of TCP connections + * each client makes the server. + */ + +#ifndef DAEMON_TCP_CONN_LIMIT_H +#define DAEMON_TCP_CONN_LIMIT_H +#include "util/storage/dnstree.h" +#include "util/locks.h" +struct config_file; +struct regional; + +/** + * TCP connection limit storage structure + */ +struct tcl_list { + /** regional for allocation */ + struct regional* region; + /** + * Tree of the addresses that are TCP connection limited. + * contents of type tcl_addr. + */ + rbtree_type tree; +}; + +/** + * + * An address span with connection limit information + */ +struct tcl_addr { + /** node in address tree */ + struct addr_tree_node node; + /** lock on structure data */ + lock_quick_type lock; + /** connection limit on this netblock */ + uint32_t limit; + /** current connection count on this netblock */ + uint32_t count; +}; + +/** + * Create TCP connection limit structure + * @return new structure or NULL on error. + */ +struct tcl_list* tcl_list_create(void); + +/** + * Delete TCP connection limit structure. + * @param tcl: to delete. + */ +void tcl_list_delete(struct tcl_list* tcl); + +/** + * Process TCP connection limit config. + * @param tcl: where to store. + * @param cfg: config options. + * @return 0 on error. + */ +int tcl_list_apply_cfg(struct tcl_list* tcl, struct config_file* cfg); + +/** + * Increment TCP connection count if found, provided the + * count was below the limit. + * @param tcl: structure for tcl storage, or NULL. + * @return: 0 if limit reached, 1 if tcl was NULL or limit not reached. + */ +int tcl_new_connection(struct tcl_addr* tcl); + +/** + * Decrement TCP connection count if found. + * @param tcl: structure for tcl storage, or NULL. + */ +void tcl_close_connection(struct tcl_addr* tcl); + +/** + * Lookup address to see its TCP connection limit structure + * @param tcl: structure for address storage. + * @param addr: address to check + * @param addrlen: length of addr. + * @return: tcl structure from this address. + */ +struct tcl_addr* +tcl_addr_lookup(struct tcl_list* tcl, struct sockaddr_storage* addr, + socklen_t addrlen); + +/** + * Get memory used by TCP connection limit structure. + * @param tcl: structure for address storage. + * @return bytes in use. + */ +size_t tcl_list_get_mem(struct tcl_list* tcl); + +#endif /* DAEMON_TCP_CONN_LIMIT_H */ diff --git a/usr.sbin/unbound/validator/val_kcache.c b/usr.sbin/unbound/validator/val_kcache.c index 22070cc6a90..e0b88b6df81 100644 --- a/usr.sbin/unbound/validator/val_kcache.c +++ b/usr.sbin/unbound/validator/val_kcache.c @@ -89,7 +89,7 @@ key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey, if(key_entry_isbad(k) && qstate->errinf && qstate->env->cfg->val_log_level >= 2) { /* on malloc failure there is simply no reason string */ - key_entry_set_reason(k, errinf_to_str(qstate)); + key_entry_set_reason(k, errinf_to_str_bogus(qstate)); } key_entry_hash(k); slabhash_insert(kcache->slab, k->entry.hash, &k->entry, |