mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-28 09:29:20 -05:00
authzone, handle probe return packets.
git-svn-id: file:///svn/unbound/trunk@4384 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
eb0f3256d9
commit
15d892c62d
4 changed files with 129 additions and 4 deletions
|
|
@ -827,7 +827,9 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
|
|||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/random.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/validator/val_nsec3.h \
|
||||
$(srcdir)/validator/val_secalgo.h
|
||||
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
|
||||
|
|
|
|||
|
|
@ -2918,7 +2918,7 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
|
|||
uint32_t* serial)
|
||||
{
|
||||
uint16_t id;
|
||||
/* TODO parse to see if packet worked, valid reply */
|
||||
/* parse to see if packet worked, valid reply */
|
||||
|
||||
/* check serial number of SOA */
|
||||
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE)
|
||||
|
|
@ -2994,6 +2994,65 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** see if the serial means the zone has to be updated, i.e. the serial
|
||||
* is newer than the zone serial, or we have no zone */
|
||||
static int
|
||||
xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial)
|
||||
{
|
||||
uint32_t zserial;
|
||||
int have_zone, zone_expired;
|
||||
lock_basic_lock(&xfr->lock);
|
||||
zserial = xfr->serial;
|
||||
have_zone = xfr->have_zone;
|
||||
zone_expired = xfr->zone_expired;
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
|
||||
if(!have_zone)
|
||||
return 1; /* no zone, anything is better */
|
||||
if(zone_expired)
|
||||
return 1; /* expired, the sent serial is better than expired
|
||||
data */
|
||||
if(compare_serial(zserial, serial) < 0)
|
||||
return 1; /* our serial is smaller than the sent serial,
|
||||
the data is newer, fetch it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** find master (from notify or probe) in list of masters */
|
||||
static struct auth_master*
|
||||
find_master_by_host(struct auth_master* list, char* host)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=list; p; p=p->next) {
|
||||
if(strcmp(p->host, host) == 0)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** start transfer task by this worker , xfr is locked. */
|
||||
static void
|
||||
xfr_start_transfer(struct auth_xfer* xfr, struct module_env* env,
|
||||
struct auth_master* master)
|
||||
{
|
||||
log_assert(xfr->task_transfer != NULL);
|
||||
log_assert(xfr->task_transfer->worker == NULL);
|
||||
log_assert(xfr->task_transfer->chunks_first == NULL);
|
||||
log_assert(xfr->task_transfer->chunks_last == NULL);
|
||||
xfr->task_transfer->worker = env->worker;
|
||||
xfr->task_transfer->env = env;
|
||||
|
||||
/* init transfer process */
|
||||
/* find that master in the transfer's list of masters? */
|
||||
xfr->task_transfer->scan_specific = find_master_by_host(
|
||||
xfr->task_transfer->masters, master->host);
|
||||
if(xfr->task_transfer->scan_specific)
|
||||
xfr->task_transfer->scan_target = NULL;
|
||||
else xfr->task_transfer->scan_target = xfr->task_transfer->masters;
|
||||
|
||||
/* TODO initiate TCP, and set timeout on it */
|
||||
}
|
||||
|
||||
/** callback for task_probe udp packets */
|
||||
int
|
||||
auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
|
|
@ -3010,11 +3069,28 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
|||
/* TODO */
|
||||
|
||||
if(err == NETEVENT_NOERROR) {
|
||||
uint32_t serial;
|
||||
uint32_t serial = 0;
|
||||
if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr,
|
||||
&serial)) {
|
||||
/* successful lookup */
|
||||
/* TODO */
|
||||
/* see if this serial indicates that the zone has
|
||||
* to be updated */
|
||||
lock_basic_lock(&xfr->lock);
|
||||
if(xfr_serial_means_update(xfr, serial)) {
|
||||
/* if updated, start the transfer task, if needed */
|
||||
if(xfr->task_transfer->worker == NULL) {
|
||||
xfr_start_transfer(xfr, env,
|
||||
(xfr->task_probe->scan_specific?xfr->task_probe->scan_specific:xfr->task_probe->scan_target));
|
||||
}
|
||||
} else {
|
||||
/* if zone not updated, start the wait timer again */
|
||||
if(xfr->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(xfr, env, 0);
|
||||
}
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
/* return, we don't sent a reply to this udp packet,
|
||||
* and we setup the tasks to do next */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3044,6 +3120,9 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env)
|
|||
if(!master) master = xfr->task_probe->scan_target;
|
||||
if(!master) return 0;
|
||||
|
||||
/* TODO: use mesh_new_callback to probe for non-addr hosts,
|
||||
* and then wait for them to be looked up (in cache, or query) */
|
||||
|
||||
/* create packet */
|
||||
xfr_create_probe_packet(xfr, env, env->scratch_buffer, 1);
|
||||
if(!xfr->task_probe->cp) {
|
||||
|
|
@ -3353,3 +3432,18 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SERIAL_BITS 32
|
||||
int
|
||||
compare_serial(uint32_t a, uint32_t b)
|
||||
{
|
||||
const uint32_t cutoff = ((uint32_t) 1 << (SERIAL_BITS - 1));
|
||||
|
||||
if (a == b) {
|
||||
return 0;
|
||||
} else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,6 +306,8 @@ struct auth_probe {
|
|||
struct auth_transfer {
|
||||
/* Worker pointer. NULL means unowned. */
|
||||
struct worker* worker;
|
||||
/* module env for this task */
|
||||
struct module_env* env;
|
||||
|
||||
/** xfer data that has been transferred, the data is applied
|
||||
* once the transfer has completed correctly */
|
||||
|
|
@ -497,4 +499,12 @@ void auth_xfer_timer(void* arg);
|
|||
int auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
|
||||
/*
|
||||
* Compares two 32-bit serial numbers as defined in RFC1982. Returns
|
||||
* <0 if a < b, 0 if a == b, and >0 if a > b. The result is undefined
|
||||
* if a != b but neither is greater or smaller (see RFC1982 section
|
||||
* 3.2.).
|
||||
*/
|
||||
int compare_serial(uint32_t a, uint32_t b);
|
||||
|
||||
#endif /* SERVICES_AUTHZONE_H */
|
||||
|
|
|
|||
|
|
@ -831,6 +831,24 @@ check_queries(const char* name, const char* zone, struct q_ans* queries)
|
|||
auth_zones_delete(az);
|
||||
}
|
||||
|
||||
/** Test authzone compare_serial */
|
||||
static void
|
||||
authzone_compare_serial(void)
|
||||
{
|
||||
if(vbmp) printf("Testing compare_serial\n");
|
||||
unit_assert(compare_serial(0, 1) < 0);
|
||||
unit_assert(compare_serial(1, 0) > 0);
|
||||
unit_assert(compare_serial(0, 0) == 0);
|
||||
unit_assert(compare_serial(1, 1) == 0);
|
||||
unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
|
||||
unit_assert(compare_serial(0, 0xf0000000) > 0);
|
||||
unit_assert(compare_serial(0xf0000000, 0) < 0);
|
||||
unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
|
||||
unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
|
||||
unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
|
||||
unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
|
||||
}
|
||||
|
||||
/** Test authzone read from file */
|
||||
static void
|
||||
authzone_read_test(void)
|
||||
|
|
@ -853,6 +871,7 @@ authzone_test(void)
|
|||
{
|
||||
unit_show_feature("authzone");
|
||||
atexit(tmpfilecleanup);
|
||||
authzone_compare_serial();
|
||||
authzone_read_test();
|
||||
authzone_query_test();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue