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
fa14bec8
Commit
fa14bec8
authored
Dec 20, 2015
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Major tidy up of EDNS0 handling and computation/use of udp packet size.
parent
14a4ae88
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
168 additions
and
118 deletions
+168
-118
src/auth.c
src/auth.c
+7
-1
src/dnsmasq.h
src/dnsmasq.h
+5
-2
src/dnssec.c
src/dnssec.c
+0
-1
src/forward.c
src/forward.c
+132
-52
src/netlink.c
src/netlink.c
+2
-1
src/rfc1035.c
src/rfc1035.c
+21
-60
src/rrfilter.c
src/rrfilter.c
+1
-1
No files found.
src/auth.c
View file @
fa14bec8
...
...
@@ -81,7 +81,8 @@ int in_zone(struct auth_zone *zone, char *name, char **cut)
}
size_t
answer_auth
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
time_t
now
,
union
mysockaddr
*
peer_addr
,
int
local_query
)
size_t
answer_auth
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
time_t
now
,
union
mysockaddr
*
peer_addr
,
int
local_query
,
int
do_bit
,
int
have_pseudoheader
)
{
char
*
name
=
daemon
->
namebuff
;
unsigned
char
*
p
,
*
ansp
;
...
...
@@ -820,6 +821,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
header
->
ancount
=
htons
(
anscount
);
header
->
nscount
=
htons
(
authcount
);
header
->
arcount
=
htons
(
0
);
/* Advertise our packet size limit in our reply */
if
(
have_pseudoheader
)
return
add_pseudoheader
(
header
,
ansp
-
(
unsigned
char
*
)
header
,
(
unsigned
char
*
)
limit
,
daemon
->
edns_pktsz
,
0
,
NULL
,
0
,
do_bit
);
return
ansp
-
(
unsigned
char
*
)
header
;
}
...
...
src/dnsmasq.h
View file @
fa14bec8
...
...
@@ -1113,7 +1113,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
int
no_cache
,
int
secure
,
int
*
doctored
);
size_t
answer_request
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
struct
in_addr
local_addr
,
struct
in_addr
local_netmask
,
time_t
now
,
int
*
ad_reqd
,
int
*
do_bit
);
time_t
now
,
int
ad_reqd
,
int
do_bit
,
int
have_pseudoheader
);
int
check_for_bogus_wildcard
(
struct
dns_header
*
header
,
size_t
qlen
,
char
*
name
,
struct
bogus_addr
*
addr
,
time_t
now
);
int
check_for_ignored_address
(
struct
dns_header
*
header
,
size_t
qlen
,
struct
bogus_addr
*
baddr
);
...
...
@@ -1123,6 +1123,8 @@ int check_for_local_domain(char *name, time_t now);
unsigned
int
questions_crc
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
buff
);
size_t
resize_packet
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
pheader
,
size_t
hlen
);
size_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
unsigned
short
udp_sz
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
);
size_t
add_mac
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
l3
);
size_t
add_source_addr
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
source
);
#ifdef HAVE_DNSSEC
...
...
@@ -1141,7 +1143,8 @@ int private_net(struct in_addr addr, int ban_localhost);
/* auth.c */
#ifdef HAVE_AUTH
size_t
answer_auth
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
time_t
now
,
union
mysockaddr
*
peer_addr
,
int
local_query
);
time_t
now
,
union
mysockaddr
*
peer_addr
,
int
local_query
,
int
do_bit
,
int
have_pseudoheader
);
int
in_zone
(
struct
auth_zone
*
zone
,
char
*
name
,
char
**
cut
);
#endif
...
...
src/dnssec.c
View file @
fa14bec8
...
...
@@ -67,7 +67,6 @@ static char *algo_digest_name(int algo)
case
12
:
return
"gosthash94"
;
case
13
:
return
"sha256"
;
case
14
:
return
"sha384"
;
default:
return
NULL
;
}
}
...
...
src/forward.c
View file @
fa14bec8
...
...
@@ -244,7 +244,6 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
void
*
hash
=
&
crc
;
#endif
unsigned
int
gotname
=
extract_request
(
header
,
plen
,
daemon
->
namebuff
,
NULL
);
unsigned
char
*
pheader
;
(
void
)
do_bit
;
...
...
@@ -264,7 +263,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
there's no point retrying the query, retry the key query instead...... */
if
(
forward
->
blocking_query
)
{
int
fd
;
int
fd
,
is_sign
;
unsigned
char
*
pheader
;
forward
->
flags
&=
~
FREC_TEST_PKTSZ
;
...
...
@@ -276,8 +276,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
blockdata_retrieve
(
forward
->
stash
,
forward
->
stash_len
,
(
void
*
)
header
);
plen
=
forward
->
stash_len
;
if
(
find_pseudoheader
(
header
,
plen
,
NULL
,
&
pheader
,
NULL
)
)
PUTSHORT
(
(
forward
->
flags
&
FREC_TEST_PKTSZ
)
?
SAFE_PKTSZ
:
forward
->
sentto
->
edns_pktsz
,
pheader
);
if
(
find_pseudoheader
(
header
,
plen
,
NULL
,
&
pheader
,
&
is_sign
)
&&
!
is_sign
)
PUTSHORT
(
SAFE_PKTSZ
,
pheader
);
if
(
forward
->
sentto
->
addr
.
sa
.
sa_family
==
AF_INET
)
log_query
(
F_NOEXTRA
|
F_DNSSEC
|
F_IPV4
,
"retry"
,
(
struct
all_addr
*
)
&
forward
->
sentto
->
addr
.
in
.
sin_addr
,
"dnssec"
);
...
...
@@ -394,32 +394,40 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
forward
->
log_id
=
daemon
->
log_id
;
if
(
option_bool
(
OPT_ADD_MAC
))
plen
=
add_mac
(
header
,
plen
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
,
&
forward
->
source
);
{
size_t
new
=
add_mac
(
header
,
plen
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
,
&
forward
->
source
);
if
(
new
!=
plen
)
{
plen
=
new
;
forward
->
flags
|=
FREC_ADDED_PHEADER
;
}
}
if
(
option_bool
(
OPT_CLIENT_SUBNET
))
{
size_t
new
=
add_source_addr
(
header
,
plen
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
,
&
forward
->
source
);
if
(
new
!=
plen
)
{
plen
=
new
;
forward
->
flags
|=
FREC_HAS_SUBNET
;
forward
->
flags
|=
FREC_HAS_SUBNET
|
FREC_ADDED_PHEADER
;
}
}
#ifdef HAVE_DNSSEC
if
(
option_bool
(
OPT_DNSSEC_VALID
))
{
size_t
new
_plen
=
add_do_bit
(
header
,
plen
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
);
size_t
new
=
add_do_bit
(
header
,
plen
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
);
if
(
new
!=
plen
)
forward
->
flags
|=
FREC_ADDED_PHEADER
;
plen
=
new
;
/* For debugging, set Checking Disabled, otherwise, have the upstream check too,
this allows it to select auth servers when one is returning bad data. */
if
(
option_bool
(
OPT_DNSSEC_DEBUG
))
header
->
hb4
|=
HB4_CD
;
if
(
new_plen
!=
plen
)
forward
->
flags
|=
FREC_ADDED_PHEADER
;
plen
=
new_plen
;
}
#endif
...
...
@@ -469,10 +477,23 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
}
#endif
}
if
(
find_pseudoheader
(
header
,
plen
,
NULL
,
&
pheader
,
NULL
))
PUTSHORT
((
forward
->
flags
&
FREC_TEST_PKTSZ
)
?
SAFE_PKTSZ
:
start
->
edns_pktsz
,
pheader
);
#ifdef HAVE_DNSSEC
if
(
option_bool
(
OPT_DNSSEC_VALID
)
&&
!
do_bit
)
{
/* Difficult one here. If our client didn't send EDNS0, we will have set the UDP
packet size to 512. But that won't provide space for the RRSIGS in many cases.
The RRSIGS will be stripped out before the answer goes back, so the packet should
shrink again. So, if we added a do-bit, bump the udp packet size to the value
known to be OK for this server. Maybe check returned size after stripping and set
the truncated bit? */
unsigned
char
*
pheader
;
int
is_sign
;
if
(
find_pseudoheader
(
header
,
plen
,
NULL
,
&
pheader
,
&
is_sign
))
PUTSHORT
(
start
->
edns_pktsz
,
pheader
);
}
#endif
if
(
retry_send
(
sendto
(
fd
,
(
char
*
)
header
,
plen
,
0
,
&
start
->
addr
.
sa
,
sa_len
(
&
start
->
addr
))))
...
...
@@ -563,30 +584,34 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
}
#endif
/* If upstream is advertising a larger UDP packet size
than we allow, trim it so that we don't get overlarge
requests for the client. We can't do this for signed packets. */
if
((
pheader
=
find_pseudoheader
(
header
,
n
,
&
plen
,
&
sizep
,
&
is_sign
)))
{
unsigned
short
udpsz
;
unsigned
char
*
psave
=
sizep
;
GETSHORT
(
udpsz
,
sizep
);
if
(
!
is_sign
&&
udpsz
>
daemon
->
edns_pktsz
)
PUTSHORT
(
daemon
->
edns_pktsz
,
psave
);
if
(
check_subnet
&&
!
check_source
(
header
,
plen
,
pheader
,
query_source
))
{
my_syslog
(
LOG_WARNING
,
_
(
"discarding DNS reply: subnet option mismatch"
));
return
0
;
}
if
(
added_pheader
)
if
(
!
is_sign
)
{
pheader
=
0
;
header
->
arcount
=
htons
(
0
);
if
(
added_pheader
)
{
/* client didn't send EDNS0, we added one, strip it off before returning answer. */
n
=
rrfilter
(
header
,
n
,
0
);
pheader
=
NULL
;
}
else
{
/* If upstream is advertising a larger UDP packet size
than we allow, trim it so that we don't get overlarge
requests for the client. We can't do this for signed packets. */
unsigned
short
udpsz
;
unsigned
char
*
psave
=
sizep
;
GETSHORT
(
udpsz
,
sizep
);
if
(
udpsz
>
daemon
->
edns_pktsz
)
PUTSHORT
(
daemon
->
edns_pktsz
,
psave
);
}
}
}
...
...
@@ -655,14 +680,16 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
}
if
(
option_bool
(
OPT_DNSSEC_VALID
))
header
->
hb4
&=
~
HB4_AD
;
if
(
!
(
header
->
hb4
&
HB4_CD
)
&&
ad_reqd
&&
cache_secure
)
header
->
hb4
|=
HB4_AD
;
/* If the requestor didn't set the DO bit, don't return DNSSEC info. */
if
(
!
do_bit
)
n
=
rrfilter
(
header
,
n
,
1
);
{
header
->
hb4
&=
~
HB4_AD
;
if
(
!
(
header
->
hb4
&
HB4_CD
)
&&
ad_reqd
&&
cache_secure
)
header
->
hb4
|=
HB4_AD
;
/* If the requestor didn't set the DO bit, don't return DNSSEC info. */
if
(
!
do_bit
)
n
=
rrfilter
(
header
,
n
,
1
);
}
#endif
/* do this after extract_addresses. Ensure NODATA reply and remove
...
...
@@ -761,8 +788,14 @@ void reply_query(int fd, int family, time_t now)
if
((
nn
=
resize_packet
(
header
,
(
size_t
)
n
,
pheader
,
plen
)))
{
header
->
hb3
&=
~
(
HB3_QR
|
HB3_AA
|
HB3_TC
);
header
->
hb4
&=
~
(
HB4_RA
|
HB4_RCODE
);
forward_query
(
-
1
,
NULL
,
NULL
,
0
,
header
,
nn
,
now
,
forward
,
0
,
0
);
header
->
hb4
&=
~
(
HB4_RA
|
HB4_RCODE
|
HB4_CD
|
HB4_AD
);
if
(
forward
->
flags
|=
FREC_CHECKING_DISABLED
)
header
->
hb4
|=
HB4_CD
;
if
(
forward
->
flags
|=
FREC_AD_QUESTION
)
header
->
hb4
|=
HB4_AD
;
if
(
forward
->
flags
&
FREC_DO_QUESTION
)
add_do_bit
(
header
,
nn
,
(
char
*
)
pheader
+
plen
);
forward_query
(
-
1
,
NULL
,
NULL
,
0
,
header
,
nn
,
now
,
forward
,
forward
->
flags
&
FREC_AD_QUESTION
,
forward
->
flags
&
FREC_DO_QUESTION
);
return
;
}
}
...
...
@@ -1007,12 +1040,13 @@ void receive_query(struct listener *listen, time_t now)
{
struct
dns_header
*
header
=
(
struct
dns_header
*
)
daemon
->
packet
;
union
mysockaddr
source_addr
;
unsigned
short
type
;
unsigned
char
*
pheader
;
unsigned
short
type
,
udp_size
=
PACKETSZ
;
/* default if no EDNS0 */
struct
all_addr
dst_addr
;
struct
in_addr
netmask
,
dst_addr_4
;
size_t
m
;
ssize_t
n
;
int
if_index
=
0
,
auth_dns
=
0
;
int
if_index
=
0
,
auth_dns
=
0
,
do_bit
=
0
,
have_pseudoheader
=
0
;
#ifdef HAVE_AUTH
int
local_auth
=
0
;
#endif
...
...
@@ -1279,10 +1313,30 @@ void receive_query(struct listener *listen, time_t now)
#endif
}
if
(
find_pseudoheader
(
header
,
(
size_t
)
n
,
NULL
,
&
pheader
,
NULL
))
{
unsigned
short
flags
;
have_pseudoheader
=
1
;
GETSHORT
(
udp_size
,
pheader
);
pheader
+=
2
;
/* ext_rcode */
GETSHORT
(
flags
,
pheader
);
if
(
flags
&
0x8000
)
do_bit
=
1
;
/* do bit */
/* If the client provides an EDNS0 UDP size, use that to limit our reply.
(bounded by the maximum configured). If no EDNS0, then it
defaults to 512 */
if
(
udp_size
>
daemon
->
edns_pktsz
)
udp_size
=
daemon
->
edns_pktsz
;
}
#ifdef HAVE_AUTH
if
(
auth_dns
)
{
m
=
answer_auth
(
header
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
,
(
size_t
)
n
,
now
,
&
source_addr
,
local_auth
);
m
=
answer_auth
(
header
,
((
char
*
)
header
)
+
udp_size
,
(
size_t
)
n
,
now
,
&
source_addr
,
local_auth
,
do_bit
,
have_pseudoheader
);
if
(
m
>=
1
)
{
send_from
(
listen
->
fd
,
option_bool
(
OPT_NOWILD
)
||
option_bool
(
OPT_CLEVERBIND
),
...
...
@@ -1293,9 +1347,13 @@ void receive_query(struct listener *listen, time_t now)
else
#endif
{
int
ad_reqd
,
do_bit
;
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
daemon
->
packet_buff_sz
,
(
size_t
)
n
,
dst_addr_4
,
netmask
,
now
,
&
ad_reqd
,
&
do_bit
);
int
ad_reqd
=
do_bit
;
/* RFC 6840 5.7 */
if
(
header
->
hb4
&
HB4_AD
)
ad_reqd
=
1
;
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
udp_size
,
(
size_t
)
n
,
dst_addr_4
,
netmask
,
now
,
ad_reqd
,
do_bit
,
have_pseudoheader
);
if
(
m
>=
1
)
{
...
...
@@ -1397,7 +1455,7 @@ unsigned char *tcp_request(int confd, time_t now,
#ifdef HAVE_AUTH
int
local_auth
=
0
;
#endif
int
checking_disabled
,
ad_question
,
do_bit
,
added_p
header
=
0
;
int
checking_disabled
,
do_bit
,
added_pheader
=
0
,
have_pseudo
header
=
0
;
int
check_subnet
,
no_cache_dnssec
=
0
,
cache_secure
=
0
,
bogusanswer
=
0
;
size_t
m
;
unsigned
short
qtype
;
...
...
@@ -1414,6 +1472,7 @@ unsigned char *tcp_request(int confd, time_t now,
union
mysockaddr
peer_addr
;
socklen_t
peer_len
=
sizeof
(
union
mysockaddr
);
int
query_count
=
0
;
unsigned
char
*
pheader
;
if
(
getpeername
(
confd
,
(
struct
sockaddr
*
)
&
peer_addr
,
&
peer_len
)
==
-
1
)
return
packet
;
...
...
@@ -1508,15 +1567,35 @@ unsigned char *tcp_request(int confd, time_t now,
else
dst_addr_4
.
s_addr
=
0
;
do_bit
=
0
;
if
(
find_pseudoheader
(
header
,
(
size_t
)
size
,
NULL
,
&
pheader
,
NULL
))
{
unsigned
short
flags
;
have_pseudoheader
=
1
;
pheader
+=
4
;
/* udp_size, ext_rcode */
GETSHORT
(
flags
,
pheader
);
if
(
flags
&
0x8000
)
do_bit
=
1
;
/* do bit */
}
#ifdef HAVE_AUTH
if
(
auth_dns
)
m
=
answer_auth
(
header
,
((
char
*
)
header
)
+
65536
,
(
size_t
)
size
,
now
,
&
peer_addr
,
local_auth
);
m
=
answer_auth
(
header
,
((
char
*
)
header
)
+
65536
,
(
size_t
)
size
,
now
,
&
peer_addr
,
local_auth
,
do_bit
,
have_pseudoheader
);
else
#endif
{
/* m > 0 if answered from cache */
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
65536
,
(
size_t
)
size
,
dst_addr_4
,
netmask
,
now
,
&
ad_question
,
&
do_bit
);
int
ad_reqd
=
do_bit
;
/* RFC 6840 5.7 */
if
(
header
->
hb4
&
HB4_AD
)
ad_reqd
=
1
;
/* m > 0 if answered from cache */
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
65536
,
(
size_t
)
size
,
dst_addr_4
,
netmask
,
now
,
ad_reqd
,
do_bit
,
have_pseudoheader
);
/* Do this by steam now we're not in the select() loop */
check_log_writer
(
1
);
...
...
@@ -1615,6 +1694,7 @@ unsigned char *tcp_request(int confd, time_t now,
}
#ifdef HAVE_DNSSEC
added_pheader
=
0
;
if
(
option_bool
(
OPT_DNSSEC_VALID
))
{
size_t
new_size
=
add_do_bit
(
header
,
size
,
((
char
*
)
header
)
+
65536
);
...
...
@@ -1719,7 +1799,7 @@ unsigned char *tcp_request(int confd, time_t now,
m
=
process_reply
(
header
,
now
,
last_server
,
(
unsigned
int
)
m
,
option_bool
(
OPT_NO_REBIND
)
&&
!
norebind
,
no_cache_dnssec
,
cache_secure
,
bogusanswer
,
ad_
question
,
do_bit
,
added_pheader
,
check_subnet
,
&
peer_addr
);
ad_
reqd
,
do_bit
,
added_pheader
,
check_subnet
,
&
peer_addr
);
break
;
}
...
...
src/netlink.c
View file @
fa14bec8
...
...
@@ -288,7 +288,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
rta
=
RTA_NEXT
(
rta
,
len1
);
}
if
(
inaddr
&&
mac
&&
callback_ok
)
if
(
!
(
neigh
->
ndm_state
&
(
NUD_NOARP
|
NUD_INCOMPLETE
|
NUD_FAILED
))
&&
inaddr
&&
mac
&&
callback_ok
)
if
(
!
((
*
callback
)(
neigh
->
ndm_family
,
inaddr
,
mac
,
maclen
,
parm
)))
callback_ok
=
0
;
}
...
...
src/rfc1035.c
View file @
fa14bec8
...
...
@@ -489,8 +489,8 @@ struct macparm {
union
mysockaddr
*
l3
;
};
s
tatic
s
ize_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
)
size_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
unsigned
short
udp_sz
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
)
{
unsigned
char
*
lenp
,
*
datap
,
*
p
;
int
rdlen
,
is_sign
;
...
...
@@ -508,7 +508,7 @@ static size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned
return
plen
;
*
p
++
=
0
;
/* empty name */
PUTSHORT
(
T_OPT
,
p
);
PUTSHORT
(
SAFE_PKTSZ
,
p
);
/* max packet length, this will be overwritten
*/
PUTSHORT
(
udp_sz
,
p
);
/* max packet length, 512 if not given in EDNS0 header
*/
PUTSHORT
(
0
,
p
);
/* extended RCODE and version */
PUTSHORT
(
set_do
?
0x8000
:
0
,
p
);
/* DO flag */
lenp
=
p
;
...
...
@@ -594,7 +594,7 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
if
(
!
match
)
return
1
;
/* continue */
parm
->
plen
=
add_pseudoheader
(
parm
->
header
,
parm
->
plen
,
parm
->
limit
,
EDNS0_OPTION_MAC
,
(
unsigned
char
*
)
mac
,
maclen
,
0
);
parm
->
plen
=
add_pseudoheader
(
parm
->
header
,
parm
->
plen
,
parm
->
limit
,
PACKETSZ
,
EDNS0_OPTION_MAC
,
(
unsigned
char
*
)
mac
,
maclen
,
0
);
return
0
;
/* done */
}
...
...
@@ -603,12 +603,6 @@ size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysock
{
struct
macparm
parm
;
/* Must have an existing pseudoheader as the only ar-record,
or have no ar-records. Must also not be signed */
if
(
ntohs
(
header
->
arcount
)
>
1
)
return
plen
;
parm
.
header
=
header
;
parm
.
limit
=
(
unsigned
char
*
)
limit
;
parm
.
plen
=
plen
;
...
...
@@ -699,13 +693,13 @@ size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, unio
struct
subnet_opt
opt
;
len
=
calc_subnet_opt
(
&
opt
,
source
);
return
add_pseudoheader
(
header
,
plen
,
(
unsigned
char
*
)
limit
,
EDNS0_OPTION_CLIENT_SUBNET
,
(
unsigned
char
*
)
&
opt
,
len
,
0
);
return
add_pseudoheader
(
header
,
plen
,
(
unsigned
char
*
)
limit
,
PACKETSZ
,
EDNS0_OPTION_CLIENT_SUBNET
,
(
unsigned
char
*
)
&
opt
,
len
,
0
);
}
#ifdef HAVE_DNSSEC
size_t
add_do_bit
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
)
{
return
add_pseudoheader
(
header
,
plen
,
(
unsigned
char
*
)
limit
,
0
,
NULL
,
0
,
1
);
return
add_pseudoheader
(
header
,
plen
,
(
unsigned
char
*
)
limit
,
PACKETSZ
,
0
,
NULL
,
0
,
1
);
}
#endif
...
...
@@ -1525,16 +1519,16 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
/* return zero if we can't answer from cache, or packet size if we can */
size_t
answer_request
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
struct
in_addr
local_addr
,
struct
in_addr
local_netmask
,
time_t
now
,
int
*
ad_reqd
,
int
*
do_bit
)
time_t
now
,
int
ad_reqd
,
int
do_bit
,
int
have_pseudoheader
)
{
char
*
name
=
daemon
->
namebuff
;
unsigned
char
*
p
,
*
ansp
,
*
pheader
;
unsigned
char
*
p
,
*
ansp
;
unsigned
int
qtype
,
qclass
;
struct
all_addr
addr
;
int
nameoffset
;
unsigned
short
flag
;
int
q
,
ans
,
anscount
=
0
,
addncount
=
0
;
int
dryrun
=
0
,
sec_reqd
=
0
,
have_pseudoheader
=
0
;
int
dryrun
=
0
;
struct
crec
*
crecp
;
int
nxdomain
=
0
,
auth
=
1
,
trunc
=
0
,
sec_data
=
1
;
struct
mx_srv_record
*
rec
;
...
...
@@ -1550,35 +1544,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if
(
header
->
hb4
&
HB4_CD
)
sec_data
=
0
;
/* RFC 6840 5.7 */
*
ad_reqd
=
header
->
hb4
&
HB4_AD
;
*
do_bit
=
0
;
/* If there is an additional data section then it will be overwritten by
partial replies, so we have to do a dry run to see if we can answer
the query. */
if
(
ntohs
(
header
->
arcount
)
!=
0
)
{
dryrun
=
1
;
/* If there's an additional section, there might be an EDNS(0) pseudoheader */
if
(
find_pseudoheader
(
header
,
qlen
,
NULL
,
&
pheader
,
NULL
))
{
unsigned
short
flags
;
have_pseudoheader
=
1
;
pheader
+=
4
;
/* udp size, ext_rcode */
GETSHORT
(
flags
,
pheader
);
if
((
sec_reqd
=
flags
&
0x8000
))
{
*
do_bit
=
1
;
/* do bit */
*
ad_reqd
=
1
;
}
}
}
dryrun
=
1
;
for
(
rec
=
daemon
->
mxnames
;
rec
;
rec
=
rec
->
next
)
rec
->
offset
=
0
;
...
...
@@ -1603,11 +1573,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
GETSHORT
(
qtype
,
p
);
GETSHORT
(
qclass
,
p
);
/* Don't filter RRSIGS from answers to ANY queries, even if do-bit
not set. */
if
(
qtype
==
T_ANY
)
*
do_bit
=
1
;
ans
=
0
;
/* have we answered this question */
if
(
qtype
==
T_TXT
||
qtype
==
T_ANY
)
...
...
@@ -1739,7 +1704,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
the zone is unsigned, which implies that we're doing
validation. */
if
((
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))
||
!
sec_reqd
||
!
do_bit
||
(
option_bool
(
OPT_DNSSEC_VALID
)
&&
!
(
crecp
->
flags
&
F_DNSSECOK
)))
{
do
...
...
@@ -1927,7 +1892,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
/* If the client asked for DNSSEC don't use cached data. */
if
((
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))
||
!
sec_reqd
||
!
(
crecp
->
flags
&
F_DNSSECOK
))
if
((
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))
||
!
do_bit
||
!
(
crecp
->
flags
&
F_DNSSECOK
))
do
{
/* don't answer wildcard queries with data not from /etc/hosts
...
...
@@ -1961,17 +1926,12 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if
(
crecp
->
flags
&
F_NEG
)
{
/* We don't cache NSEC records, so if a DNSSEC-validated negative answer
is cached and the client wants DNSSEC, forward rather than answering from the cache */
if
(
!
sec_reqd
||
!
(
crecp
->
flags
&
F_DNSSECOK
))
{
ans
=
1
;
auth
=
0
;
if
(
crecp
->
flags
&
F_NXDOMAIN
)
nxdomain
=
1
;
if
(
!
dryrun
)
log_query
(
crecp
->
flags
,
name
,
NULL
,
NULL
);
}
ans
=
1
;
auth
=
0
;
if
(
crecp
->
flags
&
F_NXDOMAIN
)
nxdomain
=
1
;
if
(
!
dryrun
)
log_query
(
crecp
->
flags
,
name
,
NULL
,
NULL
);
}
else
{
...
...
@@ -2209,10 +2169,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
len
=
ansp
-
(
unsigned
char
*
)
header
;
/* Advertise our packet size limit in our reply */
if
(
have_pseudoheader
)
len
=
add_pseudoheader
(
header
,
len
,
(
unsigned
char
*
)
limit
,
0
,
NULL
,
0
,
sec_reqd
);
len
=
add_pseudoheader
(
header
,
len
,
(
unsigned
char
*
)
limit
,
daemon
->
edns_pktsz
,
0
,
NULL
,
0
,
do_bit
);
if
(
*
ad_reqd
&&
sec_data
)
if
(
ad_reqd
&&
sec_data
)
header
->
hb4
|=
HB4_AD
;
else
header
->
hb4
&=
~
HB4_AD
;
...
...
src/rrfilter.c
View file @
fa14bec8
...
...
@@ -243,7 +243,7 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode)
for
(
p
=
rrs
[
0
],
i
=
1
;
i
<
rr_found
;
i
+=
2
)
{
unsigned
char
*
start
=
rrs
[
i
];
unsigned
char
*
end
=
(
i
!=
rr_found
-
1
)
?
rrs
[
i
+
1
]
:
((
unsigned
char
*
)
(
header
+
1
)
)
+
plen
;
unsigned
char
*
end
=
(
i
!=
rr_found
-
1
)
?
rrs
[
i
+
1
]
:
((
unsigned
char
*
)
header
)
+
plen
;
memmove
(
p
,
start
,
end
-
start
);
p
+=
end
-
start
;
...
...
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