import unbound 1.8.0, tested by myself and benno@
authorsthen <sthen@openbsd.org>
Thu, 20 Sep 2018 23:14:36 +0000 (23:14 +0000)
committersthen <sthen@openbsd.org>
Thu, 20 Sep 2018 23:14:36 +0000 (23:14 +0000)
17 files changed:
usr.sbin/unbound/ipsecmod/ipsecmod.c
usr.sbin/unbound/respip/respip.c
usr.sbin/unbound/testcode/fake_event.c
usr.sbin/unbound/testcode/replay.h
usr.sbin/unbound/testcode/streamtcp.1
usr.sbin/unbound/testcode/streamtcp.c
usr.sbin/unbound/testcode/unitauth.c
usr.sbin/unbound/testcode/unitldns.c
usr.sbin/unbound/testcode/unitmain.c
usr.sbin/unbound/testcode/unitmsgparse.c
usr.sbin/unbound/testcode/unitverify.c
usr.sbin/unbound/util/edns.c [new file with mode: 0644]
usr.sbin/unbound/util/edns.h [new file with mode: 0644]
usr.sbin/unbound/util/rtt.c
usr.sbin/unbound/util/tcp_conn_limit.c [new file with mode: 0644]
usr.sbin/unbound/util/tcp_conn_limit.h [new file with mode: 0644]
usr.sbin/unbound/validator/val_kcache.c

index 3e4ee6a..c8400c6 100644 (file)
@@ -341,6 +341,8 @@ ipsecmod_handle_query(struct module_qstate* qstate,
                                                qstate->env->cfg->ipsecmod_max_ttl;
                                        qstate->return_msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(
                                                qstate->return_msg->rep->ttl);
+                                       qstate->return_msg->rep->serve_expired_ttl = qstate->return_msg->rep->ttl +
+                                               qstate->env->cfg->serve_expired_ttl;
                                }
                        }
                }
index 2e9313f..135c45f 100644 (file)
@@ -611,8 +611,9 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
         * EDNS0 OPT RR in the additional section appended on sending it out),
         * so the total number of RRsets is an_numrrsets. */
        new_rep = construct_reply_info_base(region, rep->flags,
-               rep->qdcount, rep->ttl, rep->prefetch_ttl, an_numrrsets,
-               0, 0, an_numrrsets, sec_status_insecure);
+               rep->qdcount, rep->ttl, rep->prefetch_ttl,
+               rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets,
+               sec_status_insecure);
        if(!new_rep)
                return NULL;
        if(!reply_info_alloc_rrset_keys(new_rep, NULL, region))
index 80e3685..777ed73 100644 (file)
@@ -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)
 {
index 81f0a2c..0cce0b4 100644 (file)
@@ -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 */
index 7c738d9..526c8e1 100644 (file)
@@ -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.
index 0a63639..497e3d2 100644 (file)
@@ -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();
index 4b538ef..c162e7e 100644 (file)
@@ -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));
index e27e46e..66f7561 100644 (file)
@@ -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
index fecde80..e28be8c 100644 (file)
@@ -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");
index 627d10b..c0b38ba 100644 (file)
@@ -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;
 
index 95676e1..9e10132 100644 (file)
@@ -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 (file)
index 0000000..2c4e4a1
--- /dev/null
@@ -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 (file)
index 0000000..a4ee7de
--- /dev/null
@@ -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
index 5d86f13..f51576f 100644 (file)
@@ -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 (file)
index 0000000..d7d86a5
--- /dev/null
@@ -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 (file)
index 0000000..4fb71a3
--- /dev/null
@@ -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 */
index 22070cc..e0b88b6 100644 (file)
@@ -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,