- allow-notify: config statement for auth-zones.

git-svn-id: file:///svn/unbound/trunk@4628 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2018-04-17 13:23:35 +00:00
parent 630600e70d
commit 1b055c6ca7
12 changed files with 3081 additions and 2990 deletions

View file

@ -1,5 +1,6 @@
17 April 2018: Wouter
- auth zone notify work.
- allow-notify: config statement for auth-zones.
16 April 2018: Wouter
- Fix auth zone target lookup iterator.

View file

@ -832,6 +832,8 @@ remote-control:
# has a copy of the root for local usage. The second serves example.org
# authoritatively. zonefile: reads from file (and writes to it if you also
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from masters) sources of
# notifies.
# auth-zone:
# name: "."
# for-downstream: no

View file

@ -1518,6 +1518,14 @@ If none of the urls work, the masters are tried with IXFR and AXFR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection.
.TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer.
If the notify is from a master, it first attempts that master. Otherwise
other masters are attempted. If there are no masters, but only urls, the
file is downloaded when notified. The masters from master: statements are
allowed notify by default.
.TP
.B fallback\-enabled: \fI<yes or no>
Default no. If enabled, unbound falls back to querying the internet as
a resolver for this zone when lookups fail. For example for DNSSEC

View file

@ -3267,8 +3267,8 @@ addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
}
/* prefixes, addr/len, like 10.0.0.0/8 */
/* not http and has a / and there is one / */
/* TODO: for allow-notify elements */
if(!master->http && strchr(master->host, '/')!=NULL &&
if(master->allow_notify && !master->http &&
strchr(master->host, '/') != NULL &&
strchr(master->host, '/') == strrchr(master->host, '/') &&
netblockstrtoaddr(master->host, UNBOUND_DNS_PORT, &a, &alen,
&net) && alen == addrlen) {
@ -4808,6 +4808,9 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
/* not needed, host is in IP addr format */
return 0;
}
if(master->allow_notify)
return 0; /* allow-notifies are not transferred from, no
lookup is needed */
/* use mesh_new_callback to probe for non-addr hosts,
* and then wait for them to be looked up (in cache, or query) */
@ -4862,6 +4865,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
socklen_t addrlen = 0;
struct auth_master* master = xfr->task_transfer->master;
if(!master) return 0;
if(master->allow_notify) return 0; /* only for notify */
/* get master addr */
if(xfr->task_transfer->scan_addr) {
@ -5615,6 +5619,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
/* pick master */
struct auth_master* master = xfr_probe_current_master(xfr);
if(!master) return 0;
if(master->allow_notify) return 0; /* only for notify */
/* get master addr */
if(xfr->task_probe->scan_addr) {
@ -5812,6 +5817,11 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
/* not needed, host is in IP addr format */
return 0;
}
if(master->allow_notify && !master->http &&
strchr(master->host, '/') != NULL &&
strchr(master->host, '/') == strrchr(master->host, '/')) {
return 0; /* is IP/prefix format, not something to look up */
}
/* use mesh_new_callback to probe for non-addr hosts,
* and then wait for them to be looked up (in cache, or query) */
@ -5874,11 +5884,6 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
}
xfr_probe_move_to_next_lookup(xfr, env);
}
/* TODO Also lookup notify in masterlist.
* but skip them for xfr and probe attempts. (allow_notify_only).
* and here, copy the list of addresses for the masters/notifies
* to a separate list.
*/
/* probe of list has ended. Create or refresh the list of of
* allow_notify addrs */
probe_copy_masters_for_allow_notify(xfr);
@ -6000,6 +6005,18 @@ auth_xfer_timer(void* arg)
}
}
/** return true if there are probe (SOA UDP query) targets in the master list*/
static int
have_probe_targets(struct auth_master* list)
{
struct auth_master* p;
for(p=list; p; p = p->next) {
if(!p->allow_notify && p->host)
return 1;
}
return 0;
}
/** start task_probe if possible, if no masters for probe start task_transfer
* returns true if task has been started, and false if the task is already
* in progress. */
@ -6010,7 +6027,9 @@ xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
/* see if we need to start a probe (or maybe it is already in
* progress (due to notify)) */
if(xfr->task_probe->worker == NULL) {
if(xfr->task_probe->masters == NULL) {
if(!have_probe_targets(xfr->task_probe->masters) &&
!(xfr->task_probe->only_lookup &&
xfr->task_probe->masters != NULL)) {
/* useless to pick up task_probe, no masters to
* probe. Instead attempt to pick up task transfer */
if(xfr->task_transfer->worker == NULL) {
@ -6412,6 +6431,15 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
return 0;
}
}
for(p = c->allow_notify; p; p = p->next) {
m = auth_master_new(&list);
m->allow_notify = 1;
m->host = strdup(p->str);
if(!m->host) {
log_err("malloc failure");
return 0;
}
}
return 1;
}

View file

@ -413,6 +413,9 @@ struct auth_master {
int http;
/** use IXFR for this master */
int ixfr;
/** this is an allow notify member, the master can send notifies
* to us, but we don't send SOA probes, or zone transfer from it */
int allow_notify;
/** use ssl for channel */
int ssl;
/** the port number (for urls) */

View file

@ -1197,6 +1197,7 @@ config_delauth(struct config_auth* p)
free(p->name);
config_delstrlist(p->masters);
config_delstrlist(p->urls);
config_delstrlist(p->allow_notify);
free(p->zonefile);
free(p);
}

View file

@ -563,6 +563,8 @@ struct config_auth {
struct config_strlist* masters;
/** list of urls */
struct config_strlist* urls;
/** list of allow-notify */
struct config_strlist* allow_notify;
/** zonefile (or NULL) */
char* zonefile;
/** provide downstream answers */

File diff suppressed because it is too large Load diff

View file

@ -308,6 +308,7 @@ auth-zone{COLON} { YDVAR(0, VAR_AUTH_ZONE) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) }
url{COLON} { YDVAR(1, VAR_URL) }
allow-notify{COLON} { YDVAR(1, VAR_ALLOW_NOTIFY) }
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
for-upstream{COLON} { YDVAR(1, VAR_FOR_UPSTREAM) }
fallback-enabled{COLON} { YDVAR(1, VAR_FALLBACK_ENABLED) }

File diff suppressed because it is too large Load diff

View file

@ -281,7 +281,8 @@ extern int yydebug;
VAR_FALLBACK_ENABLED = 491,
VAR_ADDITIONAL_TLS_PORT = 492,
VAR_LOW_RTT = 493,
VAR_LOW_RTT_PCT = 494
VAR_LOW_RTT_PCT = 494,
VAR_ALLOW_NOTIFY = 495
};
#endif
/* Tokens. */
@ -522,6 +523,7 @@ extern int yydebug;
#define VAR_ADDITIONAL_TLS_PORT 492
#define VAR_LOW_RTT 493
#define VAR_LOW_RTT_PCT 494
#define VAR_ALLOW_NOTIFY 495
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -532,7 +534,7 @@ union YYSTYPE
char* str;
#line 536 "util/configparser.h" /* yacc.c:1909 */
#line 538 "util/configparser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

View file

@ -156,6 +156,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_FALLBACK_ENABLED VAR_ADDITIONAL_TLS_PORT VAR_LOW_RTT VAR_LOW_RTT_PCT
%token VAR_ALLOW_NOTIFY
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -320,7 +321,8 @@ authstart: VAR_AUTH_ZONE
contents_auth: contents_auth content_auth
| ;
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
auth_for_downstream | auth_for_upstream | auth_fallback_enabled
auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
auth_allow_notify
;
server_num_threads: VAR_NUM_THREADS STRING_ARG
{
@ -2100,6 +2102,14 @@ auth_url: VAR_URL STRING_ARG
yyerror("out of memory");
}
;
auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG
{
OUTYY(("P(allow-notify:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->auths->allow_notify,
$2))
yyerror("out of memory");
}
;
auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG
{
OUTYY(("P(for-downstream:%s)\n", $2));