aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/daemon/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/daemon/remote.c')
-rw-r--r--contrib/unbound/daemon/remote.c209
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);