summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2014-02-04 22:03:06 +0000
committerSimon Kelley <simon@thekelleys.org.uk>2014-02-04 22:03:06 +0000
commit12fae49fff5c42675ab4f130edea9e3a6ca73ba6 (patch)
tree8df9d993381c587dae00ea5f8d4386e4a4fc5606
parentfd372273bde910735f6117461f070fe8b250158b (diff)
downloaddnsmasq-12fae49fff5c42675ab4f130edea9e3a6ca73ba6.tar.gz
Make RR work when returning A/AAAA records and an RRSIG.
-rw-r--r--src/cache.c9
-rw-r--r--src/dnsmasq.h5
-rw-r--r--src/rfc1035.c43
3 files changed, 31 insertions, 26 deletions
diff --git a/src/cache.c b/src/cache.c
index ba53837..19a5d61 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -592,10 +592,13 @@ void cache_end_insert(void)
new_chain = NULL;
}
-struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned short prot)
+struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot)
{
struct crec *ans;
+ int no_rr = prot & F_NO_RR;
+ prot &= ~F_NO_RR;
+
if (crecp) /* iterating */
ans = crecp->next;
else
@@ -643,7 +646,7 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
}
else
{
- if (!insert)
+ if (!insert && !no_rr)
{
insert = up;
ins_flags = crecp->flags & (F_REVERSE | F_IMMORTAL);
@@ -683,7 +686,7 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
}
struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
- time_t now, unsigned short prot)
+ time_t now, unsigned int prot)
{
struct crec *ans;
#ifdef HAVE_IPV6
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 5317ea3..58a4fe2 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -423,6 +423,7 @@ struct crec {
#define F_DNSSEC (1u<<22)
#define F_KEYTAG (1u<<23)
#define F_SECSTAT (1u<<24)
+#define F_NO_RR (1u<<25)
/* struct sockaddr is not large enough to hold any address,
@@ -993,9 +994,9 @@ char *record_source(int index);
void querystr(char *desc, char *str, unsigned short type);
struct crec *cache_find_by_addr(struct crec *crecp,
struct all_addr *addr, time_t now,
- unsigned short prot);
+ unsigned int prot);
struct crec *cache_find_by_name(struct crec *crecp,
- char *name, time_t now, unsigned short prot);
+ char *name, time_t now, unsigned int prot);
void cache_end_insert(void);
void cache_start_insert(void);
struct crec *cache_insert(char *name, struct all_addr *addr,
diff --git a/src/rfc1035.c b/src/rfc1035.c
index a50b7d9..26cda15 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1242,7 +1242,7 @@ int check_for_local_domain(char *name, time_t now)
struct ptr_record *ptr;
struct naptr *naptr;
- if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME)) &&
+ if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME | F_NO_RR)) &&
(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
return 1;
@@ -1742,24 +1742,25 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
else if (crecp->flags & F_DNSSECOK)
{
int gotsig = 0;
-
- crecp = NULL;
- while ((crecp = cache_find_by_name(crecp, name, now, F_DS | F_DNSKEY)))
+ struct crec *rr_crec = NULL;
+
+ while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
{
- if (crecp->addr.sig.type_covered == T_PTR && crecp->uid == C_IN)
+ if (rr_crec->addr.sig.type_covered == T_PTR && rr_crec->uid == C_IN)
{
- char *sigdata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL);
+ char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
gotsig = 1;
if (!dryrun &&
add_resource_record(header, limit, &trunc, nameoffset, &ansp,
- crecp->ttd - now, &nameoffset,
+ rr_crec->ttd - now, &nameoffset,
T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
anscount++;
}
}
- /* Need to re-run original cache search */
- crecp = gotsig ? cache_find_by_addr(NULL, &addr, now, is_arpa) : NULL;
+
+ if (!gotsig)
+ crecp = NULL;
}
#endif
}
@@ -1923,7 +1924,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
cname_restart:
- if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
+ if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
{
int localise = 0;
@@ -1954,7 +1955,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
else if (crecp->flags & F_DNSSECOK)
{
/* We're returning validated data, need to return the RRSIG too. */
-
+ struct crec *rr_crec = NULL;
int sigtype = type;
/* The signature may have expired even though the data is still in cache,
forward instead of answering from cache if so. */
@@ -1963,23 +1964,23 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (crecp->flags & F_CNAME)
sigtype = T_CNAME;
- crecp = NULL;
- while ((crecp = cache_find_by_name(crecp, name, now, F_DS | F_DNSKEY)))
+ while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
{
- if (crecp->addr.sig.type_covered == sigtype && crecp->uid == C_IN)
+ if (rr_crec->addr.sig.type_covered == sigtype && rr_crec->uid == C_IN)
{
- char *sigdata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL);
+ char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
gotsig = 1;
if (!dryrun &&
add_resource_record(header, limit, &trunc, nameoffset, &ansp,
- crecp->ttd - now, &nameoffset,
- T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
+ rr_crec->ttd - now, &nameoffset,
+ T_RRSIG, C_IN, "t", rr_crec->addr.sig.keylen, sigdata))
anscount++;
}
}
- /* Need to re-run original cache search */
- crecp = gotsig ? cache_find_by_name(NULL, name, now, flag | F_CNAME) : NULL;
+
+ if (!gotsig)
+ crecp = NULL;
}
#endif
}
@@ -2072,7 +2073,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (qtype == T_CNAME || qtype == T_ANY)
{
if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
- (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))))
+ (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG | (dryrun ? F_NO_RR : 0)))))
{
if (!(crecp->flags & F_DNSSECOK))
sec_data = 0;
@@ -2111,7 +2112,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
- cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
+ cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
{
ans = 1;
if (!dryrun)