mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-18 10:09:27 -05:00
Merge 9735e34f89 into d725d94793
This commit is contained in:
commit
26052ea3ef
11 changed files with 423 additions and 142 deletions
|
|
@ -1339,7 +1339,7 @@ perform_zone_add(RES* ssl, struct local_zones* zones, char* arg)
|
|||
return 1;
|
||||
}
|
||||
if(!local_zones_add_zone(zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||
nmlabs, LDNS_RR_CLASS_IN, t, NULL)) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1385,7 +1385,7 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
|
|||
return UB_NOERROR;
|
||||
}
|
||||
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN, t)) {
|
||||
LDNS_RR_CLASS_IN, t, NULL)) {
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ respip_set_get_tree(struct respip_set* set)
|
|||
|
||||
struct resp_addr*
|
||||
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, int create, const char* ipstr)
|
||||
socklen_t addrlen, int net, int create)
|
||||
{
|
||||
struct resp_addr* node;
|
||||
log_assert(set);
|
||||
|
|
@ -119,7 +119,10 @@ respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage*
|
|||
addrlen, net)) {
|
||||
/* We know we didn't find it, so this should be
|
||||
* impossible. */
|
||||
log_warn("unexpected: duplicate address: %s", ipstr);
|
||||
char a[128];
|
||||
addr_to_str(addr, addrlen, a, sizeof(a));
|
||||
log_warn("unexpected: duplicate address: %s/%d",
|
||||
a, net);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
|
|
@ -154,8 +157,7 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
|
|||
log_err("cannot parse netblock: '%s'", ipstr);
|
||||
return NULL;
|
||||
}
|
||||
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create,
|
||||
ipstr);
|
||||
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -291,6 +293,49 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
|||
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
}
|
||||
|
||||
int
|
||||
respip_enter_rr_wol(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata_wol,
|
||||
size_t rdata_len, const char* netblockstr)
|
||||
{
|
||||
struct packed_rrset_data* pd;
|
||||
struct sockaddr* sa;
|
||||
sa = (struct sockaddr*)&raddr->node.addr;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
|
||||
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("CNAME response-ip data (%s) can not co-exist with other "
|
||||
"response-ip data for netblock %s", (rrstr?rrstr:"<out of memory>"), netblockstr);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
} else if (raddr->data &&
|
||||
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
|
||||
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("response-ip data (%s) can not be added; CNAME response-ip "
|
||||
"data already in place for netblock %s", (rrstr?rrstr:"<out of memory>"), netblockstr);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
|
||||
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
|
||||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
|
||||
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("response-ip data %s record type does not correspond "
|
||||
"to netblock %s address family", (rrstr?rrstr:"<out of memory>"), netblockstr);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!raddr->data) {
|
||||
raddr->data = new_rrset(region, rrtype, rrclass);
|
||||
if(!raddr->data)
|
||||
return 0;
|
||||
}
|
||||
pd = raddr->data->entry.data;
|
||||
return rrset_insert_rr_wol(region, pd, rdata_wol, rdata_len, ttl);
|
||||
}
|
||||
|
||||
static int
|
||||
respip_enter_rrstr(struct regional* region, struct resp_addr* raddr,
|
||||
const char* rrstr, const char* netblock)
|
||||
|
|
|
|||
|
|
@ -276,12 +276,11 @@ void respip_inform_print(struct respip_action_info* respip_actinfo,
|
|||
* @param addrlen: length of addr.
|
||||
* @param net: netblock to lookup.
|
||||
* @param create: create node if it does not exist when 1.
|
||||
* @param ipstr: human readable ip string, for logging.
|
||||
* @return newly created of found node, not holding lock.
|
||||
*/
|
||||
struct resp_addr*
|
||||
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, int create, const char* ipstr);
|
||||
socklen_t addrlen, int net, int create);
|
||||
|
||||
/**
|
||||
* Add RR to resp_addr's RRset. Create RRset if not existing.
|
||||
|
|
@ -301,6 +300,22 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
|||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
|
||||
size_t rdata_len, const char* rrstr, const char* netblockstr);
|
||||
|
||||
/**
|
||||
* Add RR to resp_addr's RRset. Create RRset if not existing.
|
||||
* @param region: region to alloc RR(set).
|
||||
* @param raddr: resp_addr containing RRset. Must hold write lock.
|
||||
* @param rrtype: RR type.
|
||||
* @param rrclass: RR class.
|
||||
* @param ttl: TTL.
|
||||
* @param rdata: RDATA. Without prefix len.
|
||||
* @param rdata_len: length of rdata.
|
||||
* @param netblockstr: netblock as string, for logging
|
||||
* @return 0 on error
|
||||
*/
|
||||
int respip_enter_rr_wol(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
|
||||
size_t rdata_len, const char* netblockstr);
|
||||
|
||||
/**
|
||||
* Delete resp_addr node from tree.
|
||||
* @param set: struct containing tree. Must hold write lock.
|
||||
|
|
|
|||
|
|
@ -1189,8 +1189,7 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
|||
static int
|
||||
az_insert_rr_as_rdata(struct auth_zone* z, uint8_t* dname, size_t dname_len,
|
||||
uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdata_wol, size_t rdatalen, int* duplicate,
|
||||
uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata_wol, size_t rdatalen, int* duplicate)
|
||||
{
|
||||
struct auth_data* node;
|
||||
if(rr_class != z->dclass) {
|
||||
|
|
@ -1207,35 +1206,9 @@ az_insert_rr_as_rdata(struct auth_zone* z, uint8_t* dname, size_t dname_len,
|
|||
return 0;
|
||||
}
|
||||
if(z->rpz) {
|
||||
uint8_t* rdata_wl;
|
||||
uint8_t buf[65536];
|
||||
if(rr == NULL) {
|
||||
/* spool it into buffer. */
|
||||
log_assert(dname);
|
||||
if(dname_len + 10 /* type, class, ttl, rdlength */ +
|
||||
rdatalen > sizeof(buf)) {
|
||||
char dstr[LDNS_MAX_DOMAINLEN], t[16], c[16];
|
||||
dname_str(dname, dstr);
|
||||
sldns_wire2str_type_buf(rr_type, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(rr_class, c, sizeof(c));
|
||||
log_err("record exceeds buffer length, %s %s %s", dstr, c, t);
|
||||
return 0;
|
||||
}
|
||||
rr = buf;
|
||||
rr_len = dname_len
|
||||
+ 10 /* type, class, ttl, rdlength */ +
|
||||
rdatalen;
|
||||
memcpy(buf, dname, dname_len);
|
||||
sldns_write_uint16(buf+dname_len, rr_type);
|
||||
sldns_write_uint16(buf+dname_len+2, rr_class);
|
||||
sldns_write_uint32(buf+dname_len+4, rr_ttl);
|
||||
sldns_write_uint16(buf+dname_len+8, rdatalen);
|
||||
memmove(buf+dname_len+10, rdata_wol, rdatalen);
|
||||
}
|
||||
rdata_wl = sldns_wirerr_get_rdatawl(rr, rr_len, dname_len);
|
||||
if(!(rpz_insert_rr(z->rpz, z->name, z->namelen, dname,
|
||||
dname_len, rr_type, rr_class, rr_ttl, rdata_wl,
|
||||
rdatalen+2, rr, rr_len)))
|
||||
dname_len, rr_type, rr_class, rr_ttl, rdata_wol,
|
||||
rdatalen)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -1256,7 +1229,7 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
|||
uint8_t* rdata_wol = sldns_wirerr_get_rdata(rr, rr_len, dname_len);
|
||||
|
||||
return az_insert_rr_as_rdata(z, dname, dname_len, rr_type, rr_class,
|
||||
rr_ttl, rdata_wol, rdatalen, duplicate, rr, rr_len);
|
||||
rr_ttl, rdata_wol, rdatalen, duplicate);
|
||||
}
|
||||
|
||||
/** Remove rr from node, ignores nonexisting RRs,
|
||||
|
|
@ -1690,7 +1663,7 @@ az_parse_accept(zone_parser_t *parser, const zone_name_t *owner,
|
|||
/* Duplicates can be ignored, do not insert them twice. */
|
||||
if(!az_insert_rr_as_rdata(state->z, (uint8_t*)owner->octets,
|
||||
owner->length, type, dclass, ttl, (uint8_t*)rdata, rdlength,
|
||||
NULL, NULL, 0)) {
|
||||
NULL)) {
|
||||
char dname[LDNS_MAX_DOMAINLEN], t[16], c[16];
|
||||
dname_str((uint8_t*)owner->octets, dname);
|
||||
sldns_wire2str_type_buf(type, t, sizeof(t));
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "config.h"
|
||||
#include "services/localzone.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/dname.h"
|
||||
|
|
@ -356,6 +357,22 @@ rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** see if rdata is duplicate */
|
||||
static int
|
||||
rr_is_duplicate_wol(struct packed_rrset_data* d, uint8_t* rdata_wol, size_t len)
|
||||
{
|
||||
size_t i, rdatawl_len = len+2;
|
||||
uint16_t len16 = htons(len);
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(d->rr_len[i] != rdatawl_len)
|
||||
continue;
|
||||
if(memcmp(d->rr_data[i], &len16, 2) == 0 &&
|
||||
memcmp(d->rr_data[i]+2, rdata_wol, len) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** new local_rrset */
|
||||
static struct local_rrset*
|
||||
new_local_rrset(struct regional* region, struct local_data* node,
|
||||
|
|
@ -393,6 +410,49 @@ new_local_rrset(struct regional* region, struct local_data* node,
|
|||
return rrset;
|
||||
}
|
||||
|
||||
/** insert RR into RRset data structure; Wastes a couple of bytes */
|
||||
int
|
||||
rrset_insert_rr_wol(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata_wol, size_t rdata_len, time_t ttl)
|
||||
{
|
||||
size_t* oldlen = pd->rr_len;
|
||||
time_t* oldttl = pd->rr_ttl;
|
||||
uint8_t** olddata = pd->rr_data;
|
||||
|
||||
/* add RR to rrset */
|
||||
if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
|
||||
log_warn("RRset has more than %d records, record ignored",
|
||||
LOCALZONE_RRSET_COUNT_MAX);
|
||||
return 1;
|
||||
}
|
||||
pd->count++;
|
||||
pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count);
|
||||
pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count);
|
||||
pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count);
|
||||
if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(pd->count > 1) {
|
||||
memcpy(pd->rr_len+1, oldlen,
|
||||
sizeof(*pd->rr_len)*(pd->count-1));
|
||||
memcpy(pd->rr_ttl+1, oldttl,
|
||||
sizeof(*pd->rr_ttl)*(pd->count-1));
|
||||
memcpy(pd->rr_data+1, olddata,
|
||||
sizeof(*pd->rr_data)*(pd->count-1));
|
||||
}
|
||||
pd->rr_len[0] = rdata_len+2;
|
||||
pd->rr_ttl[0] = ttl;
|
||||
pd->rr_data[0] = regional_alloc(region, rdata_len+2);
|
||||
if(!pd->rr_data[0]) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
sldns_write_uint16(pd->rr_data[0], rdata_len);
|
||||
memmove(pd->rr_data[0]+2, rdata_wol, rdata_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** insert RR into RRset data structure; Wastes a couple of bytes */
|
||||
int
|
||||
rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
|
|
@ -503,6 +563,48 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
|
||||
* for the RR is entered later on local_zone_enter_rr() as with the other
|
||||
* records. An artificial soa_negative record with a modified TTL (minimum of
|
||||
* the TTL and the SOA.MINIMUM) is also created and marked for usage with
|
||||
* negative answers and to avoid allocations during those answers. */
|
||||
static int
|
||||
lz_mark_soa_for_zone_wol(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset,
|
||||
uint8_t* rdata_wol, size_t rdata_len, time_t ttl)
|
||||
{
|
||||
struct packed_rrset_data* pd = (struct packed_rrset_data*)
|
||||
regional_alloc_zero(z->region, sizeof(*pd));
|
||||
struct ub_packed_rrset_key* rrset_negative = (struct ub_packed_rrset_key*)
|
||||
regional_alloc_zero(z->region, sizeof(*rrset_negative));
|
||||
time_t minimum;
|
||||
if(!rrset_negative||!pd) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
/* Mark the original SOA record and then continue with the negative one. */
|
||||
z->soa = soa_rrset;
|
||||
rrset_negative->entry.key = rrset_negative;
|
||||
pd->trust = rrset_trust_prim_noglue;
|
||||
pd->security = sec_status_insecure;
|
||||
rrset_negative->entry.data = pd;
|
||||
rrset_negative->rk.dname = soa_rrset->rk.dname;
|
||||
rrset_negative->rk.dname_len = soa_rrset->rk.dname_len;
|
||||
rrset_negative->rk.type = soa_rrset->rk.type;
|
||||
rrset_negative->rk.rrset_class = soa_rrset->rk.rrset_class;
|
||||
if(!rrset_insert_rr_wol(z->region, pd, rdata_wol, rdata_len, ttl))
|
||||
return 0;
|
||||
/* last 4 bytes are minimum ttl in network format */
|
||||
if(pd->count == 0 || pd->rr_len[0] < 2+4)
|
||||
return 0;
|
||||
minimum = (time_t)sldns_read_uint32(pd->rr_data[0]+(pd->rr_len[0]-4));
|
||||
minimum = ttl<minimum?ttl:minimum;
|
||||
pd->ttl = minimum;
|
||||
pd->rr_ttl[0] = minimum;
|
||||
|
||||
z->soa_negative = rrset_negative;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
|
||||
* for the RR is entered later on local_zone_enter_rr() as with the other
|
||||
* records. An artificial soa_negative record with a modified TTL (minimum of
|
||||
|
|
@ -545,6 +647,96 @@ lz_mark_soa_for_zone(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert dname, type, class, ttl, rdata to an rr string.
|
||||
* rdata without prefixed length. returned string is malloced.
|
||||
*/
|
||||
char* dname_rdata_to_str(uint8_t* dname, size_t dnamelen, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
char buf[65536], t[32], c[32], d[1024], result[65536+32+32+1024+1024];
|
||||
buf[0]=0; buf[sizeof(buf)-1]=0;
|
||||
d[0]=0; d[sizeof(d)-1]=0;
|
||||
(void)sldns_wire2str_rdata_buf(rdata, rdata_len, buf, sizeof(buf),
|
||||
rrtype);
|
||||
(void)sldns_wire2str_type_buf(rrtype, t, sizeof(t));
|
||||
(void)sldns_wire2str_class_buf(rrclass, c, sizeof(c));
|
||||
if(dname)
|
||||
(void)sldns_wire2str_dname_buf(dname, dnamelen, d, sizeof(d));
|
||||
snprintf(result, sizeof(result), "%s%s%u %s %s %s",
|
||||
dname, (dname?" ":""), (unsigned)ttl, c, t, d);
|
||||
return strdup(result);
|
||||
}
|
||||
|
||||
int
|
||||
local_zone_enter_rr_wol(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata_wol, size_t rdata_len)
|
||||
{
|
||||
struct local_data* node;
|
||||
struct local_rrset* rrset;
|
||||
struct packed_rrset_data* pd;
|
||||
|
||||
if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
|
||||
return 0;
|
||||
}
|
||||
log_assert(node);
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for a redirect zone. */
|
||||
if((z->type == local_zone_redirect ||
|
||||
z->type == local_zone_inform_redirect) && node->rrsets) {
|
||||
const char* othertype = NULL;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME)
|
||||
othertype = "other";
|
||||
else if (node->rrsets->rrset->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME)) {
|
||||
othertype = "CNAME";
|
||||
}
|
||||
if(othertype) {
|
||||
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("local-data '%s' in redirect zone must not "
|
||||
"coexist with %s local-data", (rrstr?rrstr:"<out of memory>"), othertype);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
rrset = local_data_find_type(node, rrtype, 0);
|
||||
if(!rrset) {
|
||||
rrset = new_local_rrset(z->region, node, rrtype, rrclass);
|
||||
if(!rrset)
|
||||
return 0;
|
||||
if(query_dname_compare(node->name, z->name) == 0) {
|
||||
if(rrtype == LDNS_RR_TYPE_NSEC)
|
||||
rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX;
|
||||
if(rrtype == LDNS_RR_TYPE_SOA &&
|
||||
!lz_mark_soa_for_zone_wol(z, rrset->rrset, rdata_wol, rdata_len, ttl))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pd = (struct packed_rrset_data*)rrset->rrset->entry.data;
|
||||
log_assert(rrset && pd);
|
||||
|
||||
/* check for duplicate RR */
|
||||
if(rr_is_duplicate_wol(pd, rdata_wol, rdata_len)) {
|
||||
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
verbose(VERB_ALGO, "ignoring duplicate RR: %s", (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
return 1;
|
||||
}
|
||||
if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
|
||||
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_warn("RRset %s has more than %d records, record ignored",
|
||||
(rrstr?rrstr:"<out of memory>"), LOCALZONE_RRSET_COUNT_MAX);
|
||||
free(rrstr);
|
||||
return 1;
|
||||
}
|
||||
return rrset_insert_rr_wol(z->region, pd, rdata_wol, rdata_len, ttl);
|
||||
}
|
||||
|
||||
int
|
||||
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
|
|
@ -2039,7 +2231,7 @@ set_kiddo_parents(struct local_zone* z, struct local_zone* match,
|
|||
|
||||
struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||
enum localzone_type tp)
|
||||
enum localzone_type tp, int* duplicate)
|
||||
{
|
||||
int exact;
|
||||
/* create */
|
||||
|
|
@ -2047,6 +2239,7 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
|||
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
|
||||
if(!z) {
|
||||
free(name);
|
||||
if(duplicate) *duplicate = 0;
|
||||
return NULL;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
|
|
@ -2060,8 +2253,14 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
|||
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
|
||||
/* duplicate entry! */
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(duplicate) {
|
||||
*duplicate = 1;
|
||||
z->name = NULL; /* Do not delete the name in
|
||||
local_zone_delete. */
|
||||
}
|
||||
local_zone_delete(z);
|
||||
log_err("internal: duplicate entry in local_zones_add_zone");
|
||||
if(duplicate == NULL)
|
||||
log_err("internal: duplicate entry in local_zones_add_zone");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2105,7 +2304,7 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
|
|||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
|
||||
if(!z) {
|
||||
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
|
||||
local_zone_transparent);
|
||||
local_zone_transparent, NULL);
|
||||
if(!z) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -403,11 +403,17 @@ local_zones_find_le(struct local_zones* zones,
|
|||
* @param labs: labelcount of name.
|
||||
* @param dclass: class to add.
|
||||
* @param tp: type.
|
||||
* @param duplicate: Allows to check if a NULL return from the function is a
|
||||
* memory error, or a duplicate entry. Pass NULL to have it not returned,
|
||||
* the name is freed on errors, and for a duplicate a log message is
|
||||
* printed. Pass not NULL, and when the error is a duplicate, the function
|
||||
* returns NULL, and the variable is set true. The name is not freed
|
||||
* when there is a duplicate, no error is printed by this function.
|
||||
* @return local_zone or NULL on error, caller must printout memory error.
|
||||
*/
|
||||
struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||
enum localzone_type tp);
|
||||
enum localzone_type tp, int* duplicate);
|
||||
|
||||
/**
|
||||
* Delete a zone. Caller must hold the zones lock.
|
||||
|
|
@ -526,6 +532,18 @@ int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
|
|||
int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
|
||||
|
||||
/**
|
||||
* Insert specified rdata into the specified resource record.
|
||||
* @param region: allocator
|
||||
* @param pd: data portion of the destination resource record
|
||||
* @param rdata_wol: source rdata, without prefix len.
|
||||
* @param rdata_len: source rdata length
|
||||
* @param ttl: time to live
|
||||
* @return 1 on success; 0 otherwise.
|
||||
*/
|
||||
int rrset_insert_rr_wol(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata_wol, size_t rdata_len, time_t ttl);
|
||||
|
||||
/**
|
||||
* Remove RR from rrset that is created using localzone's rrset_insert_rr.
|
||||
* @param pd: the RRset containing the RR to remove
|
||||
|
|
@ -631,6 +649,24 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
|||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, const char* rrstr);
|
||||
|
||||
/**
|
||||
* Add RR to local zone. Without prefix length on rdata.
|
||||
* @param z: local zone to add RR to
|
||||
* @param nm: dname of RR
|
||||
* @param nmlen: length of nm
|
||||
* @param nmlabs: number of labels of nm
|
||||
* @param rrtype: RR type
|
||||
* @param rrclass: RR class
|
||||
* @param ttl: TTL of RR to add
|
||||
* @param rdata_wol: RDATA of RR to add, without prefix length.
|
||||
* @param rdata_len: length of rdata, without prefix length.
|
||||
* @return: 1 on success
|
||||
*/
|
||||
int
|
||||
local_zone_enter_rr_wol(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata_wol, size_t rdata_len);
|
||||
|
||||
/**
|
||||
* Find a data node by exact name for a local zone
|
||||
* @param z: local_zone containing data tree
|
||||
|
|
@ -674,4 +710,12 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
|||
*/
|
||||
void
|
||||
lz_init_parents(struct local_zones* zones);
|
||||
|
||||
/**
|
||||
* Convert dname, type, class, ttl, rdata to an rr string.
|
||||
* rdata without prefixed length. returned string is malloced.
|
||||
*/
|
||||
char* dname_rdata_to_str(uint8_t* dname, size_t dnamelen, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len);
|
||||
|
||||
#endif /* SERVICES_LOCALZONE_H */
|
||||
|
|
|
|||
168
services/rpz.c
168
services/rpz.c
|
|
@ -170,15 +170,14 @@ rpz_type_ignored(uint16_t rr_type)
|
|||
/**
|
||||
* Classify RPZ action for RR type/rdata
|
||||
* @param rr_type: the RR type
|
||||
* @param rdatawl: RDATA with 2 bytes length
|
||||
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
|
||||
* @param rdata: RDATA without 2 bytes length
|
||||
* @param rdatalen: the length of rdatawl (not including its 2 bytes length)
|
||||
* @return: the RPZ action
|
||||
*/
|
||||
static enum rpz_action
|
||||
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
rpz_rr_to_action_wol(uint16_t rr_type, uint8_t* rdata, size_t rdatalen)
|
||||
{
|
||||
char* endptr;
|
||||
uint8_t* rdata;
|
||||
int rdatalabs;
|
||||
uint8_t* tldlab = NULL;
|
||||
|
||||
|
|
@ -202,11 +201,10 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
|||
|
||||
/* use CNAME target to determine RPZ action */
|
||||
log_assert(rr_type == LDNS_RR_TYPE_CNAME);
|
||||
if(rdatalen < 3)
|
||||
if(rdatalen < 1)
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
||||
rdata = rdatawl + 2; /* 2 bytes of rdata length */
|
||||
if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
|
||||
if(dname_valid(rdata, rdatalen) != rdatalen)
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
||||
rdatalabs = dname_count_labels(rdata);
|
||||
|
|
@ -226,7 +224,7 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
|||
}
|
||||
|
||||
/* all other TLDs starting with "rpz-" are invalid */
|
||||
tldlab = get_tld_label(rdata, rdatalen-2);
|
||||
tldlab = get_tld_label(rdata, rdatalen);
|
||||
if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
||||
|
|
@ -234,6 +232,21 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
|||
return RPZ_LOCAL_DATA_ACTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Classify RPZ action for RR type/rdata
|
||||
* @param rr_type: the RR type
|
||||
* @param rdatawl: RDATA with 2 bytes length
|
||||
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
|
||||
* @return: the RPZ action
|
||||
*/
|
||||
static enum rpz_action
|
||||
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
if(rdatalen < 2)
|
||||
return RPZ_INVALID_ACTION;
|
||||
return rpz_rr_to_action_wol(rr_type, rdatawl+2, rdatalen-2);
|
||||
}
|
||||
|
||||
static enum localzone_type
|
||||
rpz_action_to_localzone_type(enum rpz_action a)
|
||||
{
|
||||
|
|
@ -658,7 +671,7 @@ strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
|
|||
static void
|
||||
rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
||||
size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass,
|
||||
uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct local_zone* z;
|
||||
enum localzone_type tp = local_zone_always_transparent;
|
||||
|
|
@ -685,20 +698,41 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
|||
return;
|
||||
}
|
||||
|
||||
/* For not a local-data action.
|
||||
* Insert the zone, then detect a duplicate, instead of find it first,
|
||||
* for speed of searching the tree once. */
|
||||
if(a != RPZ_LOCAL_DATA_ACTION) {
|
||||
int duplicate = 0;
|
||||
lock_rw_wrlock(&lz->lock);
|
||||
tp = rpz_action_to_localzone_type(a);
|
||||
z = local_zones_add_zone(lz, dname, dnamelen,
|
||||
dnamelabs, rrclass, tp, &duplicate);
|
||||
if(z == NULL) {
|
||||
if(duplicate) {
|
||||
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
log_warn("rpz: create failed, out of memory");
|
||||
lock_rw_unlock(&lz->lock);
|
||||
/* dname will be free'd in failed local_zone_create() */
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&lz->lock);
|
||||
/* exact match */
|
||||
z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
|
||||
if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) {
|
||||
char* rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz nsdname trigger");
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
if(rrstr[0])
|
||||
rrstr[strlen(rrstr)-1]=0; /* remove newline */
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr);
|
||||
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
|
|
@ -707,7 +741,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
|||
if(z == NULL) {
|
||||
tp = rpz_action_to_localzone_type(a);
|
||||
z = local_zones_add_zone(lz, dname, dnamelen,
|
||||
dnamelabs, rrclass, tp);
|
||||
dnamelabs, rrclass, tp, NULL);
|
||||
if(z == NULL) {
|
||||
log_warn("rpz: create failed");
|
||||
lock_rw_unlock(&lz->lock);
|
||||
|
|
@ -717,18 +751,10 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
|||
newzone = 1;
|
||||
}
|
||||
if(a == RPZ_LOCAL_DATA_ACTION) {
|
||||
char* rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz nsdname trigger");
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, rrstr);
|
||||
local_zone_enter_rr_wol(z, dname, dnamelen, dnamelabs, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
lock_rw_unlock(&z->lock);
|
||||
free(rrstr);
|
||||
}
|
||||
if(!newzone) {
|
||||
free(dname);
|
||||
|
|
@ -748,7 +774,7 @@ rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
|
|||
static void
|
||||
rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
if(a == RPZ_INVALID_ACTION) {
|
||||
verbose(VERB_ALGO, "rpz: skipping invalid action");
|
||||
|
|
@ -757,7 +783,7 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
}
|
||||
|
||||
rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -799,7 +825,7 @@ rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen,
|
|||
static void
|
||||
rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
uint8_t* dname_stripped = NULL;
|
||||
size_t dnamelen_stripped = 0;
|
||||
|
|
@ -814,32 +840,22 @@ rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
|
||||
/* dname_stripped is consumed or freed by the insert routine */
|
||||
rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped,
|
||||
dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len,
|
||||
rr, rr_len);
|
||||
dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
static int
|
||||
rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
|
||||
uint8_t* rr, size_t rr_len)
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct resp_addr* node;
|
||||
char* rrstr;
|
||||
enum respip_action respa = rpz_action_to_respip_action(a);
|
||||
|
||||
lock_rw_wrlock(&set->lock);
|
||||
rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz ipaddr based trigger");
|
||||
lock_rw_unlock(&set->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr);
|
||||
node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1);
|
||||
if(node == NULL) {
|
||||
lock_rw_unlock(&set->lock);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -849,12 +865,11 @@ rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage*
|
|||
node->action = respa;
|
||||
|
||||
if(a == RPZ_LOCAL_DATA_ACTION) {
|
||||
respip_enter_rr(set->region, node, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, rrstr, "");
|
||||
respip_enter_rr_wol(set->region, node, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, "");
|
||||
}
|
||||
|
||||
lock_rw_unlock(&node->lock);
|
||||
free(rrstr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -890,17 +905,6 @@ rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set,
|
|||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
|
||||
char* rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz clientip based record");
|
||||
return;
|
||||
}
|
||||
log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr);
|
||||
free(rrstr);
|
||||
}
|
||||
|
||||
/* from localzone.c; difference is we don't have a dname */
|
||||
static struct local_rrset*
|
||||
rpz_clientip_new_rrset(struct regional* region,
|
||||
|
|
@ -958,14 +962,13 @@ rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* r
|
|||
return 0;
|
||||
}
|
||||
|
||||
return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "");
|
||||
return rrset_insert_rr_wol(region, rrset->rrset->entry.data, rdata, rdata_len, ttl);
|
||||
}
|
||||
|
||||
static int
|
||||
rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
|
||||
uint8_t* rr, size_t rr_len)
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct clientip_synthesized_rr* node;
|
||||
|
||||
|
|
@ -973,8 +976,14 @@ rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct so
|
|||
|
||||
node = rpz_clientip_ensure_entry(set, addr, addrlen, net);
|
||||
if(node == NULL) {
|
||||
char as[64], *rrstr;
|
||||
lock_rw_unlock(&set->lock);
|
||||
rpz_report_rrset_error("client ip address", rr, rr_len);
|
||||
addr_to_str(addr, addrlen, as, sizeof(as));
|
||||
rrstr = dname_rdata_to_str(NULL, 0, rrtype, rrclass, ttl,
|
||||
rdata, rdata_len);
|
||||
log_err("rpz: unexpected: unable to insert %s: %s/%d %s",
|
||||
"client ip address", as, net, (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1000,7 +1009,7 @@ rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct so
|
|||
static int
|
||||
rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
|
|
@ -1016,13 +1025,13 @@ rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
}
|
||||
|
||||
return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net,
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
static int
|
||||
rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
|
|
@ -1038,14 +1047,14 @@ rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
}
|
||||
|
||||
return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net,
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
/** Insert RR into RPZ's respip_set */
|
||||
static int
|
||||
rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
|
|
@ -1070,13 +1079,13 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
|||
}
|
||||
|
||||
return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net,
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
int
|
||||
rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdatawol, size_t rdatalen)
|
||||
{
|
||||
size_t policydnamelen;
|
||||
/* name is free'd in local_zone delete */
|
||||
|
|
@ -1110,7 +1119,7 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
|||
return 0;
|
||||
}
|
||||
|
||||
a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
|
||||
a = rpz_rr_to_action_wol(rr_type, rdatawol, rdatalen);
|
||||
if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
|
||||
policydname, (dnamelen-aznamelen)+1))) {
|
||||
free(policydname);
|
||||
|
|
@ -1125,27 +1134,22 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
|||
if(t == RPZ_QNAME_TRIGGER) {
|
||||
/* policydname will be consumed, no free */
|
||||
rpz_insert_qname_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
|
||||
rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else if(t == RPZ_CLIENT_IP_TRIGGER) {
|
||||
rpz_insert_clientip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else if(t == RPZ_NSIP_TRIGGER) {
|
||||
rpz_insert_nsip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else if(t == RPZ_NSDNAME_TRIGGER) {
|
||||
rpz_insert_nsdname_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else {
|
||||
free(policydname);
|
||||
|
|
|
|||
|
|
@ -136,15 +136,13 @@ struct rpz {
|
|||
* @param rr_type: RR type of the RR
|
||||
* @param rr_class: RR class of the RR
|
||||
* @param rr_ttl: TTL of the RR
|
||||
* @param rdatawl: rdata of the RR, prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, including the prepended rdata size
|
||||
* @param rr: the complete RR, for logging purposes
|
||||
* @param rr_len: the length of the complete RR
|
||||
* @param rdatawol: rdata of the RR, not prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, not including the prepended rdata size
|
||||
* @return: 0 on error
|
||||
*/
|
||||
int rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
|
||||
uint8_t* rdatawol, size_t rdatalen);
|
||||
|
||||
/**
|
||||
* Delete policy matching RR, used for IXFR.
|
||||
|
|
|
|||
|
|
@ -1265,7 +1265,7 @@ static void localzone_parents_test(void)
|
|||
nmlabs = dname_count_size_labels(nm, &nmlen);
|
||||
lock_rw_wrlock(&z2->lock);
|
||||
local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN,
|
||||
local_zone_always_nxdomain);
|
||||
local_zone_always_nxdomain, NULL);
|
||||
lock_rw_unlock(&z2->lock);
|
||||
}
|
||||
/* The trees should be the same, iterate and check the nodes */
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ int
|
|||
query_dname_compare(register uint8_t* d1, register uint8_t* d2)
|
||||
{
|
||||
register uint8_t lab1, lab2;
|
||||
register uint8_t ld1, ld2;
|
||||
log_assert(d1 && d2);
|
||||
lab1 = *d1++;
|
||||
lab2 = *d2++;
|
||||
|
|
@ -116,8 +117,8 @@ query_dname_compare(register uint8_t* d1, register uint8_t* d2)
|
|||
while(lab1--) {
|
||||
/* compare bytes first for speed */
|
||||
if(*d1 != *d2 &&
|
||||
tolower((unsigned char)*d1) != tolower((unsigned char)*d2)) {
|
||||
if(tolower((unsigned char)*d1) < tolower((unsigned char)*d2))
|
||||
(ld1=tolower((unsigned char)*d1)) != (ld2=tolower((unsigned char)*d2))) {
|
||||
if(ld1 < ld2)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -233,6 +234,7 @@ int
|
|||
dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
|
||||
{
|
||||
uint8_t len1, len2;
|
||||
register uint8_t ld1, ld2;
|
||||
int count1 = 0, count2 = 0;
|
||||
log_assert(pkt && d1 && d2);
|
||||
len1 = *d1++;
|
||||
|
|
@ -269,8 +271,8 @@ dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
|
|||
log_assert(len1 == len2 && len1 != 0);
|
||||
/* compare labels */
|
||||
while(len1--) {
|
||||
if(tolower((unsigned char)*d1) != tolower((unsigned char)*d2)) {
|
||||
if(tolower((unsigned char)*d1) < tolower((unsigned char)*d2))
|
||||
if((ld1=tolower((unsigned char)*d1)) != (ld2=tolower((unsigned char)*d2))) {
|
||||
if(ld1 < ld2)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -470,9 +472,10 @@ dname_count_size_labels(uint8_t* dname, size_t* size)
|
|||
static int
|
||||
memlowercmp(uint8_t* p1, uint8_t* p2, uint8_t len)
|
||||
{
|
||||
register uint8_t lp1, lp2;
|
||||
while(len--) {
|
||||
if(*p1 != *p2 && tolower((unsigned char)*p1) != tolower((unsigned char)*p2)) {
|
||||
if(tolower((unsigned char)*p1) < tolower((unsigned char)*p2))
|
||||
if(*p1 != *p2 && (lp1=tolower((unsigned char)*p1)) != (lp2=tolower((unsigned char)*p2))) {
|
||||
if(lp1 < lp2)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -523,15 +526,15 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
|
|||
d1 += len1;
|
||||
d2 += len2;
|
||||
} else {
|
||||
register uint8_t ld1, ld2;
|
||||
/* memlowercmp is inlined here; or just like
|
||||
* if((c=memlowercmp(d1, d2, len1)) != 0) {
|
||||
* lastdiff = c;
|
||||
* lastmlabs = atlabel; } apart from d1++,d2++ */
|
||||
while(len1) {
|
||||
if(*d1 != *d2 && tolower((unsigned char)*d1)
|
||||
!= tolower((unsigned char)*d2)) {
|
||||
if(tolower((unsigned char)*d1) <
|
||||
tolower((unsigned char)*d2)) {
|
||||
if(*d1 != *d2 && (ld1=tolower((unsigned char)*d1))
|
||||
!= (ld2=tolower((unsigned char)*d2))) {
|
||||
if(ld1 < ld2) {
|
||||
lastdiff = -1;
|
||||
lastmlabs = atlabel;
|
||||
d1 += len1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue