Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
51ea3ca2
Commit
51ea3ca2
authored
Jan 22, 2014
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Caching of DNSSEC records.
parent
57ab36e7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
250 additions
and
111 deletions
+250
-111
src/cache.c
src/cache.c
+80
-27
src/dns-protocol.h
src/dns-protocol.h
+0
-1
src/dnsmasq.h
src/dnsmasq.h
+19
-5
src/dnssec.c
src/dnssec.c
+93
-77
src/rfc1035.c
src/rfc1035.c
+58
-1
No files found.
src/cache.c
View file @
51ea3ca2
...
...
@@ -316,27 +316,71 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
if
(
flags
&
F_FORWARD
)
{
for
(
up
=
hash_bucket
(
name
),
crecp
=
*
up
;
crecp
;
crecp
=
crecp
->
hash_next
)
if
(
is_expired
(
now
,
crecp
)
||
is_outdated_cname_pointer
(
crecp
))
{
*
up
=
crecp
->
hash_next
;
if
(
!
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
)))
{
cache_unlink
(
crecp
);
cache_free
(
crecp
);
}
}
else
if
((
crecp
->
flags
&
F_FORWARD
)
&&
((
flags
&
crecp
->
flags
&
F_TYPE
)
||
((
crecp
->
flags
|
flags
)
&
F_CNAME
))
&&
hostname_isequal
(
cache_get_name
(
crecp
),
name
))
{
if
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))
return
0
;
*
up
=
crecp
->
hash_next
;
cache_unlink
(
crecp
);
cache_free
(
crecp
);
}
else
{
if
(
is_expired
(
now
,
crecp
)
||
is_outdated_cname_pointer
(
crecp
))
{
*
up
=
crecp
->
hash_next
;
if
(
!
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
)))
{
cache_unlink
(
crecp
);
cache_free
(
crecp
);
}
continue
;
}
if
((
crecp
->
flags
&
F_FORWARD
)
&&
hostname_isequal
(
cache_get_name
(
crecp
),
name
))
{
if
((
flags
&
crecp
->
flags
&
(
F_IPV4
|
F_IPV6
))
||
((
crecp
->
flags
|
flags
)
&
F_CNAME
))
{
if
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))
return
0
;
*
up
=
crecp
->
hash_next
;
cache_unlink
(
crecp
);
cache_free
(
crecp
);
continue
;
}
#ifdef HAVE_DNSSEC
/* Deletion has to be class-sensitive for DS, DNSKEY, RRSIG, also
type-covered sensitive for RRSIG */
if
(
flags
&
crecp
->
flags
&
(
F_DNSKEY
|
F_DS
))
{
int
del
=
0
;
switch
(
flags
&
(
F_DS
|
F_DNSKEY
))
{
case
F_DS
:
if
(
crecp
->
addr
.
ds
.
class
==
addr
->
addr
.
dnssec
.
class
)
del
=
1
;
break
;
case
F_DNSKEY
:
if
(
crecp
->
addr
.
key
.
class
==
addr
->
addr
.
dnssec
.
class
)
del
=
1
;
break
;
/* Both set -> RRSIG */
case
F_DS
|
F_DNSKEY
:
if
(
crecp
->
addr
.
sig
.
class
==
addr
->
addr
.
dnssec
.
class
&&
crecp
->
addr
.
sig
.
type_covered
==
addr
->
addr
.
dnssec
.
type
)
del
=
1
;
break
;
}
if
(
del
)
{
if
(
crecp
->
flags
&
F_CONFIG
)
return
0
;
*
up
=
crecp
->
hash_next
;
cache_unlink
(
crecp
);
cache_free
(
crecp
);
continue
;
}
}
#endif
}
up
=
&
crecp
->
hash_next
;
}
}
else
{
...
...
@@ -409,8 +453,8 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
if
(
daemon
->
max_cache_ttl
!=
0
&&
daemon
->
max_cache_ttl
<
ttl
)
ttl
=
daemon
->
max_cache_ttl
;
/* Don't log keys */
if
(
flags
&
(
F_IPV4
|
F_IPV6
))
/* Don't log keys
here, done elsewhere
*/
if
(
flags
&
(
F_IPV4
|
F_IPV6
|
F_CNAME
))
log_query
(
flags
|
F_UPSTREAM
,
name
,
addr
,
NULL
);
/* if previous insertion failed give up now. */
...
...
@@ -554,6 +598,9 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
if
(
!
is_expired
(
now
,
crecp
)
&&
!
is_outdated_cname_pointer
(
crecp
))
{
if
((
crecp
->
flags
&
F_FORWARD
)
&&
#ifdef HAVE_DNSSEC
((
crecp
->
flags
&
(
F_DNSKEY
|
F_DS
))
==
(
prot
&
(
F_DNSKEY
|
F_DS
)))
&&
#endif
(
crecp
->
flags
&
prot
)
&&
hostname_isequal
(
cache_get_name
(
crecp
),
name
))
{
...
...
@@ -611,7 +658,10 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
if
(
ans
&&
(
ans
->
flags
&
F_FORWARD
)
&&
(
ans
->
flags
&
prot
)
&&
#ifdef HAVE_DNSSEC
((
ans
->
flags
&
(
F_DNSKEY
|
F_DS
))
==
(
prot
&
(
F_DNSKEY
|
F_DS
)))
&&
#endif
(
ans
->
flags
&
prot
)
&&
hostname_isequal
(
cache_get_name
(
ans
),
name
))
return
ans
;
...
...
@@ -971,7 +1021,9 @@ void cache_reload(void)
cache
->
name
.
namep
=
key
->
name
;
cache
->
uid
=
key
->
keylen
;
cache
->
addr
.
key
.
algo
=
key
->
algo
;
cache
->
addr
.
key
.
flags
=
key
->
flags
;
cache
->
addr
.
key
.
keytag
=
dnskey_keytag
(
key
->
algo
,
key
->
flags
,
(
unsigned
char
*
)
key
->
key
,
key
->
keylen
);
cache
->
addr
.
key
.
class
=
C_IN
;
/* TODO - in option? */
cache_hash
(
cache
);
}
#endif
...
...
@@ -1228,16 +1280,17 @@ void dump_cache(time_t now)
if
((
cache
->
flags
&
F_CNAME
)
&&
!
is_outdated_cname_pointer
(
cache
))
a
=
cache_get_cname_target
(
cache
);
#ifdef HAVE_DNSSEC
else
if
(
cache
->
flags
&
F_D
NSKEY
)
else
if
(
cache
->
flags
&
F_D
S
)
{
a
=
daemon
->
addrbuff
;
sprintf
(
a
,
"%3u %u"
,
cache
->
addr
.
key
.
algo
,
cache
->
uid
);
sprintf
(
a
,
"%5u %3u %3u"
,
cache
->
addr
.
ds
.
keytag
,
cache
->
addr
.
ds
.
algo
,
cache
->
addr
.
ds
.
digest
);
}
else
if
(
cache
->
flags
&
F_D
S
)
else
if
(
cache
->
flags
&
F_D
NSKEY
)
{
a
=
daemon
->
addrbuff
;
sprintf
(
a
,
"%5u %3u %3u"
,
cache
->
addr
.
key
.
keytag
,
cache
->
addr
.
key
.
algo
,
cache
->
addr
.
key
.
digest
);
cache
->
addr
.
key
.
algo
,
cache
->
addr
.
key
.
flags
);
}
#endif
else
if
(
!
(
cache
->
flags
&
F_NEG
)
||
!
(
cache
->
flags
&
F_FORWARD
))
...
...
src/dns-protocol.h
View file @
51ea3ca2
...
...
@@ -76,7 +76,6 @@
#define EDNS0_OPTION_MAC 65001
/* dyndns.org temporary assignment */
#define EDNS0_OPTION_CLIENT_SUBNET 8
/* IANA */
struct
dns_header
{
u16
id
;
u8
hb3
,
hb4
;
...
...
src/dnsmasq.h
View file @
51ea3ca2
...
...
@@ -244,7 +244,12 @@ struct all_addr {
#ifdef HAVE_IPV6
struct
in6_addr
addr6
;
#endif
/* for log_query */
unsigned
int
keytag
;
/* for cache_insert if RRSIG, DNSKEY, DS */
struct
{
unsigned
short
class
,
type
;
}
dnssec
;
}
addr
;
};
...
...
@@ -363,13 +368,22 @@ struct crec {
}
cname
;
struct
{
struct
blockdata
*
keydata
;
unsigned
short
class
,
flags
,
keytag
;
unsigned
char
algo
;
}
key
;
struct
{
struct
blockdata
*
keydata
;
unsigned
short
class
,
keytag
;
unsigned
char
algo
;
unsigned
char
digest
;
/* DS only */
unsigned
short
keytag
;
}
key
;
unsigned
char
digest
;
}
ds
;
struct
{
struct
blockdata
*
keydata
;
unsigned
short
class
,
type_covered
,
keytag
;
}
sig
;
}
addr
;
time_t
ttd
;
/* time to die */
/* used as keylen if
F_DNSKEY
, index to source for F_HOSTS */
/* used as keylen if
F_DNSKEY or F_DS
, index to source for F_HOSTS */
int
uid
;
unsigned
short
flags
;
union
{
...
...
@@ -409,7 +423,7 @@ struct crec {
#define F_SECSTAT (1u<<24)
/* composites */
#define F_TYPE (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)
/*
Only one may be set
*/
#define F_TYPE (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)
/*
F_DS & F_DNSKEY -> RRSIG yuck.
*/
...
...
src/dnssec.c
View file @
51ea3ca2
...
...
@@ -707,7 +707,9 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
{
/* iterate through all possible keys 4035 5.3.1 */
for
(;
crecp
;
crecp
=
cache_find_by_name
(
crecp
,
keyname
,
now
,
F_DNSKEY
))
if
(
crecp
->
addr
.
key
.
algo
==
algo
&&
crecp
->
addr
.
key
.
keytag
==
key_tag
&&
if
(
crecp
->
addr
.
key
.
algo
==
algo
&&
crecp
->
addr
.
key
.
keytag
==
key_tag
&&
crecp
->
addr
.
key
.
class
==
class
&&
verify
(
crecp
->
addr
.
key
.
keydata
,
crecp
->
uid
,
sig
,
sig_len
,
digest
,
algo
))
return
STAT_SECURE
;
}
...
...
@@ -732,6 +734,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
struct
crec
*
crecp
,
*
recp1
;
int
rc
,
j
,
qtype
,
qclass
,
ttl
,
rdlen
,
flags
,
algo
,
valid
,
keytag
;
struct
blockdata
*
key
;
struct
all_addr
a
;
if
(
ntohs
(
header
->
qdcount
)
!=
1
||
!
extract_name
(
header
,
plen
,
&
p
,
name
,
1
,
4
))
...
...
@@ -786,23 +789,34 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
algo
=
*
p
++
;
keytag
=
dnskey_keytag
(
algo
,
flags
,
p
,
rdlen
-
4
);
/* Cache needs to known class for DNSSEC stuff */
a
.
addr
.
dnssec
.
class
=
class
;
/* Put the key into the cache. Note that if the validation fails, we won't
call cache_end_insert() and this will never be committed. */
if
((
key
=
blockdata_alloc
((
char
*
)
p
,
rdlen
-
4
))
&&
(
recp1
=
cache_insert
(
name
,
NULL
,
now
,
ttl
,
F_FORWARD
|
F_DNSKEY
)))
(
recp1
=
cache_insert
(
name
,
&
a
,
now
,
ttl
,
F_FORWARD
|
F_DNSKEY
|
F_DNSSECOK
)))
{
struct
all_addr
a
;
a
.
addr
.
keytag
=
keytag
;
log_query
(
F_KEYTAG
|
F_UPSTREAM
,
name
,
&
a
,
"DNSKEY keytag %u"
);
recp1
->
uid
=
rdlen
-
4
;
recp1
->
addr
.
key
.
keydata
=
key
;
recp1
->
addr
.
key
.
algo
=
algo
;
recp1
->
addr
.
key
.
keytag
=
keytag
;
recp1
->
addr
.
key
.
flags
=
flags
;
recp1
->
addr
.
key
.
class
=
class
;
}
p
=
psave
;
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
STAT_INSECURE
;
/* bad packet */
/* Already determined that message is OK. Just loop stuffing cache */
if
(
valid
||
!
key
)
/* Already determined that message is OK or failed to store or ineligable
(ie no zone key flag) key. Don't attempt to validate, just loop stuffing cache */
if
(
valid
||
!
key
||
!
(
flags
&
0x100
))
continue
;
for
(
recp1
=
crecp
;
recp1
;
recp1
=
cache_find_by_name
(
recp1
,
name
,
now
,
F_DS
))
...
...
@@ -811,10 +825,10 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
unsigned
char
*
digest
,
*
ds_digest
;
const
struct
nettle_hash
*
hash
;
if
(
recp1
->
addr
.
key
.
algo
==
algo
&&
recp1
->
addr
.
key
.
keytag
==
keytag
&&
(
flags
&
0x100
)
&&
/* zone key flag */
(
hash
=
hash_find
(
ds_digest_name
(
recp1
->
addr
.
key
.
digest
)))
&&
if
(
recp1
->
addr
.
ds
.
algo
==
algo
&&
recp1
->
addr
.
ds
.
keytag
==
keytag
&&
recp1
->
addr
.
ds
.
class
==
class
&&
(
hash
=
hash_find
(
ds_digest_name
(
recp1
->
addr
.
ds
.
digest
)))
&&
hash_init
(
hash
,
&
ctx
,
&
digest
))
{
...
...
@@ -833,10 +847,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
memcmp
(
ds_digest
,
digest
,
recp1
->
uid
)
==
0
&&
validate_rrset
(
now
,
header
,
plen
,
class
,
T_DNSKEY
,
name
,
keyname
,
key
,
rdlen
-
4
,
algo
,
keytag
))
{
struct
all_addr
a
;
valid
=
1
;
a
.
addr
.
keytag
=
keytag
;
log_query
(
F_KEYTAG
|
F_UPSTREAM
,
name
,
&
a
,
"DNSKEY keytag %u"
);
break
;
}
}
...
...
@@ -866,10 +877,8 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
int
dnssec_validate_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
)
{
unsigned
char
*
psave
,
*
p
=
(
unsigned
char
*
)(
header
+
1
);
struct
crec
*
crecp
;
int
qtype
,
qclass
,
val
,
j
;
struct
blockdata
*
key
;
unsigned
char
*
p
=
(
unsigned
char
*
)(
header
+
1
);
int
qtype
,
qclass
,
val
;
if
(
ntohs
(
header
->
qdcount
)
!=
1
||
!
extract_name
(
header
,
plen
,
&
p
,
name
,
1
,
4
))
...
...
@@ -884,68 +893,12 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
if
(
qtype
!=
T_DS
||
qclass
!=
class
||
ntohs
(
header
->
ancount
)
==
0
)
return
STAT_INSECURE
;
val
=
validate_rrset
(
now
,
header
,
plen
,
class
,
T_DS
,
name
,
keyname
,
NULL
,
0
,
0
,
0
);
val
=
dnssec_validate_reply
(
now
,
header
,
plen
,
name
,
keyname
,
NULL
);
if
(
val
==
STAT_BOGUS
)
log_query
(
F_UPSTREAM
,
name
,
NULL
,
"BOGUS DS"
);
/* failed to validate or missing key. */
if
(
val
!=
STAT_SECURE
)
return
val
;
cache_start_insert
();
for
(
j
=
ntohs
(
header
->
ancount
);
j
!=
0
;
j
--
)
{
int
ttl
,
rdlen
,
rc
,
algo
,
digest
,
keytag
;
/* Ensure we have type, class TTL and length */
if
(
!
(
rc
=
extract_name
(
header
,
plen
,
&
p
,
name
,
0
,
10
)))
return
STAT_INSECURE
;
/* bad packet */
GETSHORT
(
qtype
,
p
);
GETSHORT
(
qclass
,
p
);
GETLONG
(
ttl
,
p
);
GETSHORT
(
rdlen
,
p
);
/* check type, class and name, skip if not in DS rrset */
if
(
qclass
==
class
&&
qtype
==
T_DS
&&
rc
==
1
)
{
if
(
!
CHECK_LEN
(
header
,
p
,
plen
,
rdlen
)
||
rdlen
<
4
)
return
STAT_INSECURE
;
/* bad packet */
psave
=
p
;
GETSHORT
(
keytag
,
p
);
algo
=
*
p
++
;
digest
=
*
p
++
;
/* We've proved that the DS is OK, store it in the cache */
if
((
key
=
blockdata_alloc
((
char
*
)
p
,
rdlen
-
4
))
&&
(
crecp
=
cache_insert
(
name
,
NULL
,
now
,
ttl
,
F_FORWARD
|
F_DS
)))
{
struct
all_addr
a
;
a
.
addr
.
keytag
=
keytag
;
log_query
(
F_KEYTAG
|
F_UPSTREAM
,
name
,
&
a
,
"DS keytag %u"
);
crecp
->
addr
.
key
.
digest
=
digest
;
crecp
->
addr
.
key
.
keydata
=
key
;
crecp
->
addr
.
key
.
algo
=
algo
;
crecp
->
addr
.
key
.
keytag
=
keytag
;
crecp
->
uid
=
rdlen
-
4
;
}
else
return
STAT_INSECURE
;
/* cache problem */
p
=
psave
;
}
if
(
!
ADD_RDLEN
(
header
,
p
,
plen
,
rdlen
))
return
STAT_INSECURE
;
/* bad packet */
}
cache_end_insert
();
return
STAT_SECURE
;
return
val
;
}
/* 4034 6.1 */
...
...
@@ -1014,6 +967,7 @@ static int hostname_cmp(const char *a, const char *b)
/* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */
/* Returns are the same as validate_rrset, plus the class if the missing key is in *class */
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
*
class
)
{
unsigned
char
*
ans_start
,
*
p1
,
*
p2
;
...
...
@@ -1058,10 +1012,68 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
}
/* Not done, validate now */
if
(
j
==
i
&&
(
rc
=
validate_rrset
(
now
,
header
,
plen
,
class1
,
type1
,
name
,
keyname
,
NULL
,
0
,
0
,
0
))
!=
STAT_SECURE
)
if
(
j
==
i
)
{
*
class
=
class1
;
/* Class for DS or DNSKEY */
return
rc
;
if
((
rc
=
validate_rrset
(
now
,
header
,
plen
,
class1
,
type1
,
name
,
keyname
,
NULL
,
0
,
0
,
0
))
!=
STAT_SECURE
)
{
if
(
class
)
*
class
=
class1
;
/* Class for DS or DNSKEY */
return
rc
;
}
/* If we just validated a DS RRset, cache it */
if
(
type1
==
T_DS
)
{
int
ttl
,
keytag
,
algo
,
digest
;
unsigned
char
*
psave
;
struct
all_addr
a
;
struct
blockdata
*
key
;
struct
crec
*
crecp
;
cache_start_insert
();
for
(
p2
=
ans_start
,
j
=
0
;
j
<
ntohs
(
header
->
ancount
)
+
ntohs
(
header
->
nscount
);
j
++
)
{
if
(
!
(
rc
=
extract_name
(
header
,
plen
,
&
p2
,
name
,
0
,
10
)))
return
STAT_INSECURE
;
/* bad packet */
GETSHORT
(
type2
,
p2
);
GETSHORT
(
class2
,
p2
);
GETLONG
(
ttl
,
p2
);
GETSHORT
(
rdlen2
,
p2
);
if
(
type2
==
T_DS
&&
class2
==
class1
&&
rc
==
1
)
{
psave
=
p2
;
GETSHORT
(
keytag
,
p2
);
algo
=
*
p2
++
;
digest
=
*
p2
++
;
/* Cache needs to known class for DNSSEC stuff */
a
.
addr
.
dnssec
.
class
=
class2
;
if
((
key
=
blockdata_alloc
((
char
*
)
p2
,
rdlen2
-
4
))
&&
(
crecp
=
cache_insert
(
name
,
&
a
,
now
,
ttl
,
F_FORWARD
|
F_DS
|
F_DNSSECOK
)))
{
a
.
addr
.
keytag
=
keytag
;
log_query
(
F_KEYTAG
|
F_UPSTREAM
,
name
,
&
a
,
"DS keytag %u"
);
crecp
->
addr
.
ds
.
digest
=
digest
;
crecp
->
addr
.
ds
.
keydata
=
key
;
crecp
->
addr
.
ds
.
algo
=
algo
;
crecp
->
addr
.
ds
.
keytag
=
keytag
;
crecp
->
addr
.
ds
.
class
=
class2
;
crecp
->
uid
=
rdlen2
-
4
;
}
p2
=
psave
;
}
if
(
!
ADD_RDLEN
(
header
,
p2
,
plen
,
rdlen2
))
return
STAT_INSECURE
;
/* bad packet */
}
cache_end_insert
();
}
}
}
...
...
@@ -1079,6 +1091,10 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
GETSHORT
(
type1
,
p1
);
GETSHORT
(
class1
,
p1
);
/* Can't validate RRSIG query */
if
(
type1
==
T_RRSIG
)
return
STAT_INSECURE
;
cname_loop:
for
(
j
=
ntohs
(
header
->
ancount
);
j
!=
0
;
j
--
)
{
...
...
src/rfc1035.c
View file @
51ea3ca2
...
...
@@ -1368,6 +1368,11 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
p
+=
INADDRSZ
;
break
;
case
'b'
:
usval
=
va_arg
(
ap
,
int
);
*
p
++
=
usval
;
break
;
case
's'
:
usval
=
va_arg
(
ap
,
int
);
PUTSHORT
(
usval
,
p
);
...
...
@@ -1538,6 +1543,58 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
}
#ifdef HAVE_DNSSEC
if
((
qtype
==
T_DNSKEY
||
qtype
==
T_ANY
)
&&
(
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_DNSKEY
)))
{
do
{
char
*
keydata
;
if
(
crecp
->
addr
.
ds
.
class
==
qclass
&&
(
qtype
==
T_DNSKEY
||
(
crecp
->
flags
&
F_CONFIG
))
&&
(
keydata
=
blockdata_retrieve
(
crecp
->
addr
.
key
.
keydata
,
crecp
->
uid
,
NULL
)))
{
ans
=
1
;
if
(
!
dryrun
)
{
struct
all_addr
a
;
a
.
addr
.
keytag
=
crecp
->
addr
.
key
.
keytag
;
log_query
(
F_KEYTAG
|
(
crecp
->
flags
&
F_CONFIG
),
name
,
&
a
,
"DNSKEY keytag %u"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
crec_ttl
(
crecp
,
now
),
&
nameoffset
,
T_DNSKEY
,
qclass
,
"sbbt"
,
crecp
->
addr
.
key
.
flags
,
3
,
crecp
->
addr
.
key
.
algo
,
crecp
->
uid
,
keydata
))
anscount
++
;
}
}
}
while
(
crecp
=
cache_find_by_name
(
crecp
,
name
,
now
,
F_DNSKEY
));
}
if
((
qtype
==
T_DS
||
qtype
==
T_ANY
)
&&
(
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_DS
)))
{
do
{
char
*
keydata
;
if
(
crecp
->
addr
.
ds
.
class
==
qclass
&&
(
qtype
==
T_DS
||
(
crecp
->
flags
&
F_CONFIG
))
&&
(
keydata
=
blockdata_retrieve
(
crecp
->
addr
.
ds
.
keydata
,
crecp
->
uid
,
NULL
)))
{
ans
=
1
;
if
(
!
dryrun
)
{
struct
all_addr
a
;
a
.
addr
.
keytag
=
crecp
->
addr
.
ds
.
keytag
;
log_query
(
F_KEYTAG
|
(
crecp
->
flags
&
F_CONFIG
),
name
,
&
a
,
"DS keytag %u"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
crec_ttl
(
crecp
,
now
),
&
nameoffset
,
T_DS
,
qclass
,
"sbbt"
,
crecp
->
addr
.
ds
.
keytag
,
crecp
->
addr
.
ds
.
algo
,
crecp
->
addr
.
ds
.
digest
,
crecp
->
uid
,
keydata
))
anscount
++
;
}
}
}
while
(
crecp
=
cache_find_by_name
(
crecp
,
name
,
now
,
F_DS
));
}
#endif
if
(
qclass
==
C_IN
)
{
struct
txt_record
*
t
;
...
...
@@ -1901,7 +1958,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
}
}
if
(
qtype
==
T_MX
||
qtype
==
T_ANY
)
{
int
found
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment