diff options
Diffstat (limited to 'contrib/unbound/daemon/remote.c')
-rw-r--r-- | contrib/unbound/daemon/remote.c | 209 |
1 files changed, 137 insertions, 72 deletions
diff --git a/contrib/unbound/daemon/remote.c b/contrib/unbound/daemon/remote.c index ba02d7de100f..6882e16604f6 100644 --- a/contrib/unbound/daemon/remote.c +++ b/contrib/unbound/daemon/remote.c @@ -21,16 +21,16 @@ * 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 REGENTS 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. + * "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. */ /** @@ -47,7 +47,6 @@ #include <openssl/err.h> #endif #include <ctype.h> -#include <ldns/ldns.h> #include "daemon/remote.h" #include "daemon/worker.h" #include "daemon/daemon.h" @@ -75,6 +74,10 @@ #include "iterator/iter_delegpt.h" #include "services/outbound_list.h" #include "services/outside_network.h" +#include "ldns/str2wire.h" +#include "ldns/parseutil.h" +#include "ldns/wire2str.h" +#include "ldns/sbuffer.h" #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> @@ -268,7 +271,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err) } /* open fd */ - fd = create_tcp_accept_sock(res, 1, &noproto); + fd = create_tcp_accept_sock(res, 1, &noproto, 0); freeaddrinfo(res); if(fd == -1 && noproto) { if(!noproto_is_err) @@ -629,8 +632,8 @@ print_stats(SSL* ssl, const char* nm, struct stats_info* s) if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%u\n", nm, (unsigned)s->mesh_num_reply_states)) return 0; timeval_divide(&avg, &s->mesh_replies_sum_wait, s->mesh_replies_sent); - if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ"%d.%6.6d\n", nm, - (int)avg.tv_sec, (int)avg.tv_usec)) return 0; + if(!ssl_printf(ssl, "%s.recursion.time.avg"SQ ARG_LL "d.%6.6d\n", nm, + (long long)avg.tv_sec, (int)avg.tv_usec)) return 0; if(!ssl_printf(ssl, "%s.recursion.time.median"SQ"%g\n", nm, s->mesh_time_median)) return 0; return 1; @@ -713,12 +716,12 @@ print_uptime(SSL* ssl, struct worker* worker, int reset) timeval_subtract(&dt, &now, &worker->daemon->time_last_stat); if(reset) worker->daemon->time_last_stat = now; - if(!ssl_printf(ssl, "time.now"SQ"%d.%6.6d\n", - (unsigned)now.tv_sec, (unsigned)now.tv_usec)) return 0; - if(!ssl_printf(ssl, "time.up"SQ"%d.%6.6d\n", - (unsigned)up.tv_sec, (unsigned)up.tv_usec)) return 0; - if(!ssl_printf(ssl, "time.elapsed"SQ"%d.%6.6d\n", - (unsigned)dt.tv_sec, (unsigned)dt.tv_usec)) return 0; + if(!ssl_printf(ssl, "time.now"SQ ARG_LL "d.%6.6d\n", + (long long)now.tv_sec, (unsigned)now.tv_usec)) return 0; + if(!ssl_printf(ssl, "time.up"SQ ARG_LL "d.%6.6d\n", + (long long)up.tv_sec, (unsigned)up.tv_usec)) return 0; + if(!ssl_printf(ssl, "time.elapsed"SQ ARG_LL "d.%6.6d\n", + (long long)dt.tv_sec, (unsigned)dt.tv_usec)) return 0; return 1; } @@ -756,13 +759,13 @@ print_ext(SSL* ssl, struct stats_info* s) { int i; char nm[16]; - const ldns_rr_descriptor* desc; - const ldns_lookup_table* lt; + const sldns_rr_descriptor* desc; + const sldns_lookup_table* lt; /* TYPE */ for(i=0; i<STATS_QTYPE_NUM; i++) { if(inhibit_zero && s->svr.qtype[i] == 0) continue; - desc = ldns_rr_descript((uint16_t)i); + desc = sldns_rr_descript((uint16_t)i); if(desc && desc->_name) { snprintf(nm, sizeof(nm), "%s", desc->_name); } else if (i == LDNS_RR_TYPE_IXFR) { @@ -789,7 +792,7 @@ print_ext(SSL* ssl, struct stats_info* s) for(i=0; i<STATS_QCLASS_NUM; i++) { if(inhibit_zero && s->svr.qclass[i] == 0) continue; - lt = ldns_lookup_by_id(ldns_rr_classes, i); + lt = sldns_lookup_by_id(sldns_rr_classes, i); if(lt && lt->name) { snprintf(nm, sizeof(nm), "%s", lt->name); } else { @@ -806,7 +809,7 @@ print_ext(SSL* ssl, struct stats_info* s) for(i=0; i<STATS_OPCODE_NUM; i++) { if(inhibit_zero && s->svr.qopcode[i] == 0) continue; - lt = ldns_lookup_by_id(ldns_opcodes, i); + lt = sldns_lookup_by_id(sldns_opcodes, i); if(lt && lt->name) { snprintf(nm, sizeof(nm), "%s", lt->name); } else { @@ -846,7 +849,7 @@ print_ext(SSL* ssl, struct stats_info* s) for(i=0; i<STATS_RCODE_NUM; i++) { if(inhibit_zero && s->svr.ans_rcode[i] == 0) continue; - lt = ldns_lookup_by_id(ldns_rcodes, i); + lt = sldns_lookup_by_id(sldns_rcodes, i); if(lt && lt->name) { snprintf(nm, sizeof(nm), "%s", lt->name); } else { @@ -912,17 +915,20 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset) static int parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) { - ldns_rdf* rdf; + uint8_t nm[LDNS_MAX_DOMAINLEN+1]; + size_t nmlen = sizeof(nm); + int status; *res = NULL; *len = 0; *labs = 0; - rdf = ldns_dname_new_frm_str(str); - if(!rdf) { - ssl_printf(ssl, "error cannot parse name %s\n", str); + status = sldns_str2wire_dname_buf(str, nm, &nmlen); + if(status != 0) { + ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", str, + LDNS_WIREPARSE_OFFSET(status), + sldns_get_errorstr_parse(status)); return 0; } - *res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf)); - ldns_rdf_deep_free(rdf); + *res = memdup(nm, nmlen); if(!*res) { ssl_printf(ssl, "error out of memory\n"); return 0; @@ -975,7 +981,7 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg) free(nm); return; } - lock_quick_lock(&worker->daemon->local_zones->lock); + lock_rw_wrlock(&worker->daemon->local_zones->lock); if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* already present in tree */ @@ -983,17 +989,17 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg) z->type = t; /* update type anyway */ lock_rw_unlock(&z->lock); free(nm); - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); send_ok(ssl); return; } if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, t)) { - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); ssl_printf(ssl, "error out of memory\n"); return; } - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); send_ok(ssl); } @@ -1007,13 +1013,13 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg) struct local_zone* z; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) return; - lock_quick_lock(&worker->daemon->local_zones->lock); + lock_rw_wrlock(&worker->daemon->local_zones->lock); if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* present in tree */ local_zones_del_zone(worker->daemon->local_zones, z); } - lock_quick_unlock(&worker->daemon->local_zones->lock); + lock_rw_unlock(&worker->daemon->local_zones->lock); free(nm); send_ok(ssl); } @@ -1022,8 +1028,7 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg) static void do_data_add(SSL* ssl, struct worker* worker, char* arg) { - if(!local_zones_add_RR(worker->daemon->local_zones, arg, - worker->env.scratch_buffer)) { + if(!local_zones_add_RR(worker->daemon->local_zones, arg)) { ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg); return; } @@ -1090,7 +1095,7 @@ do_flush_type(SSL* ssl, struct worker* worker, char* arg) return; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) return; - t = ldns_get_rr_type_by_name(arg2); + t = sldns_get_rr_type_by_name(arg2); do_cache_remove(worker, nm, nmlen, t, LDNS_RR_CLASS_IN); free(nm); @@ -1118,9 +1123,9 @@ struct del_info { /** labels */ int labs; /** now */ - uint32_t now; + time_t now; /** time to invalidate to */ - uint32_t expired; + time_t expired; /** number of rrsets removed */ size_t num_rrsets; /** number of msgs removed */ @@ -1388,9 +1393,9 @@ ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt_addr* a; int f = 0; if(str) { /* print header for forward, stub */ - char* c = ldns_rr_class2str(dclass); + char* c = sldns_wire2str_class(dclass); dname_str(nm, buf); - if(!ssl_printf(ssl, "%s %s %s: ", buf, c, str)) { + if(!ssl_printf(ssl, "%s %s %s: ", buf, (c?c:"CLASS??"), str)) { free(c); return 0; } @@ -1571,7 +1576,7 @@ do_forward_add(SSL* ssl, struct worker* worker, char* args) struct delegpt* dp = NULL; if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, NULL)) return; - if(insecure) { + if(insecure && worker->env.anchors) { if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm)) { (void)ssl_printf(ssl, "error out of memory\n"); @@ -1598,7 +1603,7 @@ do_forward_remove(SSL* ssl, struct worker* worker, char* args) uint8_t* nm = NULL; if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) return; - if(insecure) + if(insecure && worker->env.anchors) anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm); forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, nm); @@ -1616,7 +1621,7 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) struct delegpt* dp = NULL; if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, &prime)) return; - if(insecure) { + if(insecure && worker->env.anchors) { if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm)) { (void)ssl_printf(ssl, "error out of memory\n"); @@ -1626,8 +1631,9 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) } } if(!forwards_add_stub_hole(fwd, LDNS_RR_CLASS_IN, nm)) { - if(insecure) anchors_delete_insecure(worker->env.anchors, - LDNS_RR_CLASS_IN, nm); + if(insecure && worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm); (void)ssl_printf(ssl, "error out of memory\n"); delegpt_free_mlc(dp); free(nm); @@ -1636,8 +1642,9 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) if(!hints_add_stub(worker->env.hints, LDNS_RR_CLASS_IN, dp, !prime)) { (void)ssl_printf(ssl, "error out of memory\n"); forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm); - if(insecure) anchors_delete_insecure(worker->env.anchors, - LDNS_RR_CLASS_IN, nm); + if(insecure && worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm); free(nm); return; } @@ -1654,7 +1661,7 @@ do_stub_remove(SSL* ssl, struct worker* worker, char* args) uint8_t* nm = NULL; if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) return; - if(insecure) + if(insecure && worker->env.anchors) anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, nm); forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm); @@ -1663,6 +1670,43 @@ do_stub_remove(SSL* ssl, struct worker* worker, char* args) send_ok(ssl); } +/** do the insecure_add command */ +static void +do_insecure_add(SSL* ssl, struct worker* worker, char* arg) +{ + size_t nmlen; + int nmlabs; + uint8_t* nm = NULL; + if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if(worker->env.anchors) { + if(!anchors_add_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm)) { + (void)ssl_printf(ssl, "error out of memory\n"); + free(nm); + return; + } + } + free(nm); + send_ok(ssl); +} + +/** do the insecure_remove command */ +static void +do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) +{ + size_t nmlen; + int nmlabs; + uint8_t* nm = NULL; + if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if(worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, + LDNS_RR_CLASS_IN, nm); + free(nm); + send_ok(ssl); +} + /** do the status command */ static void do_status(SSL* ssl, struct worker* worker) @@ -1684,7 +1728,7 @@ do_status(SSL* ssl, struct worker* worker) if(!ssl_printf(ssl, " ]\n")) return; uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec; - if(!ssl_printf(ssl, "uptime: %u seconds\n", (unsigned)uptime)) + if(!ssl_printf(ssl, "uptime: " ARG_LL "d seconds\n", (long long)uptime)) return; if(!ssl_printf(ssl, "unbound (pid %d) is running...\n", (int)getpid())) @@ -1703,7 +1747,8 @@ get_mesh_age(struct mesh_state* m, char* buf, size_t len, while(r && r->next) r = r->next; timeval_subtract(&d, env->now_tv, &r->start_time); - snprintf(buf, len, "%d.%6.6d", (int)d.tv_sec, (int)d.tv_usec); + snprintf(buf, len, ARG_LL "d.%6.6d", + (long long)d.tv_sec, (int)d.tv_usec); } else { snprintf(buf, len, "-"); } @@ -1748,10 +1793,11 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m, if(m->sub_set.count == 0) snprintf(buf, len, " (empty_list)"); RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) { - char* t = ldns_rr_type2str(sub->s->s.qinfo.qtype); - char* c = ldns_rr_class2str(sub->s->s.qinfo.qclass); + char* t = sldns_wire2str_type(sub->s->s.qinfo.qtype); + char* c = sldns_wire2str_class(sub->s->s.qinfo.qclass); dname_str(sub->s->s.qinfo.qname, nm); - snprintf(buf, len, " %s %s %s", t, c, nm); + snprintf(buf, len, " %s %s %s", (t?t:"TYPE??"), + (c?c:"CLASS??"), nm); l = strlen(buf); buf += l; len -= l; free(t); @@ -1780,13 +1826,14 @@ do_dump_requestlist(SSL* ssl, struct worker* worker) mesh = worker->env.mesh; if(!mesh) return; RBTREE_FOR(m, struct mesh_state*, &mesh->all) { - char* t = ldns_rr_type2str(m->s.qinfo.qtype); - char* c = ldns_rr_class2str(m->s.qinfo.qclass); + char* t = sldns_wire2str_type(m->s.qinfo.qtype); + char* c = sldns_wire2str_class(m->s.qinfo.qclass); dname_str(m->s.qinfo.qname, buf); get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env); get_mesh_status(mesh, m, statbuf, sizeof(statbuf)); if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n", - num, t, c, buf, timebuf, statbuf)) { + num, (t?t:"TYPE??"), (c?c:"CLASS??"), buf, timebuf, + statbuf)) { free(t); free(c); return; @@ -1804,7 +1851,7 @@ struct infra_arg { /** the SSL connection */ SSL* ssl; /** the time now */ - uint32_t now; + time_t now; }; /** callback for every host element in the infra cache */ @@ -1927,7 +1974,7 @@ do_list_local_zones(SSL* ssl, struct worker* worker) struct local_zones* zones = worker->daemon->local_zones; struct local_zone* z; char buf[257]; - lock_quick_lock(&zones->lock); + lock_rw_rdlock(&zones->lock); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); dname_str(z->name, buf); @@ -1935,7 +1982,7 @@ do_list_local_zones(SSL* ssl, struct worker* worker) local_zone_type2str(z->type)); lock_rw_unlock(&z->lock); } - lock_quick_unlock(&zones->lock); + lock_rw_unlock(&zones->lock); } /** do the list_local_data command */ @@ -1946,22 +1993,30 @@ do_list_local_data(SSL* ssl, struct worker* worker) struct local_zone* z; struct local_data* d; struct local_rrset* p; - lock_quick_lock(&zones->lock); + char* s = (char*)sldns_buffer_begin(worker->env.scratch_buffer); + size_t slen = sldns_buffer_capacity(worker->env.scratch_buffer); + lock_rw_rdlock(&zones->lock); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); RBTREE_FOR(d, struct local_data*, &z->data) { for(p = d->rrsets; p; p = p->next) { - ldns_rr_list* rr = packed_rrset_to_rr_list( - p->rrset, worker->env.scratch_buffer); - char* str = ldns_rr_list2str(rr); - (void)ssl_printf(ssl, "%s", str); - free(str); - ldns_rr_list_free(rr); + struct packed_rrset_data* d = + (struct packed_rrset_data*)p->rrset->entry.data; + size_t i; + for(i=0; i<d->count + d->rrsig_count; i++) { + if(!packed_rr_to_string(p->rrset, i, + 0, s, slen)) { + if(!ssl_printf(ssl, "BADRR\n")) + return; + } + if(!ssl_printf(ssl, "%s\n", s)) + return; + } } } lock_rw_unlock(&z->lock); } - lock_quick_unlock(&zones->lock); + lock_rw_unlock(&zones->lock); } /** tell other processes to execute the command */ @@ -2050,6 +2105,16 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, if(rc) distribute_cmd(rc, ssl, cmd); do_forward_remove(ssl, worker, skipwhite(p+14)); return; + } else if(cmdcmp(p, "insecure_add", 12)) { + /* must always distribute this cmd */ + if(rc) distribute_cmd(rc, ssl, cmd); + do_insecure_add(ssl, worker, skipwhite(p+12)); + return; + } else if(cmdcmp(p, "insecure_remove", 15)) { + /* must always distribute this cmd */ + if(rc) distribute_cmd(rc, ssl, cmd); + do_insecure_remove(ssl, worker, skipwhite(p+15)); + return; } else if(cmdcmp(p, "forward", 7)) { /* must always distribute this cmd */ if(rc) distribute_cmd(rc, ssl, cmd); |