mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
5
Commits
1.11.0rc1
...
release-0.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82e4110e09 | ||
|
|
fb57492c0a | ||
|
|
bde1ce87d5 | ||
|
|
b7a627b8cc | ||
|
|
ea7630845f |
+4
-2
@@ -59,10 +59,12 @@ void server_stats_querymiss(struct server_stats* stats, struct worker* worker)
|
||||
|
||||
void server_stats_log(struct server_stats* stats, int threadnum)
|
||||
{
|
||||
log_info("server stats for thread %d: %u queries, %u from cache",
|
||||
log_info("server stats for thread %d: %u queries, "
|
||||
"%u answers from cache, %u recursions",
|
||||
threadnum, (unsigned)stats->num_queries,
|
||||
(unsigned)(stats->num_queries -
|
||||
stats->num_queries_missed_cache));
|
||||
stats->num_queries_missed_cache),
|
||||
(unsigned)stats->num_queries_missed_cache);
|
||||
log_info("server stats for thread %d: requestlist max %u avg %g "
|
||||
"exceeded %u", threadnum, (unsigned)stats->max_query_list_size,
|
||||
stats->num_queries_missed_cache?
|
||||
|
||||
+2
-2
@@ -874,8 +874,8 @@ worker_restart_timer(struct worker* worker)
|
||||
void worker_stat_timer_cb(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
server_stats_log(&worker->stats, worker->thread_num);
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
worker_mem_report(worker, NULL);
|
||||
server_stats_init(&worker->stats);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
@@ -1046,8 +1046,8 @@ worker_delete(struct worker* worker)
|
||||
if(!worker)
|
||||
return;
|
||||
if(worker->env.mesh && verbosity >= VERB_OPS) {
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
server_stats_log(&worker->stats, worker->thread_num);
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
worker_mem_report(worker, NULL);
|
||||
}
|
||||
mesh_delete(worker->env.mesh);
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
11 February 2008: Wouter
|
||||
- nicer statistic output (from trunk).
|
||||
- ub_val to ub_ for library API (from trunk).
|
||||
- (from trunk) set_option, set_debugout, etc/hosts handling.
|
||||
|
||||
8 February 2008: Wouter
|
||||
- test program for multiple queries over a TCP channel.
|
||||
- tpkg test for stream tcp queries.
|
||||
- unbound replies to multiple TCP queries on a TCP channel.
|
||||
- fixup misclassification of root referral with NS in answer
|
||||
when validating a nonrec query.
|
||||
- tag 0.9
|
||||
|
||||
7 February 2008: Wouter
|
||||
- moved up all current level 2 to be level 3. And 3 to 4.
|
||||
|
||||
+117
-85
@@ -11,101 +11,109 @@
|
||||
.LP
|
||||
.B libunbound,
|
||||
.B unbound.h,
|
||||
.B ub_val_ctx,
|
||||
.B ub_val_result,
|
||||
.B ub_val_callback_t,
|
||||
.B ub_val_ctx_create,
|
||||
.B ub_val_ctx_delete,
|
||||
.B ub_val_ctx_config,
|
||||
.B ub_val_ctx_set_fwd,
|
||||
.B ub_val_ctx_resolvconf,
|
||||
.B ub_val_ctx_add_ta,
|
||||
.B ub_val_ctx_add_ta_file,
|
||||
.B ub_val_ctx_trustedkeys,
|
||||
.B ub_val_ctx_debuglevel,
|
||||
.B ub_val_ctx_async,
|
||||
.B ub_val_poll,
|
||||
.B ub_val_wait,
|
||||
.B ub_val_fd,
|
||||
.B ub_val_process,
|
||||
.B ub_val_resolve,
|
||||
.B ub_val_resolve_async,
|
||||
.B ub_val_cancel,
|
||||
.B ub_val_resolve_free,
|
||||
.B ub_val_strerror
|
||||
.B ub_ctx,
|
||||
.B ub_result,
|
||||
.B ub_callback_t,
|
||||
.B ub_ctx_create,
|
||||
.B ub_ctx_delete,
|
||||
.B ub_ctx_set_option,
|
||||
.B ub_ctx_config,
|
||||
.B ub_ctx_set_fwd,
|
||||
.B ub_ctx_resolvconf,
|
||||
.B ub_ctx_hosts,
|
||||
.B ub_ctx_add_ta,
|
||||
.B ub_ctx_add_ta_file,
|
||||
.B ub_ctx_trustedkeys,
|
||||
.B ub_ctx_debugout,
|
||||
.B ub_ctx_debuglevel,
|
||||
.B ub_ctx_async,
|
||||
.B ub_poll,
|
||||
.B ub_wait,
|
||||
.B ub_fd,
|
||||
.B ub_process,
|
||||
.B ub_resolve,
|
||||
.B ub_resolve_async,
|
||||
.B ub_cancel,
|
||||
.B ub_resolve_free,
|
||||
.B ub_strerror
|
||||
\- Unbound DNS validating resolver @version@ functions.
|
||||
.SH "SYNOPSIS"
|
||||
.LP
|
||||
.B #include <unbound.h>
|
||||
.LP
|
||||
\fIstruct ub_val_ctx *\fR
|
||||
\fBub_val_ctx_create\fR(\fIvoid\fR);
|
||||
\fIstruct ub_ctx *\fR
|
||||
\fBub_ctx_create\fR(\fIvoid\fR);
|
||||
.LP
|
||||
\fIvoid\fR
|
||||
\fBub_val_ctx_delete\fR(\fIstruct ub_val_ctx*\fR ctx);
|
||||
\fBub_ctx_delete\fR(\fIstruct ub_ctx*\fR ctx);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_config\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
\fBub_ctx_set_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar*\fR val);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_set_fwd\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR addr);
|
||||
\fBub_ctx_config\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_resolvconf\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
\fBub_ctx_set_fwd\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR addr);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_add_ta\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR ta);
|
||||
\fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_add_ta_file\fR(\fIstruct ub_val_ctx*\fR ctx,
|
||||
.br
|
||||
\fIchar*\fR fname);
|
||||
\fBub_ctx_hosts\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_trustedkeys\fR(\fIstruct ub_val_ctx*\fR ctx,
|
||||
.br
|
||||
\fIchar*\fR fname);
|
||||
\fBub_ctx_add_ta\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR ta);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_debuglevel\fR(\fIstruct ub_val_ctx*\fR ctx, \fIint\fR d);
|
||||
\fBub_ctx_add_ta_file\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_ctx_async\fR(\fIstruct ub_val_ctx*\fR ctx, \fIint\fR dothread);
|
||||
\fBub_ctx_trustedkeys\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_poll\fR(\fIstruct ub_val_ctx*\fR ctx);
|
||||
\fBub_ctx_debugout\fR(\fIstruct ub_ctx*\fR ctx, \fIFILE*\fR out);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_wait\fR(\fIstruct ub_val_ctx*\fR ctx);
|
||||
\fBub_ctx_debuglevel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR d);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_fd\fR(\fIstruct ub_val_ctx*\fR ctx);
|
||||
\fBub_ctx_async\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR dothread);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_process\fR(\fIstruct ub_val_ctx*\fR ctx);
|
||||
\fBub_poll\fR(\fIstruct ub_ctx*\fR ctx);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_resolve\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR name,
|
||||
\fBub_wait\fR(\fIstruct ub_ctx*\fR ctx);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_fd\fR(\fIstruct ub_ctx*\fR ctx);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_process\fR(\fIstruct ub_ctx*\fR ctx);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_resolve\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
|
||||
.br
|
||||
\fIint\fR rrtype, \fIint\fR rrclass, \fIint*\fR secure,
|
||||
.br
|
||||
\fIint*\fR data, \fIstruct ub_val_result**\fR result);
|
||||
\fIint*\fR data, \fIstruct ub_result**\fR result);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_resolve_async\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR name,
|
||||
\fBub_resolve_async\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
|
||||
.br
|
||||
\fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata,
|
||||
.br
|
||||
\fIub_val_callback_t\fR callback, \fIint*\fR async_id);
|
||||
\fIub_callback_t\fR callback, \fIint*\fR async_id);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_val_cancel\fR(\fIstruct ub_val_ctx*\fR ctx, \fIint\fR async_id);
|
||||
\fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id);
|
||||
.LP
|
||||
\fIvoid\fR
|
||||
\fBub_val_resolve_free\fR(\fIstruct ub_val_result*\fR result);
|
||||
\fBub_resolve_free\fR(\fIstruct ub_result*\fR result);
|
||||
.LP
|
||||
\fIconst char *\fR
|
||||
\fBub_val_strerror\fR(\fIint\fR err);
|
||||
\fBub_strerror\fR(\fIint\fR err);
|
||||
.SH "DESCRIPTION"
|
||||
.LP
|
||||
.B Unbound
|
||||
@@ -116,11 +124,11 @@ The library can be used to convert hostnames to ip addresses, and back,
|
||||
and obtain other information from the DNS. The library performs public\-key
|
||||
validation of results with DNSSEC.
|
||||
.P
|
||||
The library uses a variable of type \fIstruct ub_val_ctx\fR to keep context
|
||||
The library uses a variable of type \fIstruct ub_ctx\fR to keep context
|
||||
between calls. The user must maintain it, creating it with
|
||||
.B ub_val_ctx_create
|
||||
.B ub_ctx_create
|
||||
and deleting it with
|
||||
.B ub_val_ctx_delete\fR.
|
||||
.B ub_ctx_delete\fR.
|
||||
It can be created and deleted at any time. Creating it anew removes any
|
||||
previous configuration (such as trusted keys) and clears any cached results.
|
||||
.P
|
||||
@@ -133,20 +141,32 @@ can go on, while the results become available later.
|
||||
The functions are discussed in turn below.
|
||||
.SH "FUNCTIONS"
|
||||
.TP
|
||||
.B ub_val_ctx_create
|
||||
.B ub_ctx_create
|
||||
Create a new context, initialised with defaults.
|
||||
The information from /etc/resolv.conf and /etc/hosts is not utilised
|
||||
by default. Use
|
||||
.B ub_ctx_resolvconf
|
||||
and
|
||||
.B ub_ctx_hosts
|
||||
to read them.
|
||||
.TP
|
||||
.B ub_val_ctx_delete
|
||||
.B ub_ctx_delete
|
||||
Delete validation context and free associated resources.
|
||||
Outstanding async queries are killed and callbacks are not called for them.
|
||||
.TP
|
||||
.B ub_val_ctx_config
|
||||
.B ub_ctx_set_option
|
||||
A power\-user interface that lets you specify one of the options from the
|
||||
config file format, see \fIunbound.conf\fR(5). Not all options are
|
||||
relevant. For some specific options, such as adding trust anchors, special
|
||||
routines exist. Pass the option name with the trailing ':'.
|
||||
.TP
|
||||
.B ub_ctx_config
|
||||
A power\-user interface that lets you specify an unbound config file, see
|
||||
\fIunbound.conf\fR(5), which is read for configuration. Not all options are
|
||||
relevant. For some specific options, such as adding trust anchors, special
|
||||
routines exist.
|
||||
.TP
|
||||
.B ub_val_ctx_set_fwd
|
||||
.B ub_ctx_set_fwd
|
||||
Set machine to forward DNS queries to, the caching resolver to use.
|
||||
IP4 or IP6 address. Forwards all DNS requests to that machine, which
|
||||
is expected to run a recursive resolver. If the proxy is not
|
||||
@@ -155,7 +175,7 @@ that case the addresses are used as backup servers.
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_val_ctx_resolvconf
|
||||
.B ub_ctx_resolvconf
|
||||
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.
|
||||
@@ -165,67 +185,79 @@ If fname NULL is passed, "/etc/resolv.conf" is used.
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_hosts
|
||||
Read list of hosts from the filename given.
|
||||
Usually "/etc/hosts". When queried for, these addresses are not marked
|
||||
DNSSEC secure. If fname NULL is passed, "/etc/hosts" is used.
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B
|
||||
ub_val_ctx_add_ta
|
||||
ub_ctx_add_ta
|
||||
Add a trust anchor to the given context.
|
||||
At this time it is only possible to add trusted keys before the
|
||||
first resolve is done.
|
||||
The format is a string, similar to the zone-file format,
|
||||
[domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted.
|
||||
.TP
|
||||
.B ub_val_ctx_add_ta_file
|
||||
.B ub_ctx_add_ta_file
|
||||
Add trust anchors to the given context.
|
||||
Pass name of a file with DS and DNSKEY records in zone file format.
|
||||
At this time it is only possible to add trusted keys before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_val_ctx_trustedkeys
|
||||
.B ub_ctx_trustedkeys
|
||||
Add trust anchors to the given context.
|
||||
Pass the name of a bind-style config file with trusted-keys{}.
|
||||
At this time it is only possible to add trusted keys before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_val_ctx_debuglevel
|
||||
.B ub_ctx_debugout
|
||||
Set debug and error log output to the given stream. Pass NULL to disable
|
||||
output. Default is stderr. File-names or using syslog can be enabled
|
||||
using config options, this routine is for using your own stream.
|
||||
.TP
|
||||
.B ub_ctx_debuglevel
|
||||
Set debug verbosity for the context. Output is directed to stderr.
|
||||
Higher debug level gives more output.
|
||||
.TP
|
||||
.B ub_val_ctx_async
|
||||
.B ub_ctx_async
|
||||
Set a context behaviour for asynchronous action.
|
||||
if set to true, enables threading and a call to
|
||||
.B ub_val_resolve_async
|
||||
.B ub_resolve_async
|
||||
creates a thread to handle work in the background.
|
||||
If false, a process is forked to handle work in the background.
|
||||
Changes to this setting after
|
||||
.B ub_val_resolve_async
|
||||
.B ub_resolve_async
|
||||
calls have been made have no effect (delete and re\-create the context
|
||||
to change).
|
||||
.TP
|
||||
.B ub_val_poll
|
||||
.B ub_poll
|
||||
Poll a context to see if it has any new results.
|
||||
Do not poll in a loop, instead extract the fd below to poll for readiness,
|
||||
and then check, or wait using the wait routine.
|
||||
Returns 0 if nothing to read, or nonzero if a result is available.
|
||||
If nonzero, call
|
||||
.B ub_val_process
|
||||
.B ub_process
|
||||
to do callbacks.
|
||||
.TP
|
||||
.B ub_val_wait
|
||||
.B ub_wait
|
||||
Wait for a context to finish with results. Calls
|
||||
.B ub_val_process
|
||||
.B ub_process
|
||||
after the wait for you. After the wait, there are no more outstanding
|
||||
asynchronous queries.
|
||||
.TP
|
||||
.B ub_val_fd
|
||||
.B ub_fd
|
||||
Get file descriptor. Wait for it to become readable, at this point
|
||||
answers are returned from the asynchronous validating resolver.
|
||||
Then call the \fBub_val_process\fR to continue processing.
|
||||
Then call the \fBub_process\fR to continue processing.
|
||||
.TP
|
||||
.B ub_val_process
|
||||
.B ub_process
|
||||
Call this routine to continue processing results from the validating
|
||||
resolver (when the fd becomes readable).
|
||||
Will perform necessary callbacks.
|
||||
.TP
|
||||
.B ub_val_resolve
|
||||
.B ub_resolve
|
||||
Perform resolution and validation of the target name.
|
||||
The name is a domain name in a zero terminated text string.
|
||||
The rrtype and rrclass are DNS type and class codes.
|
||||
@@ -233,9 +265,9 @@ The value secure returns true if the answer validated securely.
|
||||
The value data returns true if there was data.
|
||||
The result structure is newly allocated with the resulting data.
|
||||
.TP
|
||||
.B ub_val_resolve_async
|
||||
.B ub_resolve_async
|
||||
Perform asynchronous resolution and validation of the target name.
|
||||
Arguments mean the same as for \fBub_val_resolve\fR except no
|
||||
Arguments mean the same as for \fBub_resolve\fR except no
|
||||
data is returned immediately, instead a callback is called later.
|
||||
The callback receives a copy of the mydata pointer, that you can use to pass
|
||||
information to the callback. The callback type is a function pointer to
|
||||
@@ -243,27 +275,27 @@ a function declared as
|
||||
.IP
|
||||
void my_callback_function(void* my_arg, int err,
|
||||
.br
|
||||
struct ub_val_result* result);
|
||||
struct ub_result* result);
|
||||
.IP
|
||||
The async_id is returned so you can (at your option) decide to track it
|
||||
and cancel the request if needed.
|
||||
.TP
|
||||
.B ub_val_cancel
|
||||
.B ub_cancel
|
||||
Cancel an async query in progress.
|
||||
.TP
|
||||
.B ub_val_resolve_free
|
||||
Free struct ub_val_result contents after use.
|
||||
.B ub_resolve_free
|
||||
Free struct ub_result contents after use.
|
||||
.TP
|
||||
.B ub_val_strerror
|
||||
.B ub_strerror
|
||||
Convert error value from one of the unbound library functions
|
||||
to a human readable string.
|
||||
.SH "RESULT DATA STRUCTURE"
|
||||
.LP
|
||||
The result of the DNS resolution and validation is returned as
|
||||
\fIstruct ub_val_result\fR. The result structure contains the following entries.
|
||||
\fIstruct ub_result\fR. The result structure contains the following entries.
|
||||
.P
|
||||
.nf
|
||||
struct ub_val_result {
|
||||
struct ub_result {
|
||||
char* qname; /* text string, original question */
|
||||
int qtype; /* type code asked for */
|
||||
int qclass; /* class code asked for */
|
||||
@@ -283,15 +315,15 @@ domain of the query.
|
||||
.SH "RETURN VALUES"
|
||||
Many routines return an error code. The value 0 (zero) denotes no error
|
||||
happened. Other values can be passed to
|
||||
.B ub_val_strerror
|
||||
.B ub_strerror
|
||||
to obtain a readable error string.
|
||||
.B ub_val_strerror
|
||||
.B ub_strerror
|
||||
returns a zero terminated string.
|
||||
.B ub_val_ctx_create
|
||||
.B ub_ctx_create
|
||||
returns NULL on an error (a malloc failure).
|
||||
.B ub_val_poll
|
||||
.B ub_poll
|
||||
returns true if some information may be available, false otherwise.
|
||||
.B ub_val_fd
|
||||
.B ub_fd
|
||||
returns a file descriptor or -1 on error.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
|
||||
+19
-8
@@ -467,7 +467,8 @@ for completeness and to satisfy some DNS update tools. Default content:
|
||||
.nf
|
||||
local\-zone: "localhost." static
|
||||
local\-data: "localhost. 10800 IN NS localhost."
|
||||
local\-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
local\-data: "localhost. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
local\-data: "localhost. 10800 IN A 127.0.0.1"
|
||||
local\-data: "localhost. 10800 IN AAAA ::1"
|
||||
.fi
|
||||
@@ -477,17 +478,26 @@ Default content:
|
||||
.nf
|
||||
local\-zone: "127.in\-addr.arpa." static
|
||||
local\-data: "127.in\-addr.arpa. 10800 IN NS localhost."
|
||||
local\-data: "127.in\-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
local\-data: "1.0.0.127.in\-addr.arpa. 10800 IN PTR localhost."
|
||||
local\-data: "127.in\-addr.arpa. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
local\-data: "1.0.0.127.in\-addr.arpa. 10800 IN
|
||||
PTR localhost."
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fIreverse IPv6 loopback\fR
|
||||
Default content:
|
||||
.nf
|
||||
local\-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." static
|
||||
local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost."
|
||||
local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost."
|
||||
local\-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." static
|
||||
local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN
|
||||
NS localhost."
|
||||
local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
local\-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN
|
||||
PTR localhost."
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fIreverse RFC1918 local use zones\fR
|
||||
@@ -503,7 +513,8 @@ Reverse data for zones 0.in\-addr.arpa, 254.169.in\-addr.arpa,
|
||||
\h'5'\fIreverse RFC4291 IP6 unspecified\fR
|
||||
Reverse data for zone
|
||||
.nf
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
|
||||
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fIreverse RFC4193 IPv6 Locally Assigned Local Addresses\fR
|
||||
|
||||
+16
-14
@@ -51,11 +51,13 @@
|
||||
#include "util/storage/slabhash.h"
|
||||
|
||||
int
|
||||
context_finalize(struct ub_val_ctx* ctx)
|
||||
context_finalize(struct ub_ctx* ctx)
|
||||
{
|
||||
struct config_file* cfg = ctx->env->cfg;
|
||||
verbosity = cfg->verbosity;
|
||||
log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||
if(ctx->logfile_override)
|
||||
log_file(ctx->log_out);
|
||||
else log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
@@ -99,7 +101,7 @@ void
|
||||
context_query_delete(struct ctx_query* q)
|
||||
{
|
||||
if(!q) return;
|
||||
ub_val_resolve_free(q->res);
|
||||
ub_resolve_free(q->res);
|
||||
free(q->msg);
|
||||
free(q);
|
||||
}
|
||||
@@ -108,7 +110,7 @@ context_query_delete(struct ctx_query* q)
|
||||
#define NUM_ID_TRIES 100000
|
||||
/** find next useful id number of 0 on error */
|
||||
static int
|
||||
find_id(struct ub_val_ctx* ctx, int* id)
|
||||
find_id(struct ub_ctx* ctx, int* id)
|
||||
{
|
||||
size_t tries = 0;
|
||||
ctx->next_querynum++;
|
||||
@@ -122,8 +124,8 @@ find_id(struct ub_val_ctx* ctx, int* id)
|
||||
}
|
||||
|
||||
struct ctx_query*
|
||||
context_new(struct ub_val_ctx* ctx, char* name, int rrtype, int rrclass,
|
||||
ub_val_callback_t cb, void* cbarg)
|
||||
context_new(struct ub_ctx* ctx, char* name, int rrtype, int rrclass,
|
||||
ub_callback_t cb, void* cbarg)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||
if(!q) return NULL;
|
||||
@@ -138,7 +140,7 @@ context_new(struct ub_val_ctx* ctx, char* name, int rrtype, int rrclass,
|
||||
q->async = (cb != NULL);
|
||||
q->cb = cb;
|
||||
q->cb_arg = cbarg;
|
||||
q->res = (struct ub_val_result*)calloc(1, sizeof(*q->res));
|
||||
q->res = (struct ub_result*)calloc(1, sizeof(*q->res));
|
||||
if(!q->res) {
|
||||
free(q);
|
||||
return NULL;
|
||||
@@ -162,7 +164,7 @@ context_new(struct ub_val_ctx* ctx, char* name, int rrtype, int rrclass,
|
||||
}
|
||||
|
||||
struct alloc_cache*
|
||||
context_obtain_alloc(struct ub_val_ctx* ctx, int locking)
|
||||
context_obtain_alloc(struct ub_ctx* ctx, int locking)
|
||||
{
|
||||
struct alloc_cache* a;
|
||||
int tnum = 0;
|
||||
@@ -188,7 +190,7 @@ context_obtain_alloc(struct ub_val_ctx* ctx, int locking)
|
||||
}
|
||||
|
||||
void
|
||||
context_release_alloc(struct ub_val_ctx* ctx, struct alloc_cache* alloc,
|
||||
context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
|
||||
int locking)
|
||||
{
|
||||
if(!ctx || !alloc)
|
||||
@@ -227,7 +229,7 @@ context_serialize_new_query(struct ctx_query* q, uint32_t* len)
|
||||
}
|
||||
|
||||
struct ctx_query*
|
||||
context_deserialize_new_query(struct ub_val_ctx* ctx, uint8_t* p, uint32_t len)
|
||||
context_deserialize_new_query(struct ub_ctx* ctx, uint8_t* p, uint32_t len)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||
if(!q) return NULL;
|
||||
@@ -239,7 +241,7 @@ context_deserialize_new_query(struct ub_val_ctx* ctx, uint8_t* p, uint32_t len)
|
||||
q->querynum = (int)ldns_read_uint32(p+sizeof(uint32_t));
|
||||
q->node.key = &q->querynum;
|
||||
q->async = 1;
|
||||
q->res = (struct ub_val_result*)calloc(1, sizeof(*q->res));
|
||||
q->res = (struct ub_result*)calloc(1, sizeof(*q->res));
|
||||
if(!q->res) {
|
||||
free(q);
|
||||
return NULL;
|
||||
@@ -260,7 +262,7 @@ context_deserialize_new_query(struct ub_val_ctx* ctx, uint8_t* p, uint32_t len)
|
||||
}
|
||||
|
||||
struct ctx_query*
|
||||
context_lookup_new_query(struct ub_val_ctx* ctx, uint8_t* p, uint32_t len)
|
||||
context_lookup_new_query(struct ub_ctx* ctx, uint8_t* p, uint32_t len)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
int querynum;
|
||||
@@ -304,7 +306,7 @@ context_serialize_answer(struct ctx_query* q, int err, ldns_buffer* pkt,
|
||||
}
|
||||
|
||||
struct ctx_query*
|
||||
context_deserialize_answer(struct ub_val_ctx* ctx,
|
||||
context_deserialize_answer(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len, int* err)
|
||||
{
|
||||
struct ctx_query* q = NULL ;
|
||||
@@ -343,7 +345,7 @@ context_serialize_cancel(struct ctx_query* q, uint32_t* len)
|
||||
return p;
|
||||
}
|
||||
|
||||
struct ctx_query* context_deserialize_cancel(struct ub_val_ctx* ctx,
|
||||
struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
|
||||
+16
-12
@@ -55,7 +55,7 @@ struct libworker;
|
||||
* qq : write queries to the async service pid/tid.
|
||||
* rr : read results from the async service pid/tid.
|
||||
*/
|
||||
struct ub_val_ctx {
|
||||
struct ub_ctx {
|
||||
/* --- pipes --- */
|
||||
/** mutex on query write pipe */
|
||||
lock_basic_t qqpipe_lock;
|
||||
@@ -87,6 +87,10 @@ struct ub_val_ctx {
|
||||
int dothread;
|
||||
/** next thread number for new threads */
|
||||
int thr_next_num;
|
||||
/** if logfile is overriden */
|
||||
int logfile_override;
|
||||
/** what logfile to use instead */
|
||||
FILE* log_out;
|
||||
/**
|
||||
* List of alloc-cache-id points per threadnum for notinuse threads.
|
||||
* Simply the entire struct alloc_cache with the 'super' member used
|
||||
@@ -137,7 +141,7 @@ struct ctx_query {
|
||||
int cancelled;
|
||||
|
||||
/** for async query, the callback function */
|
||||
ub_val_callback_t cb;
|
||||
ub_callback_t cb;
|
||||
/** for async query, the callback user arg */
|
||||
void* cb_arg;
|
||||
|
||||
@@ -152,7 +156,7 @@ struct ctx_query {
|
||||
|
||||
/** result structure, also contains original query, type, class.
|
||||
* malloced ptr ready to hand to the client. */
|
||||
struct ub_val_result* res;
|
||||
struct ub_result* res;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -206,7 +210,7 @@ enum ub_ctx_cmd {
|
||||
* @param ctx: context to finalize. creates shared data.
|
||||
* @return 0 if OK, or errcode.
|
||||
*/
|
||||
int context_finalize(struct ub_val_ctx* ctx);
|
||||
int context_finalize(struct ub_ctx* ctx);
|
||||
|
||||
/** compare two ctx_query elements */
|
||||
int context_query_cmp(const void* a, const void* b);
|
||||
@@ -227,8 +231,8 @@ void context_query_delete(struct ctx_query* q);
|
||||
* @param cbarg: user arg for async queries.
|
||||
* @return new ctx_query or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_new(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, ub_val_callback_t cb, void* cbarg);
|
||||
struct ctx_query* context_new(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, ub_callback_t cb, void* cbarg);
|
||||
|
||||
/**
|
||||
* Get a new alloc. Creates a new one or uses a cached one.
|
||||
@@ -236,7 +240,7 @@ struct ctx_query* context_new(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
* @param locking: if true, cfglock is locked while getting alloc.
|
||||
* @return an alloc, or NULL on mem error.
|
||||
*/
|
||||
struct alloc_cache* context_obtain_alloc(struct ub_val_ctx* ctx, int locking);
|
||||
struct alloc_cache* context_obtain_alloc(struct ub_ctx* ctx, int locking);
|
||||
|
||||
/**
|
||||
* Release an alloc. Puts it into the cache.
|
||||
@@ -244,7 +248,7 @@ struct alloc_cache* context_obtain_alloc(struct ub_val_ctx* ctx, int locking);
|
||||
* @param locking: if true, cfglock is locked while releasing alloc.
|
||||
* @param alloc: alloc to relinquish.
|
||||
*/
|
||||
void context_release_alloc(struct ub_val_ctx* ctx, struct alloc_cache* alloc,
|
||||
void context_release_alloc(struct ub_ctx* ctx, struct alloc_cache* alloc,
|
||||
int locking);
|
||||
|
||||
/**
|
||||
@@ -301,7 +305,7 @@ enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len);
|
||||
* @param len: length of buffer.
|
||||
* @return looked up ctx_query or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_lookup_new_query(struct ub_val_ctx* ctx,
|
||||
struct ctx_query* context_lookup_new_query(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len);
|
||||
|
||||
/**
|
||||
@@ -311,7 +315,7 @@ struct ctx_query* context_lookup_new_query(struct ub_val_ctx* ctx,
|
||||
* @param len: length of buffer.
|
||||
* @return new ctx_query or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_deserialize_new_query(struct ub_val_ctx* ctx,
|
||||
struct ctx_query* context_deserialize_new_query(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len);
|
||||
|
||||
/**
|
||||
@@ -322,7 +326,7 @@ struct ctx_query* context_deserialize_new_query(struct ub_val_ctx* ctx,
|
||||
* @param err: error code to be returned to client is passed.
|
||||
* @return ctx_query with answer added or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_deserialize_answer(struct ub_val_ctx* ctx,
|
||||
struct ctx_query* context_deserialize_answer(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len, int* err);
|
||||
|
||||
/**
|
||||
@@ -332,7 +336,7 @@ struct ctx_query* context_deserialize_answer(struct ub_val_ctx* ctx,
|
||||
* @param len: length of buffer.
|
||||
* @return ctx_query to cancel or NULL for failure.
|
||||
*/
|
||||
struct ctx_query* context_deserialize_cancel(struct ub_val_ctx* ctx,
|
||||
struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len);
|
||||
|
||||
#endif /* LIBUNBOUND_CONTEXT_H */
|
||||
|
||||
+138
-36
@@ -59,16 +59,16 @@
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/rrset.h"
|
||||
|
||||
struct ub_val_ctx*
|
||||
ub_val_ctx_create()
|
||||
struct ub_ctx*
|
||||
ub_ctx_create()
|
||||
{
|
||||
struct ub_val_ctx* ctx;
|
||||
struct ub_ctx* ctx;
|
||||
unsigned int seed;
|
||||
log_init(NULL, 0, NULL); /* logs to stderr */
|
||||
log_ident_set("libunbound");
|
||||
verbosity = 0; /* errors only */
|
||||
checklock_start();
|
||||
ctx = (struct ub_val_ctx*)calloc(1, sizeof(*ctx));
|
||||
ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
@@ -154,7 +154,7 @@ delq(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||
}
|
||||
|
||||
void
|
||||
ub_val_ctx_delete(struct ub_val_ctx* ctx)
|
||||
ub_ctx_delete(struct ub_ctx* ctx)
|
||||
{
|
||||
struct alloc_cache* a, *na;
|
||||
if(!ctx) return;
|
||||
@@ -234,7 +234,23 @@ ub_val_ctx_delete(struct ub_val_ctx* ctx)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname)
|
||||
ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val)
|
||||
{
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
if(!config_set_option(ctx->env->cfg, opt, val)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int
|
||||
ub_ctx_config(struct ub_ctx* ctx, char* fname)
|
||||
{
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
@@ -250,7 +266,7 @@ ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_add_ta(struct ub_val_ctx* ctx, char* ta)
|
||||
ub_ctx_add_ta(struct ub_ctx* ctx, char* ta)
|
||||
{
|
||||
char* dup = strdup(ta);
|
||||
if(!dup) return UB_NOMEM;
|
||||
@@ -269,7 +285,7 @@ ub_val_ctx_add_ta(struct ub_val_ctx* ctx, char* ta)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_add_ta_file(struct ub_val_ctx* ctx, char* fname)
|
||||
ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname)
|
||||
{
|
||||
char* dup = strdup(fname);
|
||||
if(!dup) return UB_NOMEM;
|
||||
@@ -288,7 +304,7 @@ ub_val_ctx_add_ta_file(struct ub_val_ctx* ctx, char* fname)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_trustedkeys(struct ub_val_ctx* ctx, char* fname)
|
||||
ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname)
|
||||
{
|
||||
char* dup = strdup(fname);
|
||||
if(!dup) return UB_NOMEM;
|
||||
@@ -307,7 +323,7 @@ ub_val_ctx_trustedkeys(struct ub_val_ctx* ctx, char* fname)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_debuglevel(struct ub_val_ctx* ctx, int d)
|
||||
ub_ctx_debuglevel(struct ub_ctx* ctx, int d)
|
||||
{
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
verbosity = d;
|
||||
@@ -316,8 +332,18 @@ ub_val_ctx_debuglevel(struct ub_val_ctx* ctx, int d)
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int ub_ctx_debugout(struct ub_ctx* ctx, void* out)
|
||||
{
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
log_file((FILE*)out);
|
||||
ctx->logfile_override = 1;
|
||||
ctx->log_out = out;
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_async(struct ub_val_ctx* ctx, int dothread)
|
||||
ub_ctx_async(struct ub_ctx* ctx, int dothread)
|
||||
{
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
if(dothread) /* cannot do threading */
|
||||
@@ -335,7 +361,7 @@ ub_val_ctx_async(struct ub_val_ctx* ctx, int dothread)
|
||||
|
||||
/** perform a select() on the result read pipe */
|
||||
static int
|
||||
pollit(struct ub_val_ctx* ctx, struct timeval* t)
|
||||
pollit(struct ub_ctx* ctx, struct timeval* t)
|
||||
{
|
||||
fd_set r;
|
||||
#ifndef S_SPLINT_S
|
||||
@@ -350,7 +376,7 @@ pollit(struct ub_val_ctx* ctx, struct timeval* t)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_poll(struct ub_val_ctx* ctx)
|
||||
ub_poll(struct ub_ctx* ctx)
|
||||
{
|
||||
struct timeval t;
|
||||
memset(&t, 0, sizeof(t));
|
||||
@@ -359,16 +385,16 @@ ub_val_poll(struct ub_val_ctx* ctx)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_fd(struct ub_val_ctx* ctx)
|
||||
ub_fd(struct ub_ctx* ctx)
|
||||
{
|
||||
return ctx->rrpipe[0];
|
||||
}
|
||||
|
||||
/** process answer from bg worker */
|
||||
static int
|
||||
process_answer_detail(struct ub_val_ctx* ctx, uint8_t* msg, uint32_t len,
|
||||
ub_val_callback_t* cb, void** cbarg, int* err,
|
||||
struct ub_val_result** res)
|
||||
process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
|
||||
ub_callback_t* cb, void** cbarg, int* err,
|
||||
struct ub_result** res)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
if(context_serial_getcmd(msg, len) != UB_LIBCMD_ANSWER) {
|
||||
@@ -397,7 +423,7 @@ process_answer_detail(struct ub_val_ctx* ctx, uint8_t* msg, uint32_t len,
|
||||
}
|
||||
if(*err) {
|
||||
*res = NULL;
|
||||
ub_val_resolve_free(q->res);
|
||||
ub_resolve_free(q->res);
|
||||
} else {
|
||||
/* parse the message, extract rcode, fill result */
|
||||
ldns_buffer* buf = ldns_buffer_new(q->msg_len);
|
||||
@@ -427,12 +453,12 @@ process_answer_detail(struct ub_val_ctx* ctx, uint8_t* msg, uint32_t len,
|
||||
|
||||
/** process answer from bg worker */
|
||||
static int
|
||||
process_answer(struct ub_val_ctx* ctx, uint8_t* msg, uint32_t len)
|
||||
process_answer(struct ub_ctx* ctx, uint8_t* msg, uint32_t len)
|
||||
{
|
||||
int err;
|
||||
ub_val_callback_t cb;
|
||||
ub_callback_t cb;
|
||||
void* cbarg;
|
||||
struct ub_val_result* res;
|
||||
struct ub_result* res;
|
||||
int r;
|
||||
|
||||
r = process_answer_detail(ctx, msg, len, &cb, &cbarg, &err, &res);
|
||||
@@ -446,7 +472,7 @@ process_answer(struct ub_val_ctx* ctx, uint8_t* msg, uint32_t len)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_process(struct ub_val_ctx* ctx)
|
||||
ub_process(struct ub_ctx* ctx)
|
||||
{
|
||||
int r;
|
||||
uint8_t* msg;
|
||||
@@ -470,12 +496,12 @@ ub_val_process(struct ub_val_ctx* ctx)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_wait(struct ub_val_ctx* ctx)
|
||||
ub_wait(struct ub_ctx* ctx)
|
||||
{
|
||||
int err;
|
||||
ub_val_callback_t cb;
|
||||
ub_callback_t cb;
|
||||
void* cbarg;
|
||||
struct ub_val_result* res;
|
||||
struct ub_result* res;
|
||||
int r;
|
||||
uint8_t* msg;
|
||||
uint32_t len;
|
||||
@@ -523,8 +549,8 @@ ub_val_wait(struct ub_val_ctx* ctx)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, struct ub_val_result** result)
|
||||
ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, struct ub_result** result)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
int r;
|
||||
@@ -564,8 +590,8 @@ ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_resolve_async(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_val_callback_t callback, int* async_id)
|
||||
ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_callback_t callback, int* async_id)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
uint8_t* msg = NULL;
|
||||
@@ -627,7 +653,7 @@ ub_val_resolve_async(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_cancel(struct ub_val_ctx* ctx, int async_id)
|
||||
ub_cancel(struct ub_ctx* ctx, int async_id)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
uint8_t* msg = NULL;
|
||||
@@ -668,7 +694,7 @@ ub_val_cancel(struct ub_val_ctx* ctx, int async_id)
|
||||
}
|
||||
|
||||
void
|
||||
ub_val_resolve_free(struct ub_val_result* result)
|
||||
ub_resolve_free(struct ub_result* result)
|
||||
{
|
||||
char** p;
|
||||
if(!result) return;
|
||||
@@ -684,7 +710,7 @@ ub_val_resolve_free(struct ub_val_result* result)
|
||||
}
|
||||
|
||||
const char*
|
||||
ub_val_strerror(int err)
|
||||
ub_strerror(int err)
|
||||
{
|
||||
switch(err) {
|
||||
case UB_NOERROR: return "no error";
|
||||
@@ -702,7 +728,7 @@ ub_val_strerror(int err)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_set_fwd(struct ub_val_ctx* ctx, char* addr)
|
||||
ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr)
|
||||
{
|
||||
struct sockaddr_storage storage;
|
||||
socklen_t stlen;
|
||||
@@ -774,7 +800,7 @@ ub_val_ctx_set_fwd(struct ub_val_ctx* ctx, char* addr)
|
||||
}
|
||||
|
||||
int
|
||||
ub_val_ctx_resolvconf(struct ub_val_ctx* ctx, char* fname)
|
||||
ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname)
|
||||
{
|
||||
FILE* in;
|
||||
int numserv = 0;
|
||||
@@ -806,7 +832,7 @@ ub_val_ctx_resolvconf(struct ub_val_ctx* ctx, char* fname)
|
||||
/* terminate after the address, remove newline */
|
||||
*parse = 0;
|
||||
|
||||
if((r = ub_val_ctx_set_fwd(ctx, addr)) != UB_NOERROR) {
|
||||
if((r = ub_ctx_set_fwd(ctx, addr)) != UB_NOERROR) {
|
||||
fclose(in);
|
||||
return r;
|
||||
}
|
||||
@@ -815,7 +841,83 @@ ub_val_ctx_resolvconf(struct ub_val_ctx* ctx, char* fname)
|
||||
fclose(in);
|
||||
if(numserv == 0) {
|
||||
/* from resolv.conf(5) if none given, use localhost */
|
||||
return ub_val_ctx_set_fwd(ctx, "127.0.0.1");
|
||||
return ub_ctx_set_fwd(ctx, "127.0.0.1");
|
||||
}
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int
|
||||
ub_ctx_hosts(struct ub_ctx* ctx, char* fname)
|
||||
{
|
||||
FILE* in;
|
||||
char buf[1024], ldata[1024];
|
||||
char* parse, *addr, *name, *ins;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
errno=EINVAL;
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
if(fname == NULL)
|
||||
fname = "/etc/hosts";
|
||||
in = fopen(fname, "r");
|
||||
if(!in) {
|
||||
/* error in errno! perror(fname) */
|
||||
return UB_READFILE;
|
||||
}
|
||||
while(fgets(buf, (int)sizeof(buf), in)) {
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
parse=buf;
|
||||
while(*parse == ' ' || *parse == '\t')
|
||||
parse++;
|
||||
if(*parse == '#')
|
||||
continue; /* skip comment */
|
||||
/* format: <addr> spaces <name> spaces <name> ... */
|
||||
addr = parse;
|
||||
/* skip addr */
|
||||
while(isxdigit(*parse) || *parse == '.' || *parse == ':')
|
||||
parse++;
|
||||
if(*parse != ' ' && *parse != '\t') {
|
||||
/* must have whitespace after address */
|
||||
fclose(in);
|
||||
errno=EINVAL;
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
*parse++ = 0; /* end delimiter for addr ... */
|
||||
/* go to names and add them */
|
||||
while(*parse) {
|
||||
while(*parse == ' ' || *parse == '\t' || *parse=='\n')
|
||||
parse++;
|
||||
if(*parse == 0 || *parse == '#')
|
||||
break;
|
||||
/* skip name, allows (too) many printable characters */
|
||||
name = parse;
|
||||
while('!' <= *parse && *parse <= '~')
|
||||
parse++;
|
||||
if(*parse)
|
||||
*parse++ = 0; /* end delimiter for name */
|
||||
snprintf(ldata, sizeof(ldata), "%s %s %s",
|
||||
name, str_is_ip6(addr)?"AAAA":"A", addr);
|
||||
ins = strdup(ldata);
|
||||
if(!ins) {
|
||||
/* out of memory */
|
||||
fclose(in);
|
||||
errno=ENOMEM;
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->local_data,
|
||||
ins)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
fclose(in);
|
||||
free(ins);
|
||||
errno=ENOMEM;
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ libworker_delete(struct libworker* w)
|
||||
|
||||
/** setup fresh libworker struct */
|
||||
static struct libworker*
|
||||
libworker_setup(struct ub_val_ctx* ctx, int is_bg)
|
||||
libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
{
|
||||
unsigned int seed;
|
||||
struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
|
||||
@@ -354,7 +354,7 @@ libworker_dobg(void* arg)
|
||||
uint32_t m;
|
||||
int fd;
|
||||
struct libworker* w = (struct libworker*)arg;
|
||||
struct ub_val_ctx* ctx = w->ctx;
|
||||
struct ub_ctx* ctx = w->ctx;
|
||||
log_thread_set(&w->thread_num);
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
/* we are forked */
|
||||
@@ -399,7 +399,7 @@ libworker_dobg(void* arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int libworker_bg(struct ub_val_ctx* ctx)
|
||||
int libworker_bg(struct ub_ctx* ctx)
|
||||
{
|
||||
struct libworker* w;
|
||||
/* fork or threadcreate */
|
||||
@@ -457,7 +457,7 @@ parse_reply(ldns_buffer* pkt, struct regional* region, struct query_info* qi)
|
||||
|
||||
/** insert canonname */
|
||||
static int
|
||||
fill_canon(struct ub_val_result* res, uint8_t* s)
|
||||
fill_canon(struct ub_result* res, uint8_t* s)
|
||||
{
|
||||
char buf[255+2];
|
||||
dname_str(s, buf);
|
||||
@@ -467,7 +467,7 @@ fill_canon(struct ub_val_result* res, uint8_t* s)
|
||||
|
||||
/** fill data into result */
|
||||
static int
|
||||
fill_res(struct ub_val_result* res, struct ub_packed_rrset_key* answer,
|
||||
fill_res(struct ub_result* res, struct ub_packed_rrset_key* answer,
|
||||
uint8_t* finalcname, struct query_info* rq)
|
||||
{
|
||||
size_t i;
|
||||
@@ -504,7 +504,7 @@ fill_res(struct ub_val_result* res, struct ub_packed_rrset_key* answer,
|
||||
|
||||
/** fill result from parsed message, on error fills servfail */
|
||||
void
|
||||
libworker_enter_result(struct ub_val_result* res, ldns_buffer* buf,
|
||||
libworker_enter_result(struct ub_result* res, ldns_buffer* buf,
|
||||
struct regional* temp, enum sec_status msg_security)
|
||||
{
|
||||
struct query_info rq;
|
||||
@@ -591,7 +591,7 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int libworker_fg(struct ub_val_ctx* ctx, struct ctx_query* q)
|
||||
int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
{
|
||||
struct libworker* w = libworker_setup(ctx, 0);
|
||||
uint16_t qflags, qid;
|
||||
@@ -690,7 +690,7 @@ libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
||||
if(q->cancelled) {
|
||||
if(q->w->is_bg_thread) {
|
||||
/* delete it now */
|
||||
struct ub_val_ctx* ctx = q->w->ctx;
|
||||
struct ub_ctx* ctx = q->w->ctx;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
(void)rbtree_delete(&ctx->queries, q->node.key);
|
||||
ctx->num_async--;
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
#ifndef LIBUNBOUND_WORKER_H
|
||||
#define LIBUNBOUND_WORKER_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
struct ub_val_ctx;
|
||||
struct ub_val_result;
|
||||
struct ub_ctx;
|
||||
struct ub_result;
|
||||
struct module_env;
|
||||
struct comm_base;
|
||||
struct outside_network;
|
||||
@@ -66,7 +66,7 @@ struct libworker {
|
||||
/** every worker has a unique thread_num. (first in struct) */
|
||||
int thread_num;
|
||||
/** context we are operating under */
|
||||
struct ub_val_ctx* ctx;
|
||||
struct ub_ctx* ctx;
|
||||
|
||||
/** is this the bg worker? */
|
||||
int is_bg;
|
||||
@@ -122,7 +122,7 @@ struct libworker_res_list {
|
||||
* @return 0 if OK, else error.
|
||||
* Further communication is done via the pipes in ctx.
|
||||
*/
|
||||
int libworker_bg(struct ub_val_ctx* ctx);
|
||||
int libworker_bg(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Create a foreground worker.
|
||||
@@ -133,7 +133,7 @@ int libworker_bg(struct ub_val_ctx* ctx);
|
||||
* @param q: query (result is stored in here).
|
||||
* @return 0 if finished OK, else error.
|
||||
*/
|
||||
int libworker_fg(struct ub_val_ctx* ctx, struct ctx_query* q);
|
||||
int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q);
|
||||
|
||||
/** cleanup the cache to remove all rrset IDs from it, arg is libworker */
|
||||
void libworker_alloc_cleanup(void* arg);
|
||||
@@ -230,7 +230,7 @@ int libworker_read_msg(int fd, uint8_t** buf, uint32_t* len, int nonblock);
|
||||
* On error, the res may contain a different status
|
||||
* (out of memory is not secure, not bogus).
|
||||
*/
|
||||
void libworker_enter_result(struct ub_val_result* res, ldns_buffer* buf,
|
||||
void libworker_enter_result(struct ub_result* res, ldns_buffer* buf,
|
||||
struct regional* temp, enum sec_status msg_security);
|
||||
|
||||
#endif /* LIBUNBOUND_WORKER_H */
|
||||
|
||||
+22
-19
@@ -1,19 +1,22 @@
|
||||
ub_val_ctx_create
|
||||
ub_val_ctx_delete
|
||||
ub_val_ctx_config
|
||||
ub_val_ctx_set_fwd
|
||||
ub_val_ctx_resolvconf
|
||||
ub_val_ctx_add_ta
|
||||
ub_val_ctx_add_ta_file
|
||||
ub_val_ctx_trustedkeys
|
||||
ub_val_ctx_debuglevel
|
||||
ub_val_ctx_async
|
||||
ub_val_poll
|
||||
ub_val_wait
|
||||
ub_val_fd
|
||||
ub_val_process
|
||||
ub_val_resolve
|
||||
ub_val_resolve_async
|
||||
ub_val_cancel
|
||||
ub_val_resolve_free
|
||||
ub_val_strerror
|
||||
ub_ctx_create
|
||||
ub_ctx_delete
|
||||
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_file
|
||||
ub_ctx_trustedkeys
|
||||
ub_ctx_debugout
|
||||
ub_ctx_debuglevel
|
||||
ub_ctx_async
|
||||
ub_poll
|
||||
ub_wait
|
||||
ub_fd
|
||||
ub_process
|
||||
ub_resolve
|
||||
ub_resolve_async
|
||||
ub_cancel
|
||||
ub_resolve_free
|
||||
ub_strerror
|
||||
|
||||
+84
-44
@@ -43,29 +43,29 @@
|
||||
* to perform (validated) DNS lookups.
|
||||
*
|
||||
* All start with
|
||||
* ctx = ub_val_ctx_create();
|
||||
* err = ub_val_ctx_add_ta(ctx, "...");
|
||||
* err = ub_val_ctx_add_ta(ctx, "...");
|
||||
* ctx = ub_ctx_create();
|
||||
* err = ub_ctx_add_ta(ctx, "...");
|
||||
* err = ub_ctx_add_ta(ctx, "...");
|
||||
* ... some lookups
|
||||
* ... call ub_val_ctx_delete(ctx); when you want to stop.
|
||||
* ... call ub_ctx_delete(ctx); when you want to stop.
|
||||
*
|
||||
* Application not threaded. Blocking.
|
||||
* int err = ub_val_resolve(ctx, "www.example.com", ...
|
||||
* if(err) fprintf(stderr, "lookup error: %s\n", ub_val_strerror(err));
|
||||
* int err = ub_resolve(ctx, "www.example.com", ...
|
||||
* if(err) fprintf(stderr, "lookup error: %s\n", ub_strerror(err));
|
||||
* ... use the answer
|
||||
*
|
||||
* Application not threaded. Non-blocking ('asynchronous').
|
||||
* err = ub_val_resolve_async(ctx, "www.example.com", ... my_callback);
|
||||
* err = ub_resolve_async(ctx, "www.example.com", ... my_callback);
|
||||
* ... application resumes processing ...
|
||||
* ... and when either ub_val_poll(ctx) is true
|
||||
* ... or when the file descriptor ub_val_fd(ctx) is readable,
|
||||
* ... and when either ub_poll(ctx) is true
|
||||
* ... or when the file descriptor ub_fd(ctx) is readable,
|
||||
* ... or whenever, the app calls ...
|
||||
* ub_val_process(ctx);
|
||||
* ub_process(ctx);
|
||||
* ... if no result is ready, the app resumes processing above,
|
||||
* ... or process() calls my_callback() with results.
|
||||
*
|
||||
* ... if the application has nothing more to do, wait for answer
|
||||
* ub_val_wait(ctx);
|
||||
* ub_wait(ctx);
|
||||
*
|
||||
* Application threaded. Blocking.
|
||||
* Blocking, same as above. The current thread does the work.
|
||||
@@ -74,7 +74,7 @@
|
||||
*
|
||||
* Application threaded. Non-blocking ('asynchronous').
|
||||
* ... setup threaded-asynchronous config option
|
||||
* err = ub_val_ctx_async(ctx, 1);
|
||||
* err = ub_ctx_async(ctx, 1);
|
||||
* ... same as async for non-threaded
|
||||
* ... the callbacks are called in the thread that calls process(ctx)
|
||||
*
|
||||
@@ -84,7 +84,7 @@
|
||||
* Otherwise, for asynchronous with threading, a worker thread is created.
|
||||
*
|
||||
* The blocking calls use shared ctx-cache when threaded. Thus
|
||||
* ub_val_resolve() and ub_val_resolve_async() && ub_val_wait() are
|
||||
* ub_resolve() and ub_resolve_async() && ub_wait() are
|
||||
* not the same. The first makes the current thread do the work, setting
|
||||
* up buffers, etc, to perform the work (but using shared cache data).
|
||||
* The second calls another worker thread (or process) to perform the work.
|
||||
@@ -100,14 +100,14 @@
|
||||
*
|
||||
* Its contents are internally defined.
|
||||
*/
|
||||
struct ub_val_ctx;
|
||||
struct ub_ctx;
|
||||
|
||||
/**
|
||||
* The validation and resolution results.
|
||||
* Allocated by the resolver, and need to be freed by the application
|
||||
* with ub_val_resolve_free().
|
||||
* with ub_resolve_free().
|
||||
*/
|
||||
struct ub_val_result {
|
||||
struct ub_result {
|
||||
/** The original question, name text string. */
|
||||
char* qname;
|
||||
/** the type asked for */
|
||||
@@ -179,7 +179,7 @@ struct ub_val_result {
|
||||
/**
|
||||
* Callback for results of async queries.
|
||||
* The readable function definition looks like:
|
||||
* void my_callback(void* my_arg, int err, struct ub_val_result* result);
|
||||
* void my_callback(void* my_arg, int err, struct ub_result* result);
|
||||
* It is called with
|
||||
* void* my_arg: your pointer to a (struct of) data of your choice,
|
||||
* or NULL.
|
||||
@@ -187,23 +187,40 @@ struct ub_val_result {
|
||||
* are forthcoming.
|
||||
* struct result: pointer to more detailed result structure.
|
||||
* This structure is allocated on the heap and needs to be
|
||||
* freed with ub_val_resolve_free(result);
|
||||
* freed with ub_resolve_free(result);
|
||||
*/
|
||||
typedef void (*ub_val_callback_t)(void*, int, struct ub_val_result*);
|
||||
typedef void (*ub_callback_t)(void*, int, struct ub_result*);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return a new context. default initialisation.
|
||||
* returns NULL on error.
|
||||
*/
|
||||
struct ub_val_ctx* ub_val_ctx_create(void);
|
||||
struct ub_ctx* ub_ctx_create(void);
|
||||
|
||||
/**
|
||||
* Destroy a validation context and free all its resources.
|
||||
* Outstanding async queries are killed and callbacks are not called for them.
|
||||
* @param ctx: context to delete.
|
||||
*/
|
||||
void ub_val_ctx_delete(struct ub_val_ctx* ctx);
|
||||
void ub_ctx_delete(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Set an option for the context.
|
||||
* @param ctx: context.
|
||||
* @param opt: option name from the unbound.conf config file format.
|
||||
* (not all settings applicable). The name includes the trailing ':'
|
||||
* for example ub_ctx_set_option("logfile:", "mylog.txt");
|
||||
* This is a power-users interface that lets you specify all sorts
|
||||
* of options.
|
||||
* For some specific options, such as adding trust anchors, special
|
||||
* routines exist.
|
||||
* @param val: value of the option.
|
||||
* @return: 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val);
|
||||
|
||||
/**
|
||||
* setup configuration for the given context.
|
||||
@@ -215,7 +232,7 @@ void ub_val_ctx_delete(struct ub_val_ctx* ctx);
|
||||
* routines exist.
|
||||
* @return: 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname);
|
||||
int ub_ctx_config(struct ub_ctx* ctx, char* fname);
|
||||
|
||||
/**
|
||||
* Set machine to forward DNS queries to, the caching resolver to use.
|
||||
@@ -225,7 +242,7 @@ int ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname);
|
||||
* that case the addresses are used as backup servers.
|
||||
*
|
||||
* To read the list of nameservers from /etc/resolv.conf (from DHCP or so),
|
||||
* use the call ub_val_ctx_resolvconf.
|
||||
* use the call ub_ctx_resolvconf.
|
||||
*
|
||||
* @param ctx: context.
|
||||
* At this time it is only possible to set configuration before the
|
||||
@@ -234,7 +251,7 @@ int ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname);
|
||||
* If the addr is NULL, forwarding is disabled.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_set_fwd(struct ub_val_ctx* ctx, char* addr);
|
||||
int ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr);
|
||||
|
||||
/**
|
||||
* Read list of nameservers to use from the filename given.
|
||||
@@ -250,7 +267,20 @@ int ub_val_ctx_set_fwd(struct ub_val_ctx* ctx, char* addr);
|
||||
* @param fname: file name string. If NULL "/etc/resolv.conf" is used.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_resolvconf(struct ub_val_ctx* ctx, char* fname);
|
||||
int ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname);
|
||||
|
||||
/**
|
||||
* Read list of hosts from the filename given.
|
||||
* Usually "/etc/hosts".
|
||||
* These addresses are not flagged as DNSSEC secure when queried for.
|
||||
*
|
||||
* @param ctx: context.
|
||||
* At this time it is only possible to set configuration before the
|
||||
* first resolve is done.
|
||||
* @param fname: file name string. If NULL "/etc/hosts" is used.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_hosts(struct ub_ctx* ctx, char* fname);
|
||||
|
||||
/**
|
||||
* Add a trust anchor to the given context.
|
||||
@@ -263,7 +293,7 @@ int ub_val_ctx_resolvconf(struct ub_val_ctx* ctx, char* fname);
|
||||
* [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_add_ta(struct ub_val_ctx* ctx, char* ta);
|
||||
int ub_ctx_add_ta(struct ub_ctx* ctx, char* ta);
|
||||
|
||||
/**
|
||||
* Add trust anchors to the given context.
|
||||
@@ -274,7 +304,7 @@ int ub_val_ctx_add_ta(struct ub_val_ctx* ctx, char* ta);
|
||||
* @param fname: filename of file with keyfile with trust anchors.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_add_ta_file(struct ub_val_ctx* ctx, char* fname);
|
||||
int ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname);
|
||||
|
||||
/**
|
||||
* Add trust anchors to the given context.
|
||||
@@ -286,7 +316,17 @@ int ub_val_ctx_add_ta_file(struct ub_val_ctx* ctx, char* fname);
|
||||
* anchors.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_trustedkeys(struct ub_val_ctx* ctx, char* fname);
|
||||
int ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname);
|
||||
|
||||
/**
|
||||
* Set debug output (and error output) to the specified stream.
|
||||
* Pass NULL to disable. Default is stderr.
|
||||
* @param ctx: context.
|
||||
* @param out: FILE* out file stream to log to.
|
||||
* Type void* to avoid stdio dependency of this header file.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_debugout(struct ub_ctx* ctx, void* out);
|
||||
|
||||
/**
|
||||
* Set debug verbosity for the context
|
||||
@@ -296,7 +336,7 @@ int ub_val_ctx_trustedkeys(struct ub_val_ctx* ctx, char* fname);
|
||||
* and 3 is lots.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_debuglevel(struct ub_val_ctx* ctx, int d);
|
||||
int ub_ctx_debuglevel(struct ub_ctx* ctx, int d);
|
||||
|
||||
/**
|
||||
* Set a context behaviour for asynchronous action.
|
||||
@@ -308,7 +348,7 @@ int ub_val_ctx_debuglevel(struct ub_val_ctx* ctx, int d);
|
||||
* no effect (delete and re-create the context to change).
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_ctx_async(struct ub_val_ctx* ctx, int dothread);
|
||||
int ub_ctx_async(struct ub_ctx* ctx, int dothread);
|
||||
|
||||
/**
|
||||
* Poll a context to see if it has any new results
|
||||
@@ -318,27 +358,27 @@ int ub_val_ctx_async(struct ub_val_ctx* ctx, int dothread);
|
||||
* @return: 0 if nothing to read, or nonzero if a result is available.
|
||||
* If nonzero, call ctx_process() to do callbacks.
|
||||
*/
|
||||
int ub_val_poll(struct ub_val_ctx* ctx);
|
||||
int ub_poll(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Wait for a context to finish with results. Calls ub_val_process() after
|
||||
* Wait for a context to finish with results. Calls ub_process() after
|
||||
* the wait for you. After the wait, there are no more outstanding
|
||||
* asynchronous queries.
|
||||
* @param ctx: context.
|
||||
* @return: 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_wait(struct ub_val_ctx* ctx);
|
||||
int ub_wait(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Get file descriptor. Wait for it to become readable, at this point
|
||||
* answers are returned from the asynchronous validating resolver.
|
||||
* Then call the ub_val_process to continue processing.
|
||||
* Then call the ub_process to continue processing.
|
||||
* This routine works immediately after context creation, the fd
|
||||
* does not change.
|
||||
* @param ctx: context.
|
||||
* @return: -1 on error, or file descriptor to use select(2) with.
|
||||
*/
|
||||
int ub_val_fd(struct ub_val_ctx* ctx);
|
||||
int ub_fd(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Call this routine to continue processing results from the validating
|
||||
@@ -347,7 +387,7 @@ int ub_val_fd(struct ub_val_ctx* ctx);
|
||||
* @param ctx: context
|
||||
* @return: 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_process(struct ub_val_ctx* ctx);
|
||||
int ub_process(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Perform resolution and validation of the target name.
|
||||
@@ -361,8 +401,8 @@ int ub_val_process(struct ub_val_ctx* ctx);
|
||||
* in that case (out of memory).
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, struct ub_val_result** result);
|
||||
int ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, struct ub_result** result);
|
||||
|
||||
/**
|
||||
* Perform resolution and validation of the target name.
|
||||
@@ -379,7 +419,7 @@ int ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
* and is passed on to the callback function.
|
||||
* @param callback: this is called on completion of the resolution.
|
||||
* It is called as:
|
||||
* void callback(void* mydata, int err, struct ub_val_result* result)
|
||||
* void callback(void* mydata, int err, struct ub_result* result)
|
||||
* with mydata: the same as passed here, you may pass NULL,
|
||||
* with err: is 0 when a result has been found.
|
||||
* with result: a newly allocated result structure.
|
||||
@@ -392,8 +432,8 @@ int ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
* cancel the query.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_resolve_async(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_val_callback_t callback, int* async_id);
|
||||
int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_callback_t callback, int* async_id);
|
||||
|
||||
/**
|
||||
* Cancel an async query in progress.
|
||||
@@ -403,19 +443,19 @@ int ub_val_resolve_async(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||
* @param async_id: which query to cancel.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_val_cancel(struct ub_val_ctx* ctx, int async_id);
|
||||
int ub_cancel(struct ub_ctx* ctx, int async_id);
|
||||
|
||||
/**
|
||||
* Free storage associated with a result structure.
|
||||
* @param result: to free
|
||||
*/
|
||||
void ub_val_resolve_free(struct ub_val_result* result);
|
||||
void ub_resolve_free(struct ub_result* result);
|
||||
|
||||
/**
|
||||
* Convert error value to a human readable string.
|
||||
* @param err: error code from one of the ub_val* functions.
|
||||
* @return pointer to constant text string, zero terminated.
|
||||
*/
|
||||
const char* ub_val_strerror(int err);
|
||||
const char* ub_strerror(int err);
|
||||
|
||||
#endif /* _UB_UNBOUND_H */
|
||||
|
||||
@@ -213,6 +213,10 @@ fi
|
||||
|
||||
replace_all doc/README
|
||||
replace_all doc/unbound.8
|
||||
replace_all doc/unbound.conf.5
|
||||
replace_all doc/unbound-checkconf.8
|
||||
replace_all doc/unbound-host.1
|
||||
replace_all doc/libunbound.3
|
||||
|
||||
info "Renaming Unbound directory to unbound-$version."
|
||||
cd ..
|
||||
|
||||
+9
-8
@@ -768,20 +768,21 @@ mesh_log_list(struct mesh_area* mesh)
|
||||
void
|
||||
mesh_stats(struct mesh_area* mesh, const char* str)
|
||||
{
|
||||
log_info("%s %u states (%u with reply, %u detached), "
|
||||
"%u waiting replies", str, (unsigned)mesh->all.count,
|
||||
verbose(VERB_DETAIL, "%s %u recursion states (%u with reply, "
|
||||
"%u detached), %u waiting replies, %u recursion replies "
|
||||
"sent", str, (unsigned)mesh->all.count,
|
||||
(unsigned)mesh->num_reply_states,
|
||||
(unsigned)mesh->num_detached_states,
|
||||
(unsigned)mesh->num_reply_addrs);
|
||||
(unsigned)mesh->num_reply_addrs,
|
||||
(unsigned)mesh->replies_sent);
|
||||
if(mesh->replies_sent > 0) {
|
||||
struct timeval avg;
|
||||
timeval_divide(&avg, &mesh->replies_sum_wait,
|
||||
mesh->replies_sent);
|
||||
log_info("sent %u replies, with average wait "
|
||||
"of %d.%6.6d sec", (unsigned)mesh->replies_sent,
|
||||
(int)avg.tv_sec, (int)avg.tv_usec);
|
||||
log_info("histogram of reply wait times");
|
||||
timehist_log(mesh->histogram);
|
||||
log_info("average recursion processing time "
|
||||
"%d.%6.6d sec", (int)avg.tv_sec, (int)avg.tv_usec);
|
||||
log_info("histogram of recursion processing times");
|
||||
timehist_log(mesh->histogram, "recursions");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -176,7 +176,7 @@ massage_class(const char* c)
|
||||
|
||||
/** nice security status string */
|
||||
static const char*
|
||||
secure_str(struct ub_val_result* result)
|
||||
secure_str(struct ub_result* result)
|
||||
{
|
||||
if(result->secure) return "(secure)";
|
||||
if(result->bogus) return "(BOGUS (security failure))";
|
||||
@@ -274,7 +274,7 @@ pretty_rdata(char* q, char* cstr, char* tstr, int t, const char* sec,
|
||||
|
||||
/** pretty line of output for results */
|
||||
static void
|
||||
pretty_output(char* q, int t, int c, struct ub_val_result* result, int docname)
|
||||
pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
|
||||
{
|
||||
int i;
|
||||
const char *secstatus = secure_str(result);
|
||||
@@ -337,25 +337,25 @@ pretty_output(char* q, int t, int c, struct ub_val_result* result, int docname)
|
||||
|
||||
/** perform a lookup and printout return if domain existed */
|
||||
static int
|
||||
dnslook(struct ub_val_ctx* ctx, char* q, int t, int c, int docname)
|
||||
dnslook(struct ub_ctx* ctx, char* q, int t, int c, int docname)
|
||||
{
|
||||
int ret;
|
||||
struct ub_val_result* result;
|
||||
struct ub_result* result;
|
||||
|
||||
ret = ub_val_resolve(ctx, q, t, c, &result);
|
||||
ret = ub_resolve(ctx, q, t, c, &result);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "resolve error: %s\n", ub_val_strerror(ret));
|
||||
fprintf(stderr, "resolve error: %s\n", ub_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
pretty_output(q, t, c, result, docname);
|
||||
ret = result->nxdomain;
|
||||
ub_val_resolve_free(result);
|
||||
ub_resolve_free(result);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** perform host lookup */
|
||||
static void
|
||||
lookup(struct ub_val_ctx* ctx, const char* nm, const char* qt, const char* qc)
|
||||
lookup(struct ub_ctx* ctx, const char* nm, const char* qt, const char* qc)
|
||||
{
|
||||
/* massage input into a query name, type and class */
|
||||
int multi = 0; /* no type, so do A, AAAA, MX */
|
||||
@@ -374,7 +374,7 @@ lookup(struct ub_val_ctx* ctx, const char* nm, const char* qt, const char* qc)
|
||||
} else {
|
||||
(void)dnslook(ctx, realq, t, c, 1);
|
||||
}
|
||||
ub_val_ctx_delete(ctx);
|
||||
ub_ctx_delete(ctx);
|
||||
free(realq);
|
||||
}
|
||||
|
||||
@@ -389,10 +389,10 @@ int main(int argc, char* argv[])
|
||||
int c;
|
||||
char* qclass = NULL;
|
||||
char* qtype = NULL;
|
||||
struct ub_val_ctx* ctx = NULL;
|
||||
struct ub_ctx* ctx = NULL;
|
||||
int debuglevel = 0;
|
||||
|
||||
ctx = ub_val_ctx_create();
|
||||
ctx = ub_ctx_create();
|
||||
if(!ctx) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
exit(1);
|
||||
@@ -408,7 +408,7 @@ int main(int argc, char* argv[])
|
||||
debuglevel++;
|
||||
if(debuglevel < 2)
|
||||
debuglevel = 2; /* at least VERB_DETAIL */
|
||||
ub_val_ctx_debuglevel(ctx, debuglevel);
|
||||
ub_ctx_debuglevel(ctx, debuglevel);
|
||||
break;
|
||||
case 't':
|
||||
qtype = optarg;
|
||||
@@ -417,13 +417,13 @@ int main(int argc, char* argv[])
|
||||
verb++;
|
||||
break;
|
||||
case 'y':
|
||||
ub_val_ctx_add_ta(ctx, optarg);
|
||||
ub_ctx_add_ta(ctx, optarg);
|
||||
break;
|
||||
case 'f':
|
||||
ub_val_ctx_add_ta_file(ctx, optarg);
|
||||
ub_ctx_add_ta_file(ctx, optarg);
|
||||
break;
|
||||
case 'F':
|
||||
ub_val_ctx_trustedkeys(ctx, optarg);
|
||||
ub_ctx_trustedkeys(ctx, optarg);
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
|
||||
+56
-45
@@ -56,7 +56,7 @@ struct lookinfo {
|
||||
/** error code from libunbound */
|
||||
int err;
|
||||
/** result from lookup */
|
||||
struct ub_val_result* result;
|
||||
struct ub_result* result;
|
||||
};
|
||||
|
||||
/** global variable to see how many queries we have left */
|
||||
@@ -72,6 +72,7 @@ void usage(char* argv[])
|
||||
printf(" -d : enable debug output\n");
|
||||
printf(" -f addr : use addr, forward to that server\n");
|
||||
printf(" -h : this help message\n");
|
||||
printf(" -H fname : read hosts from fname\n");
|
||||
printf(" -r fname : read resolv.conf from fname\n");
|
||||
printf(" -t : use a resolver thread instead of forking a process\n");
|
||||
printf(" -x : perform extended threaded test\n");
|
||||
@@ -85,7 +86,7 @@ print_result(struct lookinfo* info)
|
||||
char buf[100];
|
||||
if(info->err) /* error (from libunbound) */
|
||||
printf("%s: error %s\n", info->name,
|
||||
ub_val_strerror(info->err));
|
||||
ub_strerror(info->err));
|
||||
else if(!info->result)
|
||||
printf("%s: cancelled\n", info->name);
|
||||
else if(info->result->havedata)
|
||||
@@ -105,9 +106,9 @@ print_result(struct lookinfo* info)
|
||||
}
|
||||
}
|
||||
|
||||
/** this is a function of type ub_val_callback_t */
|
||||
/** this is a function of type ub_callback_t */
|
||||
static void
|
||||
lookup_is_done(void* mydata, int err, struct ub_val_result* result)
|
||||
lookup_is_done(void* mydata, int err, struct ub_result* result)
|
||||
{
|
||||
/* cast mydata back to the correct type */
|
||||
struct lookinfo* info = (struct lookinfo*)mydata;
|
||||
@@ -123,7 +124,7 @@ static void
|
||||
checkerr(const char* desc, int err)
|
||||
{
|
||||
if(err != 0) {
|
||||
printf("%s error: %s\n", desc, ub_val_strerror(err));
|
||||
printf("%s error: %s\n", desc, ub_strerror(err));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -143,7 +144,7 @@ struct ext_thr_info {
|
||||
/** thread id */
|
||||
ub_thread_t tid;
|
||||
/** context */
|
||||
struct ub_val_ctx* ctx;
|
||||
struct ub_ctx* ctx;
|
||||
/** size of array to query */
|
||||
int argc;
|
||||
/** array of names to query */
|
||||
@@ -157,7 +158,7 @@ static int q_is_localhost = 0;
|
||||
|
||||
/** check result structure for the 'correct' answer */
|
||||
static void
|
||||
ext_check_result(const char* desc, int err, struct ub_val_result* result)
|
||||
ext_check_result(const char* desc, int err, struct ub_result* result)
|
||||
{
|
||||
checkerr(desc, err);
|
||||
if(result == NULL) {
|
||||
@@ -218,9 +219,9 @@ ext_check_result(const char* desc, int err, struct ub_val_result* result)
|
||||
}
|
||||
}
|
||||
|
||||
/** extended bg result callback, this function is ub_val_callback_t */
|
||||
/** extended bg result callback, this function is ub_callback_t */
|
||||
static void
|
||||
ext_callback(void* mydata, int err, struct ub_val_result* result)
|
||||
ext_callback(void* mydata, int err, struct ub_result* result)
|
||||
{
|
||||
int* my_id = (int*)mydata;
|
||||
int doprint = 0;
|
||||
@@ -243,7 +244,7 @@ ext_callback(void* mydata, int err, struct ub_val_result* result)
|
||||
pi.err = 0;
|
||||
print_result(&pi);
|
||||
}
|
||||
ub_val_resolve_free(result);
|
||||
ub_resolve_free(result);
|
||||
}
|
||||
|
||||
/** extended thread worker */
|
||||
@@ -252,7 +253,7 @@ ext_thread(void* arg)
|
||||
{
|
||||
struct ext_thr_info* inf = (struct ext_thr_info*)arg;
|
||||
int i, r;
|
||||
struct ub_val_result* result;
|
||||
struct ub_result* result;
|
||||
int* async_ids = NULL;
|
||||
log_thread_set(&inf->thread_num);
|
||||
if(inf->thread_num > NUMTHR*2/3) {
|
||||
@@ -264,32 +265,32 @@ ext_thread(void* arg)
|
||||
}
|
||||
for(i=0; i<inf->numq; i++) {
|
||||
if(async_ids) {
|
||||
r = ub_val_resolve_async(inf->ctx,
|
||||
r = ub_resolve_async(inf->ctx,
|
||||
inf->argv[i%inf->argc], LDNS_RR_TYPE_A,
|
||||
LDNS_RR_CLASS_IN, &async_ids[i], ext_callback,
|
||||
&async_ids[i]);
|
||||
checkerr("ub_val_resolve_async", r);
|
||||
checkerr("ub_resolve_async", r);
|
||||
if(i > 100) {
|
||||
r = ub_val_cancel(inf->ctx, async_ids[i-100]);
|
||||
checkerr("ub_val_cancel", r);
|
||||
r = ub_cancel(inf->ctx, async_ids[i-100]);
|
||||
checkerr("ub_cancel", r);
|
||||
async_ids[i-100]=0;
|
||||
}
|
||||
} else if(inf->thread_num > NUMTHR/2) {
|
||||
/* async */
|
||||
r = ub_val_resolve_async(inf->ctx,
|
||||
r = ub_resolve_async(inf->ctx,
|
||||
inf->argv[i%inf->argc], LDNS_RR_TYPE_A,
|
||||
LDNS_RR_CLASS_IN, NULL, ext_callback, NULL);
|
||||
checkerr("ub_val_resolve_async", r);
|
||||
checkerr("ub_resolve_async", r);
|
||||
} else {
|
||||
/* blocking */
|
||||
r = ub_val_resolve(inf->ctx, inf->argv[i%inf->argc],
|
||||
r = ub_resolve(inf->ctx, inf->argv[i%inf->argc],
|
||||
LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &result);
|
||||
ext_check_result("ub_val_resolve", r, result);
|
||||
ext_check_result("ub_resolve", r, result);
|
||||
}
|
||||
}
|
||||
if(inf->thread_num > NUMTHR/2) {
|
||||
r = ub_val_wait(inf->ctx);
|
||||
checkerr("ub_val_ctx_wait", r);
|
||||
r = ub_wait(inf->ctx);
|
||||
checkerr("ub_ctx_wait", r);
|
||||
}
|
||||
free(async_ids);
|
||||
|
||||
@@ -298,7 +299,7 @@ ext_thread(void* arg)
|
||||
|
||||
/** perform extended threaded test */
|
||||
static int
|
||||
ext_test(struct ub_val_ctx* ctx, int argc, char** argv)
|
||||
ext_test(struct ub_ctx* ctx, int argc, char** argv)
|
||||
{
|
||||
struct ext_thr_info inf[NUMTHR];
|
||||
int i;
|
||||
@@ -319,7 +320,7 @@ ext_test(struct ub_val_ctx* ctx, int argc, char** argv)
|
||||
ub_thread_join(inf[i].tid);
|
||||
}
|
||||
printf("extended test end\n");
|
||||
ub_val_ctx_delete(ctx);
|
||||
ub_ctx_delete(ctx);
|
||||
checklock_stop();
|
||||
return 0;
|
||||
}
|
||||
@@ -333,7 +334,7 @@ extern char* optarg;
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int c;
|
||||
struct ub_val_ctx* ctx;
|
||||
struct ub_ctx* ctx;
|
||||
struct lookinfo* lookups;
|
||||
int i, r, cancel=0, blocking=0, ext=0;
|
||||
|
||||
@@ -341,7 +342,7 @@ int main(int argc, char** argv)
|
||||
checklock_start();
|
||||
|
||||
/* create context */
|
||||
ctx = ub_val_ctx_create();
|
||||
ctx = ub_ctx_create();
|
||||
if(!ctx) {
|
||||
printf("could not create context, %s\n", strerror(errno));
|
||||
return 1;
|
||||
@@ -351,15 +352,15 @@ int main(int argc, char** argv)
|
||||
if(argc == 1) {
|
||||
usage(argv);
|
||||
}
|
||||
while( (c=getopt(argc, argv, "bcdf:hr:tx")) != -1) {
|
||||
while( (c=getopt(argc, argv, "bcdf:hH:r:tx")) != -1) {
|
||||
switch(c) {
|
||||
case 'd':
|
||||
r = ub_val_ctx_debuglevel(ctx, 3);
|
||||
checkerr("ub_val_ctx_debuglevel", r);
|
||||
r = ub_ctx_debuglevel(ctx, 3);
|
||||
checkerr("ub_ctx_debuglevel", r);
|
||||
break;
|
||||
case 't':
|
||||
r = ub_val_ctx_async(ctx, 1);
|
||||
checkerr("ub_val_ctx_async", r);
|
||||
r = ub_ctx_async(ctx, 1);
|
||||
checkerr("ub_ctx_async", r);
|
||||
break;
|
||||
case 'c':
|
||||
cancel = 1;
|
||||
@@ -368,18 +369,28 @@ int main(int argc, char** argv)
|
||||
blocking = 1;
|
||||
break;
|
||||
case 'r':
|
||||
r = ub_val_ctx_resolvconf(ctx, optarg);
|
||||
r = ub_ctx_resolvconf(ctx, optarg);
|
||||
if(r != 0) {
|
||||
printf("ub_val_ctx_resolvconf "
|
||||
printf("ub_ctx_resolvconf "
|
||||
"error: %s : %s\n",
|
||||
ub_val_strerror(r),
|
||||
ub_strerror(r),
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
r = ub_ctx_hosts(ctx, optarg);
|
||||
if(r != 0) {
|
||||
printf("ub_ctx_hosts "
|
||||
"error: %s : %s\n",
|
||||
ub_strerror(r),
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
r = ub_val_ctx_set_fwd(ctx, optarg);
|
||||
checkerr("ub_val_ctx_set_fwd", r);
|
||||
r = ub_ctx_set_fwd(ctx, optarg);
|
||||
checkerr("ub_ctx_set_fwd", r);
|
||||
break;
|
||||
case 'x':
|
||||
ext = 1;
|
||||
@@ -410,15 +421,15 @@ int main(int argc, char** argv)
|
||||
lookups[i].name = argv[i];
|
||||
if(blocking) {
|
||||
fprintf(stderr, "lookup %s\n", argv[i]);
|
||||
r = ub_val_resolve(ctx, argv[i], LDNS_RR_TYPE_A,
|
||||
r = ub_resolve(ctx, argv[i], LDNS_RR_TYPE_A,
|
||||
LDNS_RR_CLASS_IN, &lookups[i].result);
|
||||
checkerr("ub_val_resolve", r);
|
||||
checkerr("ub_resolve", r);
|
||||
} else {
|
||||
fprintf(stderr, "start async lookup %s\n", argv[i]);
|
||||
r = ub_val_resolve_async(ctx, argv[i], LDNS_RR_TYPE_A,
|
||||
r = ub_resolve_async(ctx, argv[i], LDNS_RR_TYPE_A,
|
||||
LDNS_RR_CLASS_IN, &lookups[i], &lookup_is_done,
|
||||
&lookups[i].async_id);
|
||||
checkerr("ub_val_resolve_async", r);
|
||||
checkerr("ub_resolve_async", r);
|
||||
}
|
||||
}
|
||||
if(blocking)
|
||||
@@ -426,8 +437,8 @@ int main(int argc, char** argv)
|
||||
else if(cancel) {
|
||||
for(i=0; i<argc; i++) {
|
||||
fprintf(stderr, "cancel %s\n", argv[i]);
|
||||
r = ub_val_cancel(ctx, lookups[i].async_id);
|
||||
checkerr("ub_val_cancel", r);
|
||||
r = ub_cancel(ctx, lookups[i].async_id);
|
||||
checkerr("ub_cancel", r);
|
||||
}
|
||||
num_wait = 0;
|
||||
}
|
||||
@@ -437,8 +448,8 @@ int main(int argc, char** argv)
|
||||
for(i=0; i<1000; i++) {
|
||||
usleep(100000);
|
||||
fprintf(stderr, "%g seconds passed\n", 0.1*(double)i);
|
||||
r = ub_val_process(ctx);
|
||||
checkerr("ub_val_process", r);
|
||||
r = ub_process(ctx);
|
||||
checkerr("ub_process", r);
|
||||
if(num_wait == 0)
|
||||
break;
|
||||
}
|
||||
@@ -451,10 +462,10 @@ int main(int argc, char** argv)
|
||||
/* print lookup results */
|
||||
for(i=0; i<argc; i++) {
|
||||
print_result(&lookups[i]);
|
||||
ub_val_resolve_free(lookups[i].result);
|
||||
ub_resolve_free(lookups[i].result);
|
||||
}
|
||||
|
||||
ub_val_ctx_delete(ctx);
|
||||
ub_ctx_delete(ctx);
|
||||
free(lookups);
|
||||
checklock_stop();
|
||||
return 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
NEED_SPLINT='00-lint.tpkg'
|
||||
NEED_DOXYGEN='01-doc.tpkg'
|
||||
NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_service.tpkg fwd_three.tpkg fwd_ttlexpire.tpkg fwd_udp.tpkg fwd_tcp_tc6.tpkg fwd_compress_c00c.tpkg fwd_ancil.tpkg stat_timer.tpkg'
|
||||
NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_service.tpkg fwd_three.tpkg fwd_ttlexpire.tpkg fwd_udp.tpkg fwd_tcp_tc6.tpkg fwd_compress_c00c.tpkg fwd_ancil.tpkg stat_timer.tpkg 05-asynclook.tpkg stream_tcp.tpkg'
|
||||
NEED_XXD='fwd_compress_c00c.tpkg'
|
||||
NEED_NC='fwd_compress_c00c.tpkg'
|
||||
|
||||
|
||||
Vendored
BIN
Binary file not shown.
@@ -164,6 +164,168 @@ struct config_file* config_create_forlib()
|
||||
return cfg;
|
||||
}
|
||||
|
||||
/** check that the value passed is >= 0 */
|
||||
#define IS_NUMBER_OR_ZERO \
|
||||
if(atoi(val) == 0 && strcmp(val, "0") != 0) return 0
|
||||
/** check that the value passed is > 0 */
|
||||
#define IS_NONZERO_NUMBER \
|
||||
if(atoi(val) == 0) return 0
|
||||
/** check that the value passed is not 0 and a power of 2 */
|
||||
#define IS_POW2_NUMBER \
|
||||
if(atoi(val) == 0 || !is_pow2((size_t)atoi(val))) return 0
|
||||
/** check that the value passed is yes or no */
|
||||
#define IS_YES_OR_NO \
|
||||
if(strcmp(val, "yes") != 0 && strcmp(val, "no") != 0) return 0
|
||||
|
||||
int config_set_option(struct config_file* cfg, const char* opt,
|
||||
const char* val)
|
||||
{
|
||||
if(strcmp(opt, "verbosity:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->verbosity = atoi(val);
|
||||
} else if(strcmp(opt, "statistics-interval:") == 0) {
|
||||
if(strcmp(val, "0") == 0 || strcmp(val, "") == 0)
|
||||
cfg->stat_interval = 0;
|
||||
else if(atoi(val) == 0)
|
||||
return 0;
|
||||
else cfg->stat_interval = atoi(val);
|
||||
} else if(strcmp(opt, "num_threads:") == 0) {
|
||||
/* not supported, library must have 1 thread in bgworker */
|
||||
return 0;
|
||||
} else if(strcmp(opt, "do-ip4:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->do_ip4 = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "do-ip6:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->do_ip6 = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "do-udp:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->do_udp = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "do-tcp:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->do_tcp = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "outgoing-port:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->outgoing_base_port = atoi(val);
|
||||
} else if(strcmp(opt, "outgoing-range:") == 0) {
|
||||
IS_NONZERO_NUMBER;
|
||||
cfg->outgoing_num_ports = atoi(val);
|
||||
} else if(strcmp(opt, "outgoing-num-tcp:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->outgoing_num_tcp = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "incoming-num-tcp:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->incoming_num_tcp = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "msg-buffer-size:") == 0) {
|
||||
IS_NONZERO_NUMBER;
|
||||
cfg->msg_buffer_size = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "msg-cache-size:") == 0) {
|
||||
return cfg_parse_memsize(val, &cfg->msg_cache_size);
|
||||
} else if(strcmp(opt, "msg-cache-slabs:") == 0) {
|
||||
IS_POW2_NUMBER;
|
||||
cfg->msg_cache_slabs = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "num-queries-per-thread:") == 0) {
|
||||
IS_NONZERO_NUMBER;
|
||||
cfg->num_queries_per_thread = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "rrset-cache-size:") == 0) {
|
||||
return cfg_parse_memsize(val, &cfg->rrset_cache_size);
|
||||
} else if(strcmp(opt, "rrset-cache-slabs:") == 0) {
|
||||
IS_POW2_NUMBER;
|
||||
cfg->rrset_cache_slabs = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "cache-max-ttl:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->max_ttl = atoi(val);
|
||||
} else if(strcmp(opt, "infra-host-ttl:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->host_ttl = atoi(val);
|
||||
} else if(strcmp(opt, "infra-lame-ttl:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->lame_ttl = atoi(val);
|
||||
} else if(strcmp(opt, "infra-cache-slabs:") == 0) {
|
||||
IS_POW2_NUMBER;
|
||||
cfg->infra_cache_slabs = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "infra-cache-numhosts:") == 0) {
|
||||
IS_NONZERO_NUMBER;
|
||||
cfg->infra_cache_numhosts = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "infra-cache-lame-size:") == 0) {
|
||||
return cfg_parse_memsize(val, &cfg->infra_cache_lame_size);
|
||||
} else if(strcmp(opt, "logfile:") == 0) {
|
||||
cfg->use_syslog = 0;
|
||||
free(cfg->logfile);
|
||||
return (cfg->logfile = strdup(val)) != NULL;
|
||||
} else if(strcmp(opt, "use-syslog:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->use_syslog = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "root-hints:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->root_hints, strdup(val));
|
||||
} else if(strcmp(opt, "target-fetch-policy:") == 0) {
|
||||
free(cfg->target_fetch_policy);
|
||||
return (cfg->target_fetch_policy = strdup(val)) != NULL;
|
||||
} else if(strcmp(opt, "harden-glue:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->harden_glue = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "harden-short-bufsize:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->harden_short_bufsize = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "harden-large-queries:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->harden_large_queries = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "harden-dnssec-stripped:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->harden_dnssec_stripped = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "do-not-query-localhost:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->donotquery_localhost = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "do-not-query-address:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->donotqueryaddrs, strdup(val));
|
||||
} else if(strcmp(opt, "trust-anchor-file:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->trust_anchor_file_list,
|
||||
strdup(val));
|
||||
} else if(strcmp(opt, "trust-anchor:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->trust_anchor_list,
|
||||
strdup(val));
|
||||
} else if(strcmp(opt, "trusted-keys-file:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->trusted_keys_file_list,
|
||||
strdup(val));
|
||||
} else if(strcmp(opt, "val-override-date:") == 0) {
|
||||
if(strcmp(val, "") == 0 || strcmp(val, "0") == 0) {
|
||||
cfg->val_date_override = 0;
|
||||
} else if(strlen(val) == 14) {
|
||||
cfg->val_date_override = cfg_convert_timeval(val);
|
||||
return cfg->val_date_override != 0;
|
||||
} else {
|
||||
if(atoi(val) == 0) return 0;
|
||||
cfg->val_date_override = (uint32_t)atoi(val);
|
||||
}
|
||||
} else if(strcmp(opt, "val-bogus-ttl:") == 0) {
|
||||
IS_NUMBER_OR_ZERO;
|
||||
cfg->bogus_ttl = atoi(val);
|
||||
} else if(strcmp(opt, "val-clean-additional:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->val_clean_additional = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "val-permissive-mode:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->val_permissive_mode = (strcmp(val, "yes") == 0);
|
||||
} else if(strcmp(opt, "val-nsec3-keysize-iterations:") == 0) {
|
||||
free(cfg->val_nsec3_key_iterations);
|
||||
return (cfg->val_nsec3_key_iterations = strdup(val)) != NULL;
|
||||
} else if(strcmp(opt, "key-cache-size:") == 0) {
|
||||
return cfg_parse_memsize(val, &cfg->key_cache_size);
|
||||
} else if(strcmp(opt, "key-cache-slabs:") == 0) {
|
||||
IS_POW2_NUMBER;
|
||||
cfg->key_cache_slabs = (size_t)atoi(val);
|
||||
} else if(strcmp(opt, "local-data:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->local_data, strdup(val));
|
||||
} else if(strcmp(opt, "module-config:") == 0) {
|
||||
free(cfg->module_conf);
|
||||
return (cfg->module_conf = strdup(val)) != NULL;
|
||||
} else {
|
||||
/* unknown or unsupported (from the library interface) */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** initialize the global cfg_parser object */
|
||||
static void
|
||||
create_cfg_parser(struct config_file* cfg, char* filename)
|
||||
|
||||
@@ -271,6 +271,17 @@ void config_delete(struct config_file* config);
|
||||
*/
|
||||
void config_apply(struct config_file* config);
|
||||
|
||||
/**
|
||||
* Set the given keyword to the given value.
|
||||
* @param config: where to store config
|
||||
* @param option: option name, including the ':' character.
|
||||
* @param value: value, this string is copied if needed, or parsed.
|
||||
* The caller owns the value string.
|
||||
* @return 0 on error (malloc or syntax error).
|
||||
*/
|
||||
int config_set_option(struct config_file* config, const char* option,
|
||||
const char* value);
|
||||
|
||||
/**
|
||||
* Insert string into strlist.
|
||||
* @param head: pointer to strlist head variable.
|
||||
|
||||
+7
-1
@@ -104,7 +104,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
|
||||
}
|
||||
/* open the file for logging */
|
||||
if(chrootdir && chrootdir[0] && strncmp(filename, chrootdir,
|
||||
strlen(chrootdir)) == 0)
|
||||
strlen(chrootdir)) == 0)
|
||||
filename += strlen(chrootdir);
|
||||
f = fopen(filename, "a");
|
||||
if(!f) {
|
||||
@@ -115,6 +115,11 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
|
||||
logfile = f;
|
||||
}
|
||||
|
||||
void log_file(FILE *f)
|
||||
{
|
||||
logfile = f;
|
||||
}
|
||||
|
||||
void log_thread_set(int* num)
|
||||
{
|
||||
ub_thread_key_set(logkey, num);
|
||||
@@ -140,6 +145,7 @@ log_vmsg(int pri, const char* type,
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_SYSLOG_H */
|
||||
if(!logfile) return;
|
||||
fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n", (int)time(NULL),
|
||||
ident, (int)getpid(), tid?*tid:0, type, message);
|
||||
fflush(logfile);
|
||||
|
||||
@@ -84,6 +84,13 @@ void verbose(enum verbosity_value level,
|
||||
*/
|
||||
void log_init(const char* filename, int use_syslog, const char* chrootdir);
|
||||
|
||||
/**
|
||||
* Set logging to go to the specified file *.
|
||||
* This setting does not affect the use_syslog setting.
|
||||
* @param f: to that file, or pass NULL to disable logging.
|
||||
*/
|
||||
void log_file(FILE *f);
|
||||
|
||||
/**
|
||||
* Init a thread (will print this number for the thread log entries).
|
||||
* Must be called from the thread itself. If not called 0 is printed.
|
||||
|
||||
+2
-2
@@ -156,7 +156,7 @@ void timehist_print(struct timehist* hist)
|
||||
#endif
|
||||
}
|
||||
|
||||
void timehist_log(struct timehist* hist)
|
||||
void timehist_log(struct timehist* hist, const char* name)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
size_t i;
|
||||
@@ -165,7 +165,7 @@ void timehist_log(struct timehist* hist)
|
||||
timehist_quartile(hist, 0.50),
|
||||
timehist_quartile(hist, 0.75));
|
||||
/* 0000.000000 0000.000000 0 */
|
||||
log_info("lower(secs) upper(secs) replycount");
|
||||
log_info("lower(secs) upper(secs) %s", name);
|
||||
for(i=0; i<hist->num; i++) {
|
||||
if(hist->buckets[i].count != 0) {
|
||||
log_info("%4d.%6.6d %4d.%6.6d %u",
|
||||
|
||||
+2
-1
@@ -108,7 +108,8 @@ void timehist_print(struct timehist* hist);
|
||||
/**
|
||||
* Log histogram, print it to the logfile.
|
||||
* @param hist: histogram
|
||||
* @param name: the name of the value column
|
||||
*/
|
||||
void timehist_log(struct timehist* hist);
|
||||
void timehist_log(struct timehist* hist, const char* name);
|
||||
|
||||
#endif /* UTIL_TIMEHIST_H */
|
||||
|
||||
+10
-3
@@ -53,8 +53,8 @@
|
||||
#include "util/regional.h"
|
||||
|
||||
enum val_classification
|
||||
val_classify_response(uint16_t query_flags, struct query_info* qinf,
|
||||
struct reply_info* rep, size_t skip)
|
||||
val_classify_response(uint16_t query_flags, struct query_info* origqinf,
|
||||
struct query_info* qinf, struct reply_info* rep, size_t skip)
|
||||
{
|
||||
int rcode = (int)FLAGS_GET_RCODE(rep->flags);
|
||||
size_t i;
|
||||
@@ -82,7 +82,14 @@ val_classify_response(uint16_t query_flags, struct query_info* qinf,
|
||||
}
|
||||
return saw_ns?VAL_CLASS_REFERRAL:VAL_CLASS_NODATA;
|
||||
}
|
||||
|
||||
/* root referral where NS set is in the answer section */
|
||||
if(!(query_flags&BIT_RD) && rep->ns_numrrsets == 0 &&
|
||||
rep->an_numrrsets == 1 && rcode == LDNS_RCODE_NOERROR &&
|
||||
ntohs(rep->rrsets[0]->rk.type) == LDNS_RR_TYPE_NS &&
|
||||
query_dname_compare(rep->rrsets[0]->rk.dname,
|
||||
origqinf->qname) != 0)
|
||||
return VAL_CLASS_REFERRAL;
|
||||
|
||||
/* dump bad messages */
|
||||
if(rcode != LDNS_RCODE_NOERROR)
|
||||
return VAL_CLASS_UNKNOWN;
|
||||
|
||||
@@ -80,6 +80,7 @@ enum val_classification {
|
||||
/**
|
||||
* Given a response, classify ANSWER responses into a subtype.
|
||||
* @param query_flags: query flags for the original query.
|
||||
* @param origqinf: query info. The original query name.
|
||||
* @param qinf: query info. The chased query name.
|
||||
* @param rep: response. The original response.
|
||||
* @param skip: offset into the original response answer section.
|
||||
@@ -88,7 +89,8 @@ enum val_classification {
|
||||
* Then, another CNAME type, CNAME_NOANSWER or POSITIVE are possible.
|
||||
*/
|
||||
enum val_classification val_classify_response(uint16_t query_flags,
|
||||
struct query_info* qinf, struct reply_info* rep, size_t skip);
|
||||
struct query_info* origqinf, struct query_info* qinf,
|
||||
struct reply_info* rep, size_t skip);
|
||||
|
||||
/**
|
||||
* Given a response, determine the name of the "signer". This is primarily
|
||||
|
||||
@@ -1090,8 +1090,8 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
uint8_t* lookup_name;
|
||||
size_t lookup_len;
|
||||
enum val_classification subtype = val_classify_response(
|
||||
qstate->query_flags, &vq->qchase, vq->orig_msg->rep,
|
||||
vq->rrset_skip);
|
||||
qstate->query_flags, &qstate->qinfo, &vq->qchase,
|
||||
vq->orig_msg->rep, vq->rrset_skip);
|
||||
verbose(VERB_ALGO, "validator classification %s",
|
||||
val_classification_to_string(subtype));
|
||||
if(subtype == VAL_CLASS_REFERRAL &&
|
||||
@@ -1388,8 +1388,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
return 1;
|
||||
}
|
||||
|
||||
subtype = val_classify_response(qstate->query_flags, &vq->qchase,
|
||||
vq->orig_msg->rep, vq->rrset_skip);
|
||||
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
||||
&vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
|
||||
switch(subtype) {
|
||||
case VAL_CLASS_POSITIVE:
|
||||
verbose(VERB_ALGO, "Validating a positive response");
|
||||
@@ -1478,8 +1478,8 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct val_env* ve, int id)
|
||||
{
|
||||
enum val_classification subtype = val_classify_response(
|
||||
qstate->query_flags, &vq->qchase, vq->orig_msg->rep,
|
||||
vq->rrset_skip);
|
||||
qstate->query_flags, &qstate->qinfo, &vq->qchase,
|
||||
vq->orig_msg->rep, vq->rrset_skip);
|
||||
|
||||
/* store overall validation result in orig_msg */
|
||||
if(vq->rrset_skip == 0)
|
||||
@@ -1787,7 +1787,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
subtype = val_classify_response(BIT_RD, qinfo, msg->rep, 0);
|
||||
subtype = val_classify_response(BIT_RD, qinfo, qinfo, msg->rep, 0);
|
||||
if(subtype == VAL_CLASS_POSITIVE) {
|
||||
struct ub_packed_rrset_key* ds;
|
||||
enum sec_status sec;
|
||||
|
||||
Reference in New Issue
Block a user