diff options
Diffstat (limited to '')
23 files changed, 655 insertions, 305 deletions
diff --git a/external/unbound/libunbound/context.c b/external/unbound/libunbound/context.c index 4469b5bb4..e203111b7 100644 --- a/external/unbound/libunbound/context.c +++ b/external/unbound/libunbound/context.c @@ -62,6 +62,7 @@ context_finalize(struct ub_ctx* ctx) config_apply(cfg); if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) return UB_INITFAIL; + log_edns_known_options(VERB_ALGO, ctx->env); ctx->local_zones = local_zones_create(); if(!ctx->local_zones) return UB_NOMEM; @@ -126,7 +127,7 @@ find_id(struct ub_ctx* ctx, int* id) struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass, - ub_callback_t cb, void* cbarg) + ub_callback_type cb, void* cbarg) { struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q)); if(!q) return NULL; diff --git a/external/unbound/libunbound/context.h b/external/unbound/libunbound/context.h index 31ca09c6d..1761c4d87 100644 --- a/external/unbound/libunbound/context.h +++ b/external/unbound/libunbound/context.h @@ -49,7 +49,7 @@ struct libworker; struct tube; struct sldns_buffer; -struct event_base; +struct ub_event_base; /** * The context structure @@ -61,17 +61,17 @@ struct event_base; struct ub_ctx { /* --- pipes --- */ /** mutex on query write pipe */ - lock_basic_t qqpipe_lock; + lock_basic_type qqpipe_lock; /** the query write pipe */ struct tube* qq_pipe; /** mutex on result read pipe */ - lock_basic_t rrpipe_lock; + lock_basic_type rrpipe_lock; /** the result read pipe */ struct tube* rr_pipe; /* --- shared data --- */ /** mutex for access to env.cfg, finalized and dothread */ - lock_basic_t cfglock; + lock_basic_type cfglock; /** * The context has been finalized * This is after config when the first resolve is done. @@ -84,7 +84,7 @@ struct ub_ctx { /** pid of bg worker process */ pid_t bg_pid; /** tid of bg worker thread */ - ub_thread_t bg_tid; + ub_thread_type bg_tid; /** do threading (instead of forking) for async resolution */ int dothread; @@ -114,7 +114,7 @@ struct ub_ctx { struct ub_randstate* seed_rnd; /** event base for event oriented interface */ - struct event_base* event_base; + struct ub_event_base* event_base; /** libworker for event based interface */ struct libworker* event_worker; @@ -129,7 +129,7 @@ struct ub_ctx { * Used to see if querynum is free for use. * Content of type ctx_query. */ - rbtree_t queries; + rbtree_type queries; }; /** @@ -140,7 +140,7 @@ struct ub_ctx { */ struct ctx_query { /** node in rbtree, must be first entry, key is ptr to the querynum */ - struct rbnode_t node; + struct rbnode_type node; /** query id number, key for node */ int querynum; /** was this an async query? */ @@ -149,7 +149,7 @@ struct ctx_query { int cancelled; /** for async query, the callback function */ - ub_callback_t cb; + ub_callback_type cb; /** for async query, the callback user arg */ void* cb_arg; @@ -242,7 +242,7 @@ void context_query_delete(struct ctx_query* q); * @return new ctx_query or NULL for malloc failure. */ struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype, - int rrclass, ub_callback_t cb, void* cbarg); + int rrclass, ub_callback_type cb, void* cbarg); /** * Get a new alloc. Creates a new one or uses a cached one. diff --git a/external/unbound/libunbound/libunbound.c b/external/unbound/libunbound/libunbound.c index 17f50e8e8..eaa31c71c 100644 --- a/external/unbound/libunbound/libunbound.c +++ b/external/unbound/libunbound/libunbound.c @@ -57,6 +57,7 @@ #include "util/random.h" #include "util/net_help.h" #include "util/tube.h" +#include "util/ub_event.h" #include "services/modstack.h" #include "services/localzone.h" #include "services/cache/infra.h" @@ -131,6 +132,15 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) errno = ENOMEM; return NULL; } + /* init edns_known_options */ + if(!edns_known_options_init(ctx->env)) { + config_delete(ctx->env->cfg); + free(ctx->env); + ub_randfree(ctx->seed_rnd); + free(ctx); + errno = ENOMEM; + return NULL; + } ctx->env->alloc = &ctx->superalloc; ctx->env->worker = NULL; ctx->env->need_to_validate = 0; @@ -150,6 +160,7 @@ ub_ctx_create(void) ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); modstack_desetup(&ctx->mods, ctx->env); + edns_known_options_delete(ctx->env); free(ctx->env); free(ctx); errno = e; @@ -161,6 +172,7 @@ ub_ctx_create(void) ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); modstack_desetup(&ctx->mods, ctx->env); + edns_known_options_delete(ctx->env); free(ctx->env); free(ctx); errno = e; @@ -170,6 +182,20 @@ ub_ctx_create(void) } struct ub_ctx* +ub_ctx_create_ub_event(struct ub_event_base* ueb) +{ + struct ub_ctx* ctx = ub_ctx_create_nopipe(); + if(!ctx) + return NULL; + /* no pipes, but we have the locks to make sure everything works */ + ctx->created_bg = 0; + ctx->dothread = 1; /* the processing is in the same process, + makes ub_cancel and ub_ctx_delete do the right thing */ + ctx->event_base = ueb; + return ctx; +} + +struct ub_ctx* ub_ctx_create_event(struct event_base* eb) { struct ub_ctx* ctx = ub_ctx_create_nopipe(); @@ -179,13 +205,17 @@ ub_ctx_create_event(struct event_base* eb) ctx->created_bg = 0; ctx->dothread = 1; /* the processing is in the same process, makes ub_cancel and ub_ctx_delete do the right thing */ - ctx->event_base = eb; + ctx->event_base = ub_libevent_event_base(eb); + if (!ctx->event_base) { + ub_ctx_delete(ctx); + return NULL; + } return ctx; } /** delete q */ static void -delq(rbnode_t* n, void* ATTR_UNUSED(arg)) +delq(rbnode_type* n, void* ATTR_UNUSED(arg)) { struct ctx_query* q = (struct ctx_query*)n; context_query_delete(q); @@ -279,6 +309,7 @@ ub_ctx_delete(struct ub_ctx* ctx) rrset_cache_delete(ctx->env->rrset_cache); infra_delete(ctx->env->infra_cache); config_delete(ctx->env->cfg); + edns_known_options_delete(ctx->env); free(ctx->env); } ub_randfree(ctx->seed_rnd); @@ -468,7 +499,7 @@ ub_fd(struct ub_ctx* ctx) /** process answer from bg worker */ static int process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len, - ub_callback_t* cb, void** cbarg, int* err, + ub_callback_type* cb, void** cbarg, int* err, struct ub_result** res) { struct ctx_query* q; @@ -535,7 +566,7 @@ static int process_answer(struct ub_ctx* ctx, uint8_t* msg, uint32_t len) { int err; - ub_callback_t cb; + ub_callback_type cb; void* cbarg; struct ub_result* res; int r; @@ -578,7 +609,7 @@ int ub_wait(struct ub_ctx* ctx) { int err; - ub_callback_t cb; + ub_callback_type cb; void* cbarg; struct ub_result* res; int r; @@ -674,7 +705,8 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, - int rrclass, void* mydata, ub_event_callback_t callback, int* async_id) + int rrclass, void* mydata, ub_event_callback_type callback, + int* async_id) { struct ctx_query* q; int r; @@ -698,8 +730,11 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, } } + /* set time in case answer comes from cache */ + ub_comm_base_now(ctx->event_worker->base); + /* create new ctx_query and attempt to add to the list */ - q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback, + q = context_new(ctx, name, rrtype, rrclass, (ub_callback_type)callback, mydata); if(!q) return UB_NOMEM; @@ -713,7 +748,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype, - int rrclass, void* mydata, ub_callback_t callback, int* async_id) + int rrclass, void* mydata, ub_callback_type callback, int* async_id) { struct ctx_query* q; uint8_t* msg = NULL; @@ -924,6 +959,88 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) return UB_NOERROR; } +int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr, + int isprime) +{ + char* a; + struct config_stub **prev, *elem; + + /* check syntax for zone name */ + if(zone) { + uint8_t* nm; + int nmlabs; + size_t nmlen; + if(!parse_dname(zone, &nm, &nmlen, &nmlabs)) { + errno=EINVAL; + return UB_SYNTAX; + } + free(nm); + } else { + zone = "."; + } + + /* check syntax for addr (if not NULL) */ + if(addr) { + struct sockaddr_storage storage; + socklen_t stlen; + if(!extstrtoaddr(addr, &storage, &stlen)) { + errno=EINVAL; + return UB_SYNTAX; + } + } + + lock_basic_lock(&ctx->cfglock); + if(ctx->finalized) { + lock_basic_unlock(&ctx->cfglock); + errno=EINVAL; + return UB_AFTERFINAL; + } + + /* arguments all right, now find or add the stub */ + prev = &ctx->env->cfg->stubs; + elem = cfg_stub_find(&prev, zone); + if(!elem && !addr) { + /* not found and we want to delete, nothing to do */ + lock_basic_unlock(&ctx->cfglock); + return UB_NOERROR; + } else if(elem && !addr) { + /* found, and we want to delete */ + *prev = elem->next; + config_delstub(elem); + lock_basic_unlock(&ctx->cfglock); + return UB_NOERROR; + } else if(!elem) { + /* not found, create the stub entry */ + elem=(struct config_stub*)calloc(1, sizeof(struct config_stub)); + if(elem) elem->name = strdup(zone); + if(!elem || !elem->name) { + free(elem); + lock_basic_unlock(&ctx->cfglock); + errno = ENOMEM; + return UB_NOMEM; + } + elem->next = ctx->env->cfg->stubs; + ctx->env->cfg->stubs = elem; + } + + /* add the address to the list and set settings */ + elem->isprime = isprime; + a = strdup(addr); + if(!a) { + lock_basic_unlock(&ctx->cfglock); + errno = ENOMEM; + return UB_NOMEM; + } + if(!cfg_strlist_insert(&elem->addrs, a)) { + lock_basic_unlock(&ctx->cfglock); + free(a); + errno = ENOMEM; + return UB_NOMEM; + } + lock_basic_unlock(&ctx->cfglock); + return UB_NOERROR; +} + int ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname) { @@ -1241,10 +1358,12 @@ const char* ub_version(void) int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) { + struct ub_event_base* new_base; + if (!ctx || !ctx->event_base || !base) { return UB_INITFAIL; } - if (ctx->event_base == base) { + if (ub_libevent_get_event_base(ctx->event_base) == base) { /* already set */ return UB_NOERROR; } @@ -1253,9 +1372,11 @@ ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) { /* destroy the current worker - safe to pass in NULL */ libworker_delete_event(ctx->event_worker); ctx->event_worker = NULL; - ctx->event_base = base; + new_base = ub_libevent_event_base(base); + if (new_base) + ctx->event_base = new_base; ctx->created_bg = 0; ctx->dothread = 1; lock_basic_unlock(&ctx->cfglock); - return UB_NOERROR; + return new_base ? UB_NOERROR : UB_INITFAIL; } diff --git a/external/unbound/libunbound/libworker.c b/external/unbound/libunbound/libworker.c index 72b615313..b42ba0bd8 100644 --- a/external/unbound/libunbound/libworker.c +++ b/external/unbound/libunbound/libworker.c @@ -119,7 +119,7 @@ libworker_delete_event(struct libworker* w) /** setup fresh libworker struct */ static struct libworker* -libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb) +libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) { unsigned int seed; struct libworker* w = (struct libworker*)calloc(1, sizeof(*w)); @@ -232,6 +232,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb) cfg->do_tcp?cfg->outgoing_num_tcp:0, w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id, ports, numports, cfg->unwanted_threshold, + cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w, cfg->do_udp, w->sslctx, cfg->delay_close, NULL); if(!w->is_bg || w->is_bg_thread) { @@ -257,7 +258,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb) } struct libworker* libworker_create_event(struct ub_ctx* ctx, - struct event_base* eb) + struct ub_event_base* eb) { return libworker_setup(ctx, 0, eb); } @@ -572,14 +573,17 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q, { qinfo->qtype = (uint16_t)q->res->qtype; qinfo->qclass = (uint16_t)q->res->qclass; + qinfo->local_alias = NULL; qinfo->qname = sldns_str2wire_dname(q->res->qname, &qinfo->qname_len); if(!qinfo->qname) { return 0; } + qinfo->local_alias = NULL; edns->edns_present = 1; edns->ext_rcode = 0; edns->edns_version = 0; edns->bits = EDNS_DO; + edns->opt_list = NULL; if(sldns_buffer_capacity(w->back->udp_buff) < 65535) edns->udp_size = (uint16_t)sldns_buffer_capacity( w->back->udp_buff); @@ -605,8 +609,9 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) /* see if there is a fixed answer */ sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); - if(local_zones_answer(ctx->local_zones, &qinfo, &edns, - w->back->udp_buff, w->env->scratch, NULL)) { + if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns, + w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0, + NULL, 0, NULL, 0, NULL)) { regional_free_all(w->env->scratch); libworker_fillup_fg(q, LDNS_RCODE_NOERROR, w->back->udp_buff, sec_status_insecure, NULL); @@ -634,7 +639,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, char* why_bogus) { struct ctx_query* q = (struct ctx_query*)arg; - ub_event_callback_t cb = (ub_event_callback_t)q->cb; + ub_event_callback_type cb = (ub_event_callback_type)q->cb; void* cb_arg = q->cb_arg; int cancelled = q->cancelled; @@ -675,8 +680,9 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, /* see if there is a fixed answer */ sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); - if(local_zones_answer(ctx->local_zones, &qinfo, &edns, - w->back->udp_buff, w->env->scratch, NULL)) { + if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns, + w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0, + NULL, 0, NULL, 0, NULL)) { regional_free_all(w->env->scratch); free(qinfo.qname); libworker_event_done_cb(q, LDNS_RCODE_NOERROR, @@ -795,8 +801,9 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) /* see if there is a fixed answer */ sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); - if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns, - w->back->udp_buff, w->env->scratch, NULL)) { + if(local_zones_answer(w->ctx->local_zones, w->env, &qinfo, &edns, + w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0, + NULL, 0, NULL, 0, NULL)) { regional_free_all(w->env->scratch); q->msg_security = sec_status_insecure; add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL); @@ -819,11 +826,10 @@ void libworker_alloc_cleanup(void* arg) slabhash_clear(w->env->msg_cache); } -struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen, - uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, - int want_dnssec, int nocaps, struct sockaddr_storage* addr, - socklen_t addrlen, uint8_t* zone, size_t zonelen, - struct module_qstate* q) +struct outbound_entry* libworker_send_query(struct query_info* qinfo, + uint16_t flags, int dnssec, int want_dnssec, int nocaps, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, int ssl_upstream, struct module_qstate* q) { struct libworker* w = (struct libworker*)q->env->worker; struct outbound_entry* e = (struct outbound_entry*)regional_alloc( @@ -831,11 +837,10 @@ struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen, if(!e) return NULL; e->qstate = q; - e->qsent = outnet_serviced_query(w->back, qname, - qnamelen, qtype, qclass, flags, dnssec, want_dnssec, nocaps, - q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, addr, - addrlen, zone, zonelen, libworker_handle_service_reply, e, - w->back->udp_buff); + e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec, + want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream, + addr, addrlen, zone, zonelen, q, libworker_handle_service_reply, + e, w->back->udp_buff, q->env); if(!e->qsent) { return NULL; } @@ -950,13 +955,12 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg)) log_assert(0); } -struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname), - size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype), - uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags), - int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), - int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), - socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), - size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q)) +struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo), + uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), + int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), + struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), + uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), + int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q)) { log_assert(0); return 0; diff --git a/external/unbound/libunbound/libworker.h b/external/unbound/libunbound/libworker.h index 0103b5d88..b546e89f2 100644 --- a/external/unbound/libunbound/libworker.h +++ b/external/unbound/libunbound/libworker.h @@ -1,5 +1,5 @@ /* - * libunbound/worker.h - worker thread or process that resolves + * libunbound/libworker.h - worker thread or process that resolves * * Copyright (c) 2007, NLnet Labs. All rights reserved. * @@ -58,7 +58,8 @@ struct comm_reply; struct regional; struct tube; struct sldns_buffer; -struct event_base; +struct ub_event_base; +struct query_info; /** * The library-worker status structure @@ -115,7 +116,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q); * @return new worker or NULL. */ struct libworker* libworker_create_event(struct ub_ctx* ctx, - struct event_base* eb); + struct ub_event_base* eb); /** * Attach context_query to mesh for callback in event-driven setup. diff --git a/external/unbound/libunbound/python/doc/conf.py b/external/unbound/libunbound/python/doc/conf.py index 97fca2125..1766036b9 100644 --- a/external/unbound/libunbound/python/doc/conf.py +++ b/external/unbound/libunbound/python/doc/conf.py @@ -82,10 +82,13 @@ pygments_style = 'sphinx' # Options for HTML output # ----------------------- +# The theme that the html output should use. +html_theme = "classic" + # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. -html_style = 'default.css' +#html_style = 'default.css' # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". diff --git a/external/unbound/libunbound/python/doc/examples/example1a.rst b/external/unbound/libunbound/python/doc/examples/example1a.rst index 3c81547f2..f46cb92f4 100644 --- a/external/unbound/libunbound/python/doc/examples/example1a.rst +++ b/external/unbound/libunbound/python/doc/examples/example1a.rst @@ -1,26 +1,33 @@ .. _example_resolve_name: -============================== Resolve a name -============================== +============== -This basic example shows how to create a context and resolve a host address (DNS record of A type). +This basic example shows how to create a context and resolve a host address +(DNS record of A type). + +Source code +----------- :: - #!/usr/bin/python - import unbound - - ctx = unbound.ub_ctx() - ctx.resolvconf("/etc/resolv.conf") - - status, result = ctx.resolve("www.google.com") - if status == 0 and result.havedata: - print "Result.data:", result.data.address_list - elif status != 0: - print "Resolve error:", unbound.ub_strerror(status) - -In contrast with C API, the source code is more compact while the performance of C implementation is preserved. -The main advantage is that you need not take care about the deallocation and allocation of context and result structures; pyUnbound module do it automatically for you. - -If only domain name is given, the :meth:`unbound.ub_ctx.resolve` looks for A records in IN class. + #!/usr/bin/python + import unbound + + ctx = unbound.ub_ctx() + ctx.resolvconf("/etc/resolv.conf") + + status, result = ctx.resolve("www.google.com") + if status == 0 and result.havedata: + print "Result.data:", result.data.address_list + elif status != 0: + print "Resolve error:", unbound.ub_strerror(status) + +In contrast with the C API, the source code is more compact while the +performance of C implementation is preserved. +The main advantage is that you need not take care about the deallocation and +allocation of context and result structures; pyUnbound module does it +automatically for you. + +If only domain name is given, the :meth:`unbound.ub_ctx.resolve` looks for +A records in IN class. diff --git a/external/unbound/libunbound/python/doc/examples/example1b.rst b/external/unbound/libunbound/python/doc/examples/example1b.rst index ea1e6f57d..1adae2cb1 100644 --- a/external/unbound/libunbound/python/doc/examples/example1b.rst +++ b/external/unbound/libunbound/python/doc/examples/example1b.rst @@ -1,33 +1,37 @@ .. _example_reverse_lookup: -============================== Reverse DNS lookup -============================== +================== -Reverse DNS lookup involves determining the hostname associated with a given IP address. +Reverse DNS lookup involves determining the hostname associated with a given IP +address. This example shows how reverse lookup can be done using unbound module. For the reverse DNS records, the special domain in-addr.arpa is reserved. -For example, a host name for the IP address 74.125.43.147 can be obtained by issuing a DNS query for the PTR record for address 147.43.125.74.in-addr.arpa. +For example, a host name for the IP address ``74.125.43.147`` can be obtained +by issuing a DNS query for the PTR record for address +``147.43.125.74.in-addr.arpa.`` + +Source code +----------- :: - #!/usr/bin/python - import unbound - - ctx = unbound.ub_ctx() - ctx.resolvconf("/etc/resolv.conf") - - status, result = ctx.resolve(unbound.reverse("74.125.43.147") + ".in-addr.arpa.", unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN) - if status == 0 and result.havedata: - print "Result.data:", result.data.domain_list - elif status != 0: - print "Resolve error:", unbound.ub_strerror(status) - -In order to simplify the python code, unbound module contains function which reverses the hostname components. -This function is defined as follows:: + #!/usr/bin/python + import unbound - def reverse(domain): - return '.'.join([a for a in domain.split(".")][::-1]) + ctx = unbound.ub_ctx() + ctx.resolvconf("/etc/resolv.conf") + status, result = ctx.resolve(unbound.reverse("74.125.43.147") + ".in-addr.arpa.", unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN) + if status == 0 and result.havedata: + print "Result.data:", result.data.domain_list + elif status != 0: + print "Resolve error:", unbound.ub_strerror(status) + +In order to simplify the python code, unbound module contains the +:meth:`unbound.reverse` function which reverses the hostname components. +This function is defined as follows:: + def reverse(domain): + return '.'.join([a for a in domain.split(".")][::-1]) diff --git a/external/unbound/libunbound/python/doc/examples/example2.rst b/external/unbound/libunbound/python/doc/examples/example2.rst index c009ec1f5..a2bf2cbf5 100644 --- a/external/unbound/libunbound/python/doc/examples/example2.rst +++ b/external/unbound/libunbound/python/doc/examples/example2.rst @@ -1,41 +1,41 @@ .. _example_setup_ctx: -============================== Lookup from threads -============================== +=================== -This example shows how to use unbound module from a threaded program. -In this example, three lookup threads are created which work in background. -Each thread resolves different DNS record. +This example shows how to use unbound module from a threaded program. +In this example, three lookup threads are created which work in background. +Each thread resolves different DNS record. + +Source code +----------- :: - #!/usr/bin/python - from unbound import ub_ctx, RR_TYPE_A, RR_CLASS_IN - from threading import Thread - - ctx = ub_ctx() - ctx.resolvconf("/etc/resolv.conf") - - class LookupThread(Thread): - def __init__(self,ctx, name): - Thread.__init__(self) - self.ctx = ctx - self.name = name - - def run(self): - print "Thread lookup started:",self.name - status, result = self.ctx.resolve(self.name, RR_TYPE_A, RR_CLASS_IN) - if status == 0 and result.havedata: - print " Result:",self.name,":", result.data.address_list - - threads = [] - for name in ["www.fit.vutbr.cz","www.vutbr.cz","www.google.com"]: - thread = LookupThread(ctx, name) - thread.start() - threads.append(thread) - - for thread in threads: - thread.join() + #!/usr/bin/python + from unbound import ub_ctx, RR_TYPE_A, RR_CLASS_IN + from threading import Thread + + ctx = ub_ctx() + ctx.resolvconf("/etc/resolv.conf") + + class LookupThread(Thread): + def __init__(self,ctx, name): + Thread.__init__(self) + self.ctx = ctx + self.name = name + + def run(self): + print "Thread lookup started:",self.name + status, result = self.ctx.resolve(self.name, RR_TYPE_A, RR_CLASS_IN) + if status == 0 and result.havedata: + print " Result:",self.name,":", result.data.address_list + threads = [] + for name in ["www.fit.vutbr.cz","www.vutbr.cz","www.google.com"]: + thread = LookupThread(ctx, name) + thread.start() + threads.append(thread) + for thread in threads: + thread.join() diff --git a/external/unbound/libunbound/python/doc/examples/example3.rst b/external/unbound/libunbound/python/doc/examples/example3.rst index 91360335c..b0626b55f 100644 --- a/external/unbound/libunbound/python/doc/examples/example3.rst +++ b/external/unbound/libunbound/python/doc/examples/example3.rst @@ -1,12 +1,14 @@ .. _example_asynch: -============================== Asynchronous lookup -============================== +=================== This example performs the name lookup in the background. The main program keeps running while the name is resolved. +Source code +----------- + :: #!/usr/bin/python @@ -33,4 +35,5 @@ The main program keeps running while the name is resolved. if (status != 0): print "Resolve error:", unbound.ub_strerror(status) -The :meth:`unbound.ub_ctx.resolve_async` method is able to pass on any Python object. In this example, we used a dictionary object `my_data`. +The :meth:`unbound.ub_ctx.resolve_async` method is able to pass on any Python +object. In this example, we used a dictionary object ``my_data``. diff --git a/external/unbound/libunbound/python/doc/examples/example4.rst b/external/unbound/libunbound/python/doc/examples/example4.rst index 996ef4ede..3b43eb85f 100644 --- a/external/unbound/libunbound/python/doc/examples/example4.rst +++ b/external/unbound/libunbound/python/doc/examples/example4.rst @@ -1,33 +1,35 @@ .. _example_examine: -============================== DNSSEC validator -============================== +================ This example program performs DNSSEC validation of a DNS lookup. +Source code +----------- + :: - #!/usr/bin/python - import os - from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN - - ctx = ub_ctx() - ctx.resolvconf("/etc/resolv.conf") - if (os.path.isfile("keys")): - ctx.add_ta_file("keys") #read public keys for DNSSEC verification - - status, result = ctx.resolve("www.nic.cz", RR_TYPE_A, RR_CLASS_IN) - if status == 0 and result.havedata: - - print "Result:", result.data.address_list - - if result.secure: - print "Result is secure" - elif result.bogus: - print "Result is bogus" - else: - print "Result is insecure" + #!/usr/bin/python + import os + from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN + + ctx = ub_ctx() + ctx.resolvconf("/etc/resolv.conf") + if (os.path.isfile("keys")): + ctx.add_ta_file("keys") #read public keys for DNSSEC verification + + status, result = ctx.resolve("www.nic.cz", RR_TYPE_A, RR_CLASS_IN) + if status == 0 and result.havedata: + + print "Result:", result.data.address_list + + if result.secure: + print "Result is secure" + elif result.bogus: + print "Result is bogus" + else: + print "Result is insecure" More detailed informations can be seen in libUnbound DNSSEC tutorial `here`_. diff --git a/external/unbound/libunbound/python/doc/examples/example5.rst b/external/unbound/libunbound/python/doc/examples/example5.rst index 0a31d9a57..9262014bb 100644 --- a/external/unbound/libunbound/python/doc/examples/example5.rst +++ b/external/unbound/libunbound/python/doc/examples/example5.rst @@ -1,13 +1,17 @@ .. _example_resolver_only: -============================== Resolver only -============================== +============= This example program shows how to perform DNS resolution only. Unbound contains two basic modules: resolver and validator. -In case, the validator is not necessary, the validator module can be turned off using "module-config" option. -This option contains a list of module names separated by the space char. This list determined which modules should be employed and in what order. +In case, the validator is not necessary, the validator module can be turned off +using "module-config" option. +This option contains a list of module names separated by the space char. This +list determined which modules should be employed and in what order. + +Source code +----------- :: @@ -25,5 +29,6 @@ This option contains a list of module names separated by the space char. This li print "Result:", result.data.address_list .. note:: - The :meth:`unbound.ub_ctx.set_option` method must be used before the first resolution (i.e. before :meth:`unbound.ub_ctx.resolve` or :meth:`unbound.ub_ctx.resolve_async` call). - + The :meth:`unbound.ub_ctx.set_option` method must be used before the first + resolution (i.e. before :meth:`unbound.ub_ctx.resolve` or + :meth:`unbound.ub_ctx.resolve_async` call). diff --git a/external/unbound/libunbound/python/doc/examples/example6.rst b/external/unbound/libunbound/python/doc/examples/example6.rst index 478e13909..6fde8b25f 100644 --- a/external/unbound/libunbound/python/doc/examples/example6.rst +++ b/external/unbound/libunbound/python/doc/examples/example6.rst @@ -1,11 +1,13 @@ .. _example_localzone: -============================== Local zone manipulation -============================== +======================= -This example program shows how to define local zone containing custom DNS records. +This example program shows how to define local zone containing custom DNS +records. -.. literalinclude:: example6-1.py - :language: python +Source code +----------- +.. literalinclude:: example6-1.py + :language: python diff --git a/external/unbound/libunbound/python/doc/examples/example7.rst b/external/unbound/libunbound/python/doc/examples/example7.rst index d4050215e..2f48c8f0f 100644 --- a/external/unbound/libunbound/python/doc/examples/example7.rst +++ b/external/unbound/libunbound/python/doc/examples/example7.rst @@ -1,18 +1,33 @@ .. _example_idna: -================================================= Internationalized domain name support -================================================= +===================================== Unlike the libUnbound, pyUnbound is able to handle IDN queries. -.. literalinclude:: example7-1.py - :language: python +Automatic IDN DNAME conversion +------------------------------- -If we use unicode string in :meth:`unbound.ub_ctx.resolve` method, the IDN DNAME conversion (if it is necessary) is performed on background. +If we use unicode string in :meth:`unbound.ub_ctx.resolve` method, +the IDN DNAME conversion (if it is necessary) is performed on background. -.. literalinclude:: example7-2.py - :language: python +Source code +........... -The :class:`unbound.ub_data` class contains attributes suffix which converts the dname to UTF string. These attributes have the '_idn' suffix. -Apart from this aproach, two conversion functions exist (:func:`unbound.idn2dname` and :func:`unbound.dname2idn`). +.. literalinclude:: example7-1.py + :language: python + +IDN converted attributes +------------------------ + +The :class:`unbound.ub_data` class contains attributes suffix which converts +the dname to UTF string. These attributes have the ``_idn`` suffix. + +Apart from this aproach, two conversion functions exist +(:func:`unbound.idn2dname` and :func:`unbound.dname2idn`). + +Source code +........... + +.. literalinclude:: example7-2.py + :language: python diff --git a/external/unbound/libunbound/python/doc/examples/example8.rst b/external/unbound/libunbound/python/doc/examples/example8.rst index 8cdfcdc0a..16c140475 100644 --- a/external/unbound/libunbound/python/doc/examples/example8.rst +++ b/external/unbound/libunbound/python/doc/examples/example8.rst @@ -1,28 +1,34 @@ .. _example_mxlookup: -================================================= Lookup for MX and NS records -================================================= +============================ -The pyUnbound extension provides functions which are able to encode RAW RDATA produces by unbound resolver (see :class:`unbound.ub_data`). +The pyUnbound extension provides functions which are able to encode RAW RDATA +produces by unbound resolver (see :class:`unbound.ub_data`). -.. literalinclude:: example8-1.py - :language: python +Source code +----------- -Previous example produces following output:: +.. literalinclude:: example8-1.py + :language: python - Result: - raw data: 00 0F 05 6D 61 69 6C 34 03 6E 69 63 02 63 7A 00;00 14 02 6D 78 05 63 7A 6E 69 63 03 6F 72 67 00;00 0A 04 6D 61 69 6C 03 6E 69 63 02 63 7A 00 - priority:15 address: mail4.nic.cz. - priority:20 address: mx.cznic.org. - priority:10 address: mail.nic.cz. +Output +------ - Result: - raw data: D9 1F CD 32 - address: 217.31.205.50 +The previous example produces the following output:: - Result: - raw data: 01 61 02 6E 73 03 6E 69 63 02 63 7A 00;01 65 02 6E 73 03 6E 69 63 02 63 7A 00;01 63 02 6E 73 03 6E 69 63 02 63 7A 00 - host: a.ns.nic.cz. - host: e.ns.nic.cz. - host: c.ns.nic.cz. + Result: + raw data: 00 0F 05 6D 61 69 6C 34 03 6E 69 63 02 63 7A 00;00 14 02 6D 78 05 63 7A 6E 69 63 03 6F 72 67 00;00 0A 04 6D 61 69 6C 03 6E 69 63 02 63 7A 00 + priority:15 address: mail4.nic.cz. + priority:20 address: mx.cznic.org. + priority:10 address: mail.nic.cz. + + Result: + raw data: D9 1F CD 32 + address: 217.31.205.50 + + Result: + raw data: 01 61 02 6E 73 03 6E 69 63 02 63 7A 00;01 65 02 6E 73 03 6E 69 63 02 63 7A 00;01 63 02 6E 73 03 6E 69 63 02 63 7A 00 + host: a.ns.nic.cz. + host: e.ns.nic.cz. + host: c.ns.nic.cz. diff --git a/external/unbound/libunbound/python/doc/examples/index.rst b/external/unbound/libunbound/python/doc/examples/index.rst index c2c9cf457..283261652 100644 --- a/external/unbound/libunbound/python/doc/examples/index.rst +++ b/external/unbound/libunbound/python/doc/examples/index.rst @@ -1,14 +1,16 @@ Examples -============================== +======== -Here you can find several examples which utilizes the unbound library in Python environment. -Unbound is a caching validator and resolver and can be linked into an application, as a library where can answer DNS queries for the application. +Here you can find several examples which utilizes the unbound library in Python +environment. Unbound is a caching validator and resolver and can be linked into +an application, as a library where can answer DNS queries for the application. This set of examples shows how to use the functions from Python environment. -`Tutorials` +Tutorials +--------- .. toctree:: - :maxdepth: 1 - :glob: + :maxdepth: 1 + :glob: - example* + example* diff --git a/external/unbound/libunbound/python/doc/install.rst b/external/unbound/libunbound/python/doc/install.rst index a073a5c66..bb3118984 100644 --- a/external/unbound/libunbound/python/doc/install.rst +++ b/external/unbound/libunbound/python/doc/install.rst @@ -1,31 +1,38 @@ Installation -=================================== +============ -**Prerequisites** +Prerequisites +------------- Python 2.4 or higher, SWIG 1.3 or higher, GNU make -**Compiling** +Compiling +--------- After downloading, you can compile the pyUnbound library by doing:: - > tar -xzf unbound-x.x.x-py.tar.gz - > cd unbound-x.x.x - > ./configure --with-pyunbound - > make + > tar -xzf unbound-x.x.x-py.tar.gz + > cd unbound-x.x.x + > ./configure --with-pyunbound + > make -You may want to --with-pythonmodule as well if you want to use python as -a module in the resolver. +You may want to enable ``--with-pythonmodule`` as well if you want to use +python as a module in the resolver. -You need GNU make to compile sources; SWIG and Python devel libraries to compile extension module. +You need ``GNU make`` to compile sources; ``SWIG`` and ``Python devel`` +libraries to compile extension module. -**Testing** +Testing +------- -If the compilation is successful, you can test the python LDNS extension module by:: +If the compilation is successful, you can test the python LDNS extension module +by:: - > cd contrib/python - > make testenv - > ./dns-lookup.py + > cd contrib/python + > make testenv + > ./dns-lookup.py -You may want to make install in the main directory since make testenv is for debugging. In contrib/examples you can find simple applications written in Python using the Unbound extension. +You may want to ``make install`` in the main directory since ``make testenv`` +is for debugging. In contrib/examples you can find simple applications written +in Python using the Unbound extension. diff --git a/external/unbound/libunbound/python/doc/intro.rst b/external/unbound/libunbound/python/doc/intro.rst index f751f54c0..e490d2c6f 100644 --- a/external/unbound/libunbound/python/doc/intro.rst +++ b/external/unbound/libunbound/python/doc/intro.rst @@ -1,39 +1,58 @@ Introduction -=================================== - -**Unbound** - - `Unbound`_ is an implementation of a DNS resolver, that performs caching and DNSSEC validation. - Together with unbound, the libunbound library is provided. - This library can be used to convert hostnames to ip addresses, and back, as well as obtain other information. - Since the resolver allows to specify the class and type of a query (A record, NS, MX, ...), this library offers powerful resolving tool. - The library also performs public-key validation of results with DNSSEC. - - .. _Unbound: http://www.unbound.net/documentation - -**pyUnbound** - - The pyUnbound is an extension module for Python which provides an object-oriented interface to libunbound. - It is the first Python module which offers thread-safe caching resolver. - - The interface was designed with the emphasis on the simplicity of use. - There are two main classes :class:`unbound.ub_ctx` (a validation and resolution context) and :class:`unbound.ub_result` which contains the validation and resolution results. - The objects are thread-safe, and a context can be used in non-threaded as well as threaded environment. - Resolution can be performed blocking and non-blocking (i.e. asynchronous). - The asynchronous method returns from the call immediately, so that processing can go on, while the results become available later. - -**Features** - * customizable caching validation resolver for synchronous and asynchronous lookups - * easy to use object interface - * easy to integrate extension module - * designed for thread environment (i.e. thread-safe) - * allows define and customize of local zone and its RR's during the operation (i.e. without restart) - * includes encoding functions to simplify the results retrieval - * Internationalized domain name (`IDN`_) support - - .. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name - -**Application area** - * DNS-based applications performing DNS lookups; the caching resolver can reduce overhead - * Applications where the validation of DNS records is required - * Great solution for customizable and dynamic DNS-based white/blacklists (spam rejection, connection rejection, ...) using the dynamic local zone manipulation +============ + +Unbound +------- + +`Unbound`_ is an implementation of a DNS resolver, that performs caching and +DNSSEC validation. +Together with unbound, the libunbound library is provided. +This library can be used to convert hostnames to ip addresses, and back, as +well as obtain other information. +Since the resolver allows to specify the class and type of a query (A record, +NS, MX, ...), this library offers powerful resolving tool. +The library also performs public-key validation of results with DNSSEC. + +.. _Unbound: http://www.unbound.net/documentation + +pyUnbound +--------- + +The pyUnbound is an extension module for Python which provides an +object-oriented interface to libunbound. +It is the first Python module which offers thread-safe caching resolver. + +The interface was designed with the emphasis on the simplicity of use. +There are two main classes :class:`unbound.ub_ctx` (a validation and resolution +context) and :class:`unbound.ub_result` which contains the validation and +resolution results. +The objects are thread-safe, and a context can be used in non-threaded as well +as threaded environment. +Resolution can be performed blocking and non-blocking (i.e. asynchronous). +The asynchronous method returns from the call immediately, so that processing +can go on, while the results become available later. + +Features +-------- + +* Customizable caching validation resolver for synchronous and asynchronous + lookups +* Easy to use object interface +* Easy to integrate extension module +* Designed for thread environment (i.e. thread-safe) +* Allows define and customize of local zone and its RR's during the operation + (i.e. without restart) +* Includes encoding functions to simplify the results retrieval +* Internationalized domain name (`IDN`_) support + +.. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name + +Application area +---------------- + +* DNS-based applications performing DNS lookups; the caching resolver can + reduce overhead +* Applications where the validation of DNS records is required +* Great solution for customizable and dynamic DNS-based white/blacklists (spam + rejection, connection rejection, ...) using the dynamic local zone + manipulation diff --git a/external/unbound/libunbound/python/libunbound.i b/external/unbound/libunbound/python/libunbound.i index 50a9b67ac..84a536929 100644 --- a/external/unbound/libunbound/python/libunbound.i +++ b/external/unbound/libunbound/python/libunbound.i @@ -945,7 +945,7 @@ int _ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, v :param idnname: (unicode string) IDN name :returns: (string) domain name """ - return '.'.join([encodings.idna.ToASCII(a) for a in idnname.split('.')]) + return '.'.join([encodings.idna.ToASCII(a) if a else '' for a in idnname.split('.')]) def dname2idn(name): """Converts canonic domain name in IDN format to unicode string diff --git a/external/unbound/libunbound/ubsyms.def b/external/unbound/libunbound/ubsyms.def index ff3d9587b..0d8e6af91 100644 --- a/external/unbound/libunbound/ubsyms.def +++ b/external/unbound/libunbound/ubsyms.def @@ -1,33 +1,35 @@ +ub_cancel +ub_ctx_add_ta +ub_ctx_add_ta_autr +ub_ctx_add_ta_file +ub_ctx_async +ub_ctx_config ub_ctx_create ub_ctx_create_event +ub_ctx_create_ub_event +ub_ctx_data_add +ub_ctx_data_remove +ub_ctx_debuglevel +ub_ctx_debugout ub_ctx_delete ub_ctx_get_option -ub_ctx_set_option -ub_ctx_config -ub_ctx_set_fwd -ub_ctx_resolvconf ub_ctx_hosts -ub_ctx_add_ta -ub_ctx_add_ta_autr -ub_ctx_add_ta_file +ub_ctx_print_local_zones +ub_ctx_resolvconf +ub_ctx_set_event +ub_ctx_set_fwd +ub_ctx_set_option +ub_ctx_set_stub ub_ctx_trustedkeys -ub_ctx_debugout -ub_ctx_debuglevel -ub_ctx_async -ub_poll -ub_wait +ub_ctx_zone_add +ub_ctx_zone_remove ub_fd +ub_poll ub_process ub_resolve ub_resolve_async ub_resolve_event -ub_cancel ub_resolve_free ub_strerror -ub_ctx_print_local_zones -ub_ctx_zone_add -ub_ctx_zone_remove -ub_ctx_data_add -ub_ctx_data_remove ub_version -ub_ctx_set_event +ub_wait diff --git a/external/unbound/libunbound/unbound-event.h b/external/unbound/libunbound/unbound-event.h index b80de38de..d5f0b1a36 100644 --- a/external/unbound/libunbound/unbound-event.h +++ b/external/unbound/libunbound/unbound-event.h @@ -36,20 +36,21 @@ /** * \file * - * This file contains the unbound interface for use with libevent. - * You have to use the same libevent that unbound was compiled with, - * otherwise it wouldn't work, the event and event_base structures would - * be different. If unbound is compiled without libevent support then - * this header file is not supposed to be installed on the system. + * This file contains the unbound interface for use with user defined + * pluggable event bases. * - * Use ub_ctx_create_event_base() to create an unbound context that uses - * the event base that you have made. Then, use the ub_resolve_event call - * to add DNS resolve queries to the context. Those then run when you - * call event_dispatch() on your event_base, and when they are done you - * get a function callback. + * Use ub_ctx_create_event_ub_base() to create an unbound context that uses + * the user provided event base API. Then, use the ub_resolve_event call + * to add DNS resolve queries to the context. Those then run whith the + * provided event_base, and when they are done you get a function callback. * * This method does not fork another process or create a thread, the effort - * is done by the unbound state machines that are connected to the event_base. + * is done by the unbound state machines that are connected to the event base. + * + * It is also possible to provide a libevent based event base by using + * ub_ctx_create_event_base(). But you have to use the same libevent that + * unbound was compiled with, otherwise it wouldn't work, the event and + * event_base structures would be different. */ #ifndef _UB_UNBOUND_EVENT_H #define _UB_UNBOUND_EVENT_H @@ -62,12 +63,136 @@ struct ub_ctx; struct ub_result; struct event_base; -typedef void (*ub_event_callback_t)(void*, int, void*, int, int, char*); +/** event timeout */ +#define UB_EV_TIMEOUT 0x01 +/** event fd readable */ +#define UB_EV_READ 0x02 +/** event fd writable */ +#define UB_EV_WRITE 0x04 +/** event signal */ +#define UB_EV_SIGNAL 0x08 +/** event must persist */ +#define UB_EV_PERSIST 0x10 + +/** magic number to identify this version of the pluggable event api */ +#define UB_EVENT_MAGIC 0x44d74d78 + +struct ub_event; +struct ub_event_base; +struct timeval; + +/** + * The Virtual Method Table for and ub_event_base "object" + */ +struct ub_event_base_vmt { + /** Destructor for the ub_event_base object, + * (not called by libunbound) */ + void (*free)(struct ub_event_base*); + /** Run the event loop + * (not called by libunbound when using ub_resolve_event) */ + int (*dispatch)(struct ub_event_base*); + /** Exit the given event loop */ + int (*loopexit)(struct ub_event_base*, struct timeval*); + /** Instantiate a new ub_event associated with this event base */ + struct ub_event* (*new_event)(struct ub_event_base*, + int fd, short bits, void (*cb)(int, short, void*), void* arg); + /** Instantiate a new signal associated with this event base, + * (not called by libunbound) */ + struct ub_event* (*new_signal)(struct ub_event_base*, int fd, + void (*cb)(int, short, void*), void* arg); + /** Create a new ub_event associated with the given wsaevent, + * (not called by libunbound) */ + struct ub_event* (*winsock_register_wsaevent)(struct ub_event_base*, + void* wsaevent, void (*cb)(int, short, void*), void* arg); +}; + +/** + * A user defined pluggable event base is registered by providing a + * ub_event_base "object" with the ub_ctx_create_ub_event() function. + * The magic number must be correct and the Virtual Method Table must be + * fully equipped providing the event base API to be used by libunbound. + */ +struct ub_event_base { + /** magic must be UB_EVENT_MAGIC (0x44d74d78) */ + unsigned long magic; + /** Virtual Method Table for ub_event_base */ + struct ub_event_base_vmt* vmt; +}; + +/** + * The Virtual Method Table for and ub_event "object" + */ +struct ub_event_vmt { + /** Add event bits for this event to fire on. + * The event will be deactivated before this function is called. */ + void (*add_bits)(struct ub_event*, short); + /** Configure the event so it will not longer fire on given bits + * The event will be deactivated before this function is called. */ + void (*del_bits)(struct ub_event*, short); + /** Change or set the file descriptor on the event + * The event will be deactivated before this function is called. */ + void (*set_fd)(struct ub_event*, int); + /** Destructor for the ub_event object */ + void (*free)(struct ub_event*); + /** Activate the event. The given timeval is an timeout value. */ + int (*add)(struct ub_event*, struct timeval*); + /** Deactivate the event */ + int (*del)(struct ub_event*); + /** Reconfigure and activate a timeout event */ + int (*add_timer)(struct ub_event*, struct ub_event_base*, + void (*cb)(int, short, void*), void* arg, struct timeval*); + /** Deactivate the timeout event */ + int (*del_timer)(struct ub_event*); + /** Activate a signal event (not called by libunbound). */ + int (*add_signal)(struct ub_event*, struct timeval*); + /** Deactivate a signal event (not called by libunbound). */ + int (*del_signal)(struct ub_event*); + /** Destructor for a ub_event associated with a wsaevent, + * (not called by libunbound) + */ + void (*winsock_unregister_wsaevent)(struct ub_event* ev); + /** Libunbound will signal the eventloop when a TCP windows socket + * will block on next read or write (given by the eventbits), to work + * around edge trigger event behaviour of select on windows with TCP. + */ + void (*winsock_tcp_wouldblock)(struct ub_event*, int eventbit); +}; + +/** + * An "object" comprising a user defined pluggable event. + * The magic number must be correct and the Virtual Method Table must be + * fully equipped providing the ub_event API to be used by libunbound. + */ +struct ub_event { + /** magic must be UB_EVENT_MAGIC (0x44d74d78) */ + unsigned long magic; + /** Virtual Method Table for ub_event */ + struct ub_event_vmt* vmt; +}; + +typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*); + +/** + * Create a resolving and validation context. + * The information from /etc/resolv.conf and /etc/hosts is not utilised by + * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them. + * @param base: the pluggable event base that the caller has created. + * The unbound context uses this event base. + * @return a new context. default initialisation. + * returns NULL on error. + * You must use ub_resolve_event with this context. + * Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done + * with the event_base. Setup the options you like with the other functions. + */ +struct ub_ctx* ub_ctx_create_ub_event(struct ub_event_base* base); /** * Create a resolving and validation context. * The information from /etc/resolv.conf and /etc/hosts is not utilised by * default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them. + * You have to use the same libevent that unbound was compiled with, + * otherwise it wouldn't work, the event and event_base structures would + * be different. * @param base: the event base that the caller has created. The unbound * context uses this event base. * @return a new context. default initialisation. @@ -79,7 +204,10 @@ typedef void (*ub_event_callback_t)(void*, int, void*, int, int, char*); struct ub_ctx* ub_ctx_create_event(struct event_base* base); /** - * Set a new event_base on a context created with ub_ctx_create_event. + * Set a new libevent event_base on a context created with ub_ctx_create_event. + * You have to use the same libevent that unbound was compiled with, + * otherwise it wouldn't work, the event and event_base structures would + * be different. * Any outbound queries will be canceled. * @param ctx the ub_ctx to update. Must have been created with ub_ctx_create_event * @param base the new event_base to attach to the ctx @@ -126,7 +254,8 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base); * @return 0 if OK, else error. */ int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, - int rrclass, void* mydata, ub_event_callback_t callback, int* async_id); + int rrclass, void* mydata, ub_event_callback_type callback, + int* async_id); #ifdef __cplusplus } diff --git a/external/unbound/libunbound/unbound.h b/external/unbound/libunbound/unbound.h index fe903d0c5..fc744be4c 100644 --- a/external/unbound/libunbound/unbound.h +++ b/external/unbound/libunbound/unbound.h @@ -102,9 +102,9 @@ extern "C" { #endif /** the version of this header file */ -#define UNBOUND_VERSION_MAJOR @UNBOUND_VERSION_MAJOR@ -#define UNBOUND_VERSION_MINOR @UNBOUND_VERSION_MINOR@ -#define UNBOUND_VERSION_MICRO @UNBOUND_VERSION_MICRO@ +#define UNBOUND_VERSION_MAJOR 1 +#define UNBOUND_VERSION_MINOR 6 +#define UNBOUND_VERSION_MICRO 3 /** * The validation context is created to hold the resolver status, @@ -223,7 +223,7 @@ struct ub_result { * This structure is allocated on the heap and needs to be * freed with ub_resolve_free(result); */ -typedef void (*ub_callback_t)(void*, int, struct ub_result*); +typedef void (*ub_callback_type)(void*, int, struct ub_result*); /** * Create a resolving and validation context. @@ -304,6 +304,27 @@ int ub_ctx_config(struct ub_ctx* ctx, const char* fname); int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr); /** + * Add a stub zone, with given address to send to. This is for custom + * root hints or pointing to a local authoritative dns server. + * For dns resolvers and the 'DHCP DNS' ip address, use ub_ctx_set_fwd. + * This is similar to a stub-zone entry in unbound.conf. + * + * @param ctx: context. + * It is only possible to set configuration before the + * first resolve is done. + * @param zone: name of the zone, string. + * @param addr: address, IP4 or IP6 in string format. + * The addr is added to the list of stub-addresses if the entry exists. + * If the addr is NULL the stub entry is removed. + * @param isprime: set to true to set stub-prime to yes for the stub. + * For local authoritative servers, people usually set it to false, + * For root hints it should be set to true. + * @return 0 if OK, else error. + */ +int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr, + int isprime); + +/** * Read list of nameservers to use from the filename given. * Usually "/etc/resolv.conf". Uses those nameservers as caching proxies. * If they do not support DNSSEC, validation may fail. @@ -498,7 +519,7 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, * @return 0 if OK, else error. */ int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype, - int rrclass, void* mydata, ub_callback_t callback, int* async_id); + int rrclass, void* mydata, ub_callback_type callback, int* async_id); /** * Cancel an async query in progress. diff --git a/external/unbound/libunbound/worker.h b/external/unbound/libunbound/worker.h index a53150199..88e1cf799 100644 --- a/external/unbound/libunbound/worker.h +++ b/external/unbound/libunbound/worker.h @@ -48,13 +48,12 @@ struct comm_reply; struct comm_point; struct module_qstate; struct tube; +struct edns_option; +struct query_info; /** * Worker service routine to send serviced queries to authoritative servers. - * @param qname: query name. (host order) - * @param qnamelen: length in bytes of qname, including trailing 0. - * @param qtype: query type. (host order) - * @param qclass: query class. (host order) + * @param qinfo: query info. * @param flags: host order flags word, with opcode and CD bit. * @param dnssec: if set, EDNS record will have DO bit set. * @param want_dnssec: signatures needed. @@ -63,15 +62,15 @@ struct tube; * @param addrlen: length of addr. * @param zone: delegation point name. * @param zonelen: length of zone name wireformat dname. + * @param ssl_upstream: use SSL for upstream queries. * @param q: wich query state to reactivate upon return. * @return: false on failure (memory or socket related). no query was * sent. */ -struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen, - uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, - int want_dnssec, int nocaps, struct sockaddr_storage* addr, - socklen_t addrlen, uint8_t* zone, size_t zonelen, - struct module_qstate* q); +struct outbound_entry* libworker_send_query(struct query_info* qinfo, + uint16_t flags, int dnssec, int want_dnssec, int nocaps, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, int ssl_upstream, struct module_qstate* q); /** process incoming replies from the network */ int libworker_handle_reply(struct comm_point* c, void* arg, int error, @@ -106,10 +105,7 @@ void worker_sighandler(int sig, void* arg); /** * Worker service routine to send serviced queries to authoritative servers. - * @param qname: query name. (host order) - * @param qnamelen: length in bytes of qname, including trailing 0. - * @param qtype: query type. (host order) - * @param qclass: query class. (host order) + * @param qinfo: query info. * @param flags: host order flags word, with opcode and CD bit. * @param dnssec: if set, EDNS record will have DO bit set. * @param want_dnssec: signatures needed. @@ -118,15 +114,15 @@ void worker_sighandler(int sig, void* arg); * @param addrlen: length of addr. * @param zone: wireformat dname of the zone. * @param zonelen: length of zone name. + * @param ssl_upstream: use SSL for upstream queries. * @param q: wich query state to reactivate upon return. * @return: false on failure (memory or socket related). no query was * sent. */ -struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen, - uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, - int want_dnssec, int nocaps, struct sockaddr_storage* addr, - socklen_t addrlen, uint8_t* zone, size_t zonelen, - struct module_qstate* q); +struct outbound_entry* worker_send_query(struct query_info* qinfo, + uint16_t flags, int dnssec, int want_dnssec, int nocaps, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, int ssl_upstream, struct module_qstate* q); /** * process control messages from the main thread. Frees the control |