Commit aace5d0f authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] include ECS in query logging

4566.	[func]		Query logging now includes the ECS option if one
			was included in the query. [RT #44476]
parent 7769c929
4566. [func] Query logging now includes the ECS option if one
was included in the query. [RT #44476]
4565. [cleanup] The inline macro versions of isc_buffer_put*()
did not implement automatic buffer reallocation.
[RT #44216]
......
......@@ -1643,9 +1643,9 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
count++;
}
if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) &&
(client->ecs_addr.family == AF_INET ||
client->ecs_addr.family == AF_INET6 ||
client->ecs_addr.family == AF_UNSPEC))
(client->ecs.addr.family == AF_INET ||
client->ecs.addr.family == AF_INET6 ||
client->ecs.addr.family == AF_UNSPEC))
{
isc_buffer_t buf;
isc_uint8_t addr[16];
......@@ -1654,12 +1654,12 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
/* Add CLIENT-SUBNET option. */
plen = client->ecs_addrlen;
plen = client->ecs.source;
/* Round up prefix len to a multiple of 8 */
addrl = (plen + 7) / 8;
switch (client->ecs_addr.family) {
switch (client->ecs.addr.family) {
case AF_UNSPEC:
INSIST(plen == 0);
family = 0;
......@@ -1667,12 +1667,12 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
case AF_INET:
INSIST(plen <= 32);
family = 1;
memmove(addr, &client->ecs_addr.type, addrl);
memmove(addr, &client->ecs.addr.type, addrl);
break;
case AF_INET6:
INSIST(plen <= 128);
family = 2;
memmove(addr, &client->ecs_addr.type, addrl);
memmove(addr, &client->ecs.addr.type, addrl);
break;
default:
INSIST(0);
......@@ -1682,9 +1682,9 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
/* family */
isc_buffer_putuint16(&buf, family);
/* source prefix-length */
isc_buffer_putuint8(&buf, client->ecs_addrlen);
isc_buffer_putuint8(&buf, client->ecs.source);
/* scope prefix-length */
isc_buffer_putuint8(&buf, client->ecs_scope);
isc_buffer_putuint8(&buf, client->ecs.scope);
/* address */
if (addrl > 0) {
......@@ -2137,9 +2137,9 @@ process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
}
}
memmove(&client->ecs_addr, &caddr, sizeof(caddr));
client->ecs_addrlen = addrlen;
client->ecs_scope = 0;
memmove(&client->ecs.addr, &caddr, sizeof(caddr));
client->ecs.source = addrlen;
client->ecs.scope = 0;
client->attributes |= NS_CLIENTATTR_HAVEECS;
isc_buffer_forward(buf, (unsigned int)optlen);
......@@ -2551,8 +2551,8 @@ client_request(isc_task_t *task, isc_event_t *event) {
else
opt = dns_message_getopt(client->message);
client->ecs_addrlen = 0;
client->ecs_scope = 0;
client->ecs.source = 0;
client->ecs.scope = 0;
if (opt != NULL) {
/*
......@@ -2664,11 +2664,11 @@ client_request(isc_task_t *task, isc_event_t *event) {
}
if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
addr = &client->ecs_addr;
scope = &client->ecs_scope;
addr = &client->ecs.addr;
scope = &client->ecs.scope;
}
if (allowed(&netaddr, tsig, addr, client->ecs_addrlen,
if (allowed(&netaddr, tsig, addr, client->ecs.source,
scope, view->matchclients) &&
allowed(&client->destaddr, tsig, NULL,
0, NULL, view->matchdestinations) &&
......@@ -3077,8 +3077,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
client->recursionquota = NULL;
client->interface = NULL;
client->peeraddr_valid = ISC_FALSE;
client->ecs_addrlen = 0;
client->ecs_scope = 0;
dns_ecs_init(&client->ecs);
#ifdef ALLOW_FILTER_AAAA
client->filter_aaaa = dns_aaaa_ok;
#endif
......@@ -3711,8 +3710,8 @@ ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
}
if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
ecs_addr = &client->ecs_addr;
ecs_addrlen = client->ecs_addrlen;
ecs_addr = &client->ecs.addr;
ecs_addrlen = client->ecs.source;
}
result = dns_acl_match2(netaddr, client->signer,
......
......@@ -60,6 +60,7 @@
#include <isc/queue.h>
#include <dns/db.h>
#include <dns/ecs.h>
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
......@@ -135,9 +136,7 @@ struct ns_client {
isc_boolean_t peeraddr_valid;
isc_netaddr_t destaddr;
isc_netaddr_t ecs_addr; /*%< EDNS client subnet */
isc_uint8_t ecs_addrlen;
isc_uint8_t ecs_scope;
dns_ecs_t ecs; /*%< EDNS client subnet sent by client */
struct in6_pktinfo pktinfo;
isc_dscp_t dscp;
......
......@@ -100,6 +100,9 @@
/*% Client presented a COOKIE. */
#define WANTCOOKIE(c) (((c)->attributes & \
NS_CLIENTATTR_WANTCOOKIE) != 0)
/*% Client presented a CLIENT-SUBNET option. */
#define HAVEECS(c) (((c)->attributes & \
NS_CLIENTATTR_HAVEECS) != 0)
/*% No authority? */
#define NOAUTHORITY(c) (((c)->query.attributes & \
NS_QUERYATTR_NOAUTHORITY) != 0)
......@@ -8933,6 +8936,7 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
char typename[DNS_RDATATYPE_FORMATSIZE];
char classname[DNS_RDATACLASS_FORMATSIZE];
char onbuf[ISC_NETADDR_FORMATSIZE];
char ecsbuf[DNS_ECS_FORMATSIZE + sizeof(" [ECS ]") - 1] = { 0 };
char ednsbuf[sizeof("E(255)")] = { 0 };
dns_rdataset_t *rdataset;
int level = ISC_LOG_INFO;
......@@ -8951,15 +8955,22 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
snprintf(ednsbuf, sizeof(ednsbuf), "E(%d)",
client->ednsversion);
if (HAVEECS(client)) {
strlcpy(ecsbuf, " [ECS ", sizeof(ecsbuf));
dns_ecs_format(&client->ecs, ecsbuf + 6, sizeof(ecsbuf) - 6);
strlcat(ecsbuf, "]", sizeof(ecsbuf));
}
ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
level, "query: %s %s %s %s%s%s%s%s%s%s (%s)", namebuf,
classname, typename, WANTRECURSION(client) ? "+" : "-",
level, "query: %s %s %s %s%s%s%s%s%s%s (%s)%s",
namebuf, classname, typename,
WANTRECURSION(client) ? "+" : "-",
(client->signer != NULL) ? "S" : "", ednsbuf,
TCP(client) ? "T" : "",
((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
HAVECOOKIE(client) ? "V" : WANTCOOKIE(client) ? "K" : "",
onbuf);
onbuf, ecsbuf);
}
static inline void
......
......@@ -388,16 +388,25 @@ echo "I:testing rndc with querylog command ($n)"
ret=0
# first enable it with querylog on option
$RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf querylog on >/dev/null 2>&1 || ret=1
# query for builtin and check if query was logged
$DIG @10.53.0.4 -p 5300 -c ch -t txt foo12345.bind > /dev/null || ret 1
grep "query logging is now on" ns4/named.run > /dev/null || ret=1
grep "query: foo12345.bind CH TXT" ns4/named.run > /dev/null || ret=1
# query for builtin and check if query was logged (without +subnet)
$DIG @10.53.0.4 -p 5300 -c ch -t txt foo12345.bind > /dev/null || ret 1
grep "query: foo12345.bind CH TXT.*(.*)$" ns4/named.run > /dev/null || ret=1
# query for another builtin zone and check if query was logged (with +subnet=127.0.0.1)
$DIG +subnet=127.0.0.1 @10.53.0.4 -p 5300 -c ch -t txt foo12346.bind > /dev/null || ret 1
grep "query: foo12346.bind CH TXT.*\[ECS 127\.0\.0\.1\/32\/0]" ns4/named.run > /dev/null || ret=1
# query for another builtin zone and check if query was logged (with +subnet=127.0.0.1/24)
$DIG +subnet=127.0.0.1/24 @10.53.0.4 -p 5300 -c ch -t txt foo12347.bind > /dev/null || ret 1
grep "query: foo12347.bind CH TXT.*\[ECS 127\.0\.0\.0\/24\/0]" ns4/named.run > /dev/null || ret=1
# query for another builtin zone and check if query was logged (with +subnet=::1)
$DIG +subnet=::1 @10.53.0.4 -p 5300 -c ch -t txt foo12348.bind > /dev/null || ret 1
grep "query: foo12348.bind CH TXT.*\[ECS \:\:1\/128\/0]" ns4/named.run > /dev/null || ret=1
# toggle query logging and check again
$RNDC -s 10.53.0.4 -p 9956 -c ns4/key6.conf querylog > /dev/null 2>&1 || ret=1
# query for another builtin zone and check if query was logged
$DIG @10.53.0.4 -p 5300 -c ch -t txt foo9876.bind > /dev/null || ret 1
grep "query logging is now off" ns4/named.run > /dev/null || ret=1
grep "query: foo9876.bind CH TXT" ns4/named.run > /dev/null && ret=1
# query for another builtin zone and check if query was logged (without +subnet)
$DIG @10.53.0.4 -p 5300 -c ch -t txt foo9876.bind > /dev/null || ret 1
grep "query: foo9876.bind CH TXT.*(.*)$" ns4/named.run > /dev/null && ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......
......@@ -211,15 +211,19 @@
address and port number, and the query name,
class and type. Next, it reports whether the
Recursion Desired flag was set (+ if set, -
if not set), if the query was signed (S),
EDNS was in used along with the EDNS version
number (E(#)), if TCP was used (T), if DO
(DNSSEC Ok) was set (D), if CD (Checking
Disabled) was set (C), if a valid DNS Server
COOKIE was received (V), or if a DNS COOKIE
option without a valid Server COOKIE was
if not set), whether the query was signed (S),
whether EDNS was in use along with the EDNS version
number (E(#)), whether TCP was used (T), whether
DO (DNSSEC Ok) was set (D), whether CD (Checking
Disabled) was set (C), whether a valid DNS Server
COOKIE was received (V), and whether a DNS
COOKIE option without a valid Server COOKIE was
present (K). After this the destination
address the query was sent to is reported.
Finally, if any CLIENT-SUBNET option
was present in the client query, it is
included in square brackets in the format
[ECS <replaceable>address/source/scope</replaceable>].
</para>
<para>
......
......@@ -187,6 +187,13 @@
in <filename>named.conf</filename>. [RT #43154]
</para>
</listitem>
<listitem>
<para>
Query logging now includes the ECS option, if one was
present in the query, in the format
"[ECS <replaceable>address/source/scope</replaceable>]".
</para>
</listitem>
</itemizedlist>
</section>
......
......@@ -58,8 +58,8 @@ DNSTAPOBJS = dnstap.@O@ dnstap.pb-c.@O@
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \
cache.@O@ callbacks.@O@ catz.@O@ clientinfo.@O@ compress.@O@ \
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ forward.@O@ \
ipkeylist.@O@ iptable.@O@ journal.@O@ keydata.@O@ \
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ ecs.@O@ \
forward.@O@ ipkeylist.@O@ iptable.@O@ journal.@O@ keydata.@O@ \
keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ nta.@O@ \
......@@ -98,7 +98,7 @@ DNSTAPSRCS = dnstap.c dnstap.pb-c.c
DNSSRCS = acache.c acl.c adb.c badcache. byaddr.c \
cache.c callbacks.c clientinfo.c compress.c \
db.c dbiterator.c dbtable.c diff.c dispatch.c \
dlz.c dns64.c dnssec.c ds.c dyndb.c forward.c \
dlz.c dns64.c dnssec.c ds.c dyndb.c ecs.c forward.c \
ipkeylist.c iptable.c journal.c keydata.c keytable.c lib.c \
log.c lookup.c master.c masterdump.c message.c \
name.c ncache.c nsec.c nsec3.c nta.c \
......
/*
* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*! \file */
#include <config.h>
#include <string.h>
#include <isc/netaddr.h>
#include <isc/print.h>
#include <isc/util.h>
#include <dns/ecs.h>
#include <dns/types.h>
void
dns_ecs_init(dns_ecs_t *ecs) {
isc_netaddr_unspec(&ecs->addr);
ecs->source = 0;
/*
* XXXMUKS: Fix me when resolver ECS gets merged where scope
* gets initialized to 0xff.
*/
ecs->scope = 0;
}
void
dns_ecs_format(dns_ecs_t *ecs, char *buf, size_t size) {
size_t len;
REQUIRE(ecs != NULL);
REQUIRE(buf != NULL);
REQUIRE(size >= DNS_ECS_FORMATSIZE);
isc_netaddr_format(&ecs->addr, buf, size);
len = strlen(buf);
INSIST(size >= len);
buf += len;
size -= len;
snprintf(buf, size, "/%u/%u", ecs->source, ecs->scope);
}
......@@ -15,7 +15,7 @@ HEADERS = acache.h acl.h adb.h badcache.h bit.h byaddr.h \
client.h clientinfo.h compress.h \
db.h dbiterator.h dbtable.h diff.h dispatch.h \
dlz.h dlz_dlopen.h dns64.h dnssec.h ds.h dsdigest.h \
dnstap.h dyndb.h \
dnstap.h dyndb.h ecs.h \
edns.h ecdb.h events.h fixedname.h forward.h geoip.h \
ipkeylist.h iptable.h \
journal.h keydata.h keyflags.h keytable.h keyvalues.h \
......
/*
* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef DNS_ECS_H
#define DNS_ECS_H 1
#include <isc/netaddr.h>
#include <isc/types.h>
#include <dns/types.h>
struct dns_ecs {
isc_netaddr_t addr;
isc_uint8_t source;
isc_uint8_t scope;
};
#define DNS_ECS_FORMATSIZE (ISC_NETADDR_FORMATSIZE + 8) /* <address>/NNN/NNN */
ISC_LANG_BEGINDECLS
void
dns_ecs_init(dns_ecs_t *ecs);
/*%<
* Initialize a DNS ECS structure.
*
* Requires:
* \li 'ecs' is not NULL and points to a valid dns_ecs structure.
*/
void
dns_ecs_format(dns_ecs_t *ecs, char *buf, size_t size);
/*%<
* Format an ECS record as text. Result is guaranteed to be null-terminated.
*
* Requires:
* \li 'ecs' is not NULL.
* \li 'buf' is not NULL.
* \li 'size' is at least DNS_ECS_FORMATSIZE
*/
#endif /* DNS_ECS_H */
......@@ -79,6 +79,7 @@ typedef struct dns_dtenv dns_dtenv_t;
typedef struct dns_dtmsg dns_dtmsg_t;
typedef isc_uint16_t dns_dtmsgtype_t;
typedef struct dns_dumpctx dns_dumpctx_t;
typedef struct dns_ecs dns_ecs_t;
typedef struct dns_ednsopt dns_ednsopt_t;
typedef struct dns_fetch dns_fetch_t;
typedef struct dns_fixedname dns_fixedname_t;
......
......@@ -387,6 +387,8 @@ dns_dyndb_createctx
dns_dyndb_destroyctx
dns_ecdb_register
dns_ecdb_unregister
dns_ecs_init
dns_ecs_format
dns_fwdtable_add
dns_fwdtable_addfwd
dns_fwdtable_create
......
......@@ -202,6 +202,10 @@ SOURCE=..\include\dns\ecdb.h
# End Source File
# Begin Source File
SOURCE=..\include\dns\ecs.h
# End Source File
# Begin Source File
SOURCE=..\include\dns\edns.h
# End Source File
# Begin Source File
......@@ -592,6 +596,10 @@ SOURCE=..\ecdb.c
# End Source File
# Begin Source File
SOURCE=..\ecs.c
# End Source File
# Begin Source File
SOURCE=..\forward.c
# End Source File
@IF GEOIP
......
......@@ -146,6 +146,7 @@ CLEAN :
-@erase "$(INTDIR)\dst_result.obj"
-@erase "$(INTDIR)\dyndb.obj"
-@erase "$(INTDIR)\ecdb.obj"
-@erase "$(INTDIR)\ecs.obj"
-@erase "$(INTDIR)\forward.obj"
@IF GEOIP
-@erase "$(INTDIR)\geoip.obj"
......@@ -303,6 +304,7 @@ LINK32_OBJS= \
"$(INTDIR)\ds.obj" \
"$(INTDIR)\dyndb.obj" \
"$(INTDIR)\ecdb.obj" \
"$(INTDIR)\ecs.obj" \
"$(INTDIR)\forward.obj" \
@IF GEOIP
"$(INTDIR)\geoip.obj" \
......@@ -472,6 +474,8 @@ CLEAN :
-@erase "$(INTDIR)\dyndb.sbr"
-@erase "$(INTDIR)\ecdb.obj"
-@erase "$(INTDIR)\ecdb.sbr"
-@erase "$(INTDIR)\ecs.obj"
-@erase "$(INTDIR)\ecs.sbr"
-@erase "$(INTDIR)\forward.obj"
-@erase "$(INTDIR)\forward.sbr"
@IF GEOIP
......@@ -705,6 +709,7 @@ BSC32_SBRS= \
"$(INTDIR)\ds.sbr" \
"$(INTDIR)\dyndb.sbr" \
"$(INTDIR)\ecdb.sbr" \
"$(INTDIR)\ecs.sbr" \
"$(INTDIR)\forward.sbr" \
@IF GEOIP
"$(INTDIR)\geoip.sbr" \
......@@ -824,6 +829,7 @@ LINK32_OBJS= \
"$(INTDIR)\ds.obj" \
"$(INTDIR)\dyndb.obj" \
"$(INTDIR)\ecdb.obj" \
"$(INTDIR)\ecs.obj" \
"$(INTDIR)\forward.obj" \
@IF GEOIP
"$(INTDIR)\geoip.obj" \
......@@ -1345,6 +1351,24 @@ SOURCE=..\ecdb.c
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
SOURCE=..\ecs.c
!IF "$(CFG)" == "libdns - @PLATFORM@ Release"
"$(INTDIR)\ecs.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug"
"$(INTDIR)\ecs.obj" "$(INTDIR)\ecs.sbr" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
SOURCE=..\forward.c
......
......@@ -96,6 +96,9 @@
<ClCompile Include="..\ecdb.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ecs.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClCompile Include="..\forward.c">
<Filter>Library Source Files</Filter>
</ClCompile>
......@@ -431,6 +434,9 @@
<ClInclude Include="..\include\dns\ecdb.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\dns\ecs.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\dns\edns.h">
<Filter>Library Header Files</Filter>
</ClInclude>
......
......@@ -133,6 +133,7 @@
<ClCompile Include="..\dst_result.c" />
<ClCompile Include="..\dyndb.c" />
<ClCompile Include="..\ecdb.c" />
<ClCompile Include="..\ecs.c" />
<ClCompile Include="..\forward.c" />
@IF GEOIP
<ClCompile Include="..\geoip.c" />
......@@ -254,6 +255,7 @@
<ClInclude Include="..\include\dns\dsdigest.h" />
<ClInclude Include="..\include\dns\dyndb.h" />
<ClInclude Include="..\include\dns\ecdb.h" />
<ClInclude Include="..\include\dns\ecs.h" />
<ClInclude Include="..\include\dns\edns.h" />
<ClInclude Include="..\include\dns\enumclass.h" />
<ClInclude Include="..\include\dns\enumtype.h" />
......
......@@ -122,6 +122,12 @@ isc_netaddr_any6(isc_netaddr_t *netaddr);
* Return the IPv6 wildcard address.
*/
void
isc_netaddr_unspec(isc_netaddr_t *netaddr);
/*%<
* Initialize as AF_UNSPEC address.
*/
isc_boolean_t
isc_netaddr_ismulticast(const isc_netaddr_t *na);
/*%<
......
......@@ -363,6 +363,12 @@ isc_netaddr_any6(isc_netaddr_t *netaddr) {
netaddr->type.in6 = in6addr_any;
}
void
isc_netaddr_unspec(isc_netaddr_t *netaddr) {
memset(netaddr, 0, sizeof(*netaddr));
netaddr->family = AF_UNSPEC;
}
isc_boolean_t
isc_netaddr_ismulticast(const isc_netaddr_t *na) {
switch (na->family) {
......
......@@ -483,6 +483,7 @@ isc_netaddr_masktoprefixlen
isc_netaddr_prefixok
isc_netaddr_setzone
isc_netaddr_totext
isc_netaddr_unspec
isc_netscope_pton
isc_ntpaths_get
isc_ntpaths_init
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment