mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-18 01:58:27 -05:00
auth zone work.
git-svn-id: file:///svn/unbound/trunk@4512 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
6fc79a70a3
commit
3b87862c8a
4 changed files with 198 additions and 19 deletions
|
|
@ -1818,12 +1818,12 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
|||
if(x) {
|
||||
z->zone_is_slave = 1;
|
||||
/* set options on xfer zone */
|
||||
if(!xfer_set_masters(&x->task_probe->masters, c)) {
|
||||
if(!xfer_set_masters(&x->task_probe->masters, c, 0)) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
if(!xfer_set_masters(&x->task_transfer->masters, c)) {
|
||||
if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
|
|
@ -3443,7 +3443,8 @@ xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf,
|
|||
|
||||
/** create IXFR/AXFR packet for xfr */
|
||||
static void
|
||||
xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id)
|
||||
xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
|
||||
struct auth_master* master)
|
||||
{
|
||||
struct query_info qinfo;
|
||||
uint32_t serial;
|
||||
|
|
@ -3460,7 +3461,7 @@ xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id)
|
|||
xfr->task_transfer->on_ixfr_is_axfr = 0;
|
||||
xfr->task_transfer->on_ixfr = 1;
|
||||
qinfo.qtype = LDNS_RR_TYPE_IXFR;
|
||||
if(!have_zone || xfr->task_transfer->ixfr_fail) {
|
||||
if(!have_zone || xfr->task_transfer->ixfr_fail || !master->ixfr) {
|
||||
qinfo.qtype = LDNS_RR_TYPE_AXFR;
|
||||
xfr->task_transfer->ixfr_fail = 0;
|
||||
xfr->task_transfer->on_ixfr = 0;
|
||||
|
|
@ -4137,11 +4138,34 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
|||
xfr->task_transfer->cp = NULL;
|
||||
}
|
||||
|
||||
if(master->http) {
|
||||
/* perform http fetch */
|
||||
/* store http port number into sockaddr,
|
||||
* unless someone used unbound's host@port notation */
|
||||
if(strchr(master->host, '@') == NULL)
|
||||
sockaddr_store_port(&addr, addrlen, master->port);
|
||||
/* TODO
|
||||
xfr->task_transfer->cp = outnet_comm_point_for_http(env->outnet,
|
||||
auth_xfer_transfer_http_callback, xfr, &addr, addrlen,
|
||||
env->scratch_buffer, AUTH_TRANSFER_TIMEOUT,
|
||||
master->ssl, master->host, master->file);
|
||||
*/
|
||||
if(!xfr->task_transfer->cp) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "cannot create http cp connection for "
|
||||
"%s to %s", zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* perform AXFR/IXFR */
|
||||
/* set the packet to be written */
|
||||
/* create new ID */
|
||||
xfr->task_transfer->id = (uint16_t)(ub_random(env->rnd)&0xffff);
|
||||
xfr_create_ixfr_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_transfer->id);
|
||||
xfr->task_transfer->id, master);
|
||||
|
||||
/* connect on fd */
|
||||
xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
|
||||
|
|
@ -4699,6 +4723,29 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** callback for task_transfer http connections */
|
||||
int
|
||||
auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* ATTR_UNUSED(repinfo))
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
log_assert(xfr->task_transfer);
|
||||
env = xfr->task_transfer->env;
|
||||
lock_basic_lock(&xfr->lock);
|
||||
/* TODO */
|
||||
(void)env;
|
||||
(void)err;
|
||||
/* if we want to read more messages, setup the commpoint to read
|
||||
* a DNS packet, and the timeout */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
c->tcp_is_reading = 1;
|
||||
sldns_buffer_clear(c->buffer);
|
||||
comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** start transfer task by this worker , xfr is locked. */
|
||||
static void
|
||||
xfr_start_transfer(struct auth_xfer* xfr, struct module_env* env,
|
||||
|
|
@ -5325,8 +5372,115 @@ auth_master_new(struct auth_master*** list)
|
|||
return m;
|
||||
}
|
||||
|
||||
/** dup_prefix : create string from initial part of other string, malloced */
|
||||
static char*
|
||||
dup_prefix(char* str, size_t num)
|
||||
{
|
||||
char* result;
|
||||
size_t len = strlen(str);
|
||||
if(len < num) num = len; /* not more than strlen */
|
||||
result = (char*)malloc(num+1);
|
||||
if(!result) {
|
||||
log_err("malloc failure");
|
||||
return result;
|
||||
}
|
||||
memmove(result, str, num);
|
||||
result[num] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** dup string and print error on error */
|
||||
static char*
|
||||
dup_all(char* str)
|
||||
{
|
||||
char* result = strdup(str);
|
||||
if(!str) {
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** find first of two characters */
|
||||
static char*
|
||||
str_find_first_of_chars(char* s, char a, char b)
|
||||
{
|
||||
char* ra = strchr(s, a);
|
||||
char* rb = strchr(s, b);
|
||||
if(!ra) return rb;
|
||||
if(!rb) return ra;
|
||||
if(ra < rb) return ra;
|
||||
return rb;
|
||||
}
|
||||
|
||||
/** parse URL into host and file parts, false on malloc or parse error */
|
||||
static int
|
||||
parse_url(char* url, char** host, char** file, int* port, int* ssl)
|
||||
{
|
||||
char* p = url;
|
||||
/* parse http://www.example.com/file.htm
|
||||
* or http://127.0.0.1 (index.html)
|
||||
* or https://[::1@1234]/a/b/c/d */
|
||||
*ssl = 0;
|
||||
*port = 80;
|
||||
|
||||
/* parse http:// or https:// */
|
||||
if(strncmp(p, "http://", 7) == 0) {
|
||||
p += 7;
|
||||
} else if(strncmp(p, "https://", 8) == 0) {
|
||||
p += 8;
|
||||
*ssl = 1;
|
||||
*port = 443;
|
||||
}
|
||||
|
||||
/* parse hostname part */
|
||||
if(p[0] == '[') {
|
||||
char* end = strchr(p, ']');
|
||||
p++; /* skip over [ */
|
||||
if(end) {
|
||||
*host = dup_prefix(p, (end-p));
|
||||
if(!*host) return 0;
|
||||
p = end+1; /* skip over ] */
|
||||
} else {
|
||||
*host = dup_all(p);
|
||||
if(!*host) return 0;
|
||||
p = end;
|
||||
}
|
||||
} else {
|
||||
char* end = str_find_first_of_chars(p, ':', '/');
|
||||
if(end) {
|
||||
*host = dup_prefix(p, (end-p));
|
||||
if(!*host) return 0;
|
||||
} else {
|
||||
*host = dup_all(p);
|
||||
if(!*host) return 0;
|
||||
}
|
||||
p = end; /* at next : or / or NULL */
|
||||
}
|
||||
|
||||
/* parse port number */
|
||||
if(p && p[0] == ':') {
|
||||
char* end = NULL;
|
||||
*port = strtol(p+1, &end, 10);
|
||||
p = end;
|
||||
}
|
||||
|
||||
/* parse filename part */
|
||||
while(p && *p == '/')
|
||||
p++;
|
||||
if(!p || p[0] == 0)
|
||||
*file = strdup("index.html");
|
||||
else *file = strdup(p);
|
||||
if(!*file) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
xfer_set_masters(struct auth_master** list, struct config_auth* c)
|
||||
xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http)
|
||||
{
|
||||
struct auth_master* m;
|
||||
struct config_strlist* p;
|
||||
|
|
@ -5334,19 +5488,16 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c)
|
|||
while(*list) {
|
||||
list = &( (*list)->next );
|
||||
}
|
||||
for(p = c->masters; p; p = p->next) {
|
||||
m = auth_master_new(&list);
|
||||
m->ixfr = 1;
|
||||
m->host = strdup(p->str);
|
||||
if(!m->host) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(p = c->urls; p; p = p->next) {
|
||||
if(with_http)
|
||||
for(p = c->urls; p; p = p->next) {
|
||||
m = auth_master_new(&list);
|
||||
m->http = 1;
|
||||
/* TODO parse url, get host, file */
|
||||
if(!parse_url(p->str, &m->host, &m->file, &m->port, &m->ssl))
|
||||
return 0;
|
||||
}
|
||||
for(p = c->masters; p; p = p->next) {
|
||||
m = auth_master_new(&list);
|
||||
m->ixfr = 1; /* this flag is not configurable */
|
||||
m->host = strdup(p->str);
|
||||
if(!m->host) {
|
||||
log_err("malloc failure");
|
||||
|
|
|
|||
|
|
@ -402,6 +402,8 @@ struct auth_master {
|
|||
int ixfr;
|
||||
/** use ssl for channel */
|
||||
int ssl;
|
||||
/** the port number (for urls) */
|
||||
int port;
|
||||
/** if the host is a hostname, the list of resolved addrs, if any*/
|
||||
struct auth_addr* list;
|
||||
};
|
||||
|
|
@ -563,10 +565,11 @@ struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
|
|||
* Set masters in auth xfer structure from config.
|
||||
* @param list: pointer to start of list. The malloced list is returned here.
|
||||
* @param c: the config items to copy over.
|
||||
* @param with_http: if true, http urls are also included, before the masters.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int xfer_set_masters(struct auth_master** list, struct config_auth* c);
|
||||
|
||||
int xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http);
|
||||
|
||||
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
|
||||
void auth_xfer_timer(void* arg);
|
||||
|
|
@ -577,6 +580,9 @@ int auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
|||
/** callback for task_transfer tcp connections */
|
||||
int auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** callback for task_transfer http connections */
|
||||
int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** xfer probe timeout callback, part of task_probe */
|
||||
void auth_xfer_probe_timer_callback(void* arg);
|
||||
/** mesh callback for task_probe on lookup of host names */
|
||||
|
|
|
|||
|
|
@ -271,6 +271,19 @@ int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** store port number into sockaddr structure */
|
||||
void
|
||||
sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port)
|
||||
{
|
||||
if(addr_is_ip6(addr, addrlen)) {
|
||||
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
|
||||
sa->sin6_port = (in_port_t)htons(port);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons(port);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
|
||||
uint16_t type, uint16_t dclass)
|
||||
|
|
|
|||
|
|
@ -201,6 +201,15 @@ int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
|||
int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen, int* net);
|
||||
|
||||
/**
|
||||
* Store port number into sockaddr structure
|
||||
* @param addr: sockaddr structure, ip4 or ip6.
|
||||
* @param addrlen: length of addr.
|
||||
* @param port: port number to put into the addr.
|
||||
*/
|
||||
void sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int port);
|
||||
|
||||
/**
|
||||
* Print string with neat domain name, type and class.
|
||||
* @param v: at what verbosity level to print this.
|
||||
|
|
|
|||
Loading…
Reference in a new issue