mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
5
Commits
v2.92test3
...
v2.92test4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a458c2bfb0 | ||
|
|
9e67099ce7 | ||
|
|
cfa1313e1f | ||
|
|
e3a2c8dadf | ||
|
|
95b74a7acf |
No files matched your search
+2
-1
@@ -134,7 +134,8 @@ only, to stop dnsmasq daemonising in production, use
|
||||
Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1. If the argument "extra" is supplied, ie
|
||||
.B --log-queries=extra
|
||||
then the log has extra information at the start of each line.
|
||||
This consists of a serial number which ties together the log lines associated with an individual query, and the IP address of the requestor. If the argument "proto" is supplied, this shows everything that "extra" does and also the network protocol used to communicate the queries.
|
||||
This consists of a serial number which ties together the log lines associated with an individual query, and the IP address of the requestor. If the argument "proto" is supplied, this shows everything that "extra" does and also the network protocol used to communicate the queries. Logging of only queries to the authoritative server can be configured with
|
||||
.B --log-queries=auth
|
||||
.TP
|
||||
.B \-8, --log-facility=<facility>
|
||||
Set the facility to which dnsmasq will send syslog entries, this
|
||||
|
||||
+47
-34
@@ -103,9 +103,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
unsigned char *p, *ansp;
|
||||
int qtype, qclass, rc;
|
||||
int nameoffset, axfroffset = 0;
|
||||
int q, anscount = 0, authcount = 0;
|
||||
int anscount = 0, authcount = 0;
|
||||
struct crec *crecp;
|
||||
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0;
|
||||
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0, notimp = 0;
|
||||
struct auth_zone *zone = NULL;
|
||||
struct addrlist *subnet = NULL;
|
||||
char *cut;
|
||||
@@ -116,18 +116,20 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
union all_addr addr;
|
||||
struct cname *a, *candidate;
|
||||
unsigned int wclen;
|
||||
unsigned int log_flags = local_query ? 0 : F_NOERR;
|
||||
|
||||
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
||||
if (ntohs(header->qdcount) != 1)
|
||||
return 0;
|
||||
|
||||
/* determine end of question section (we put answers there) */
|
||||
if (!(ansp = skip_questions(header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
|
||||
/* now process each question, answers go in RRs after the question */
|
||||
p = (unsigned char *)(header+1);
|
||||
|
||||
for (q = ntohs(header->qdcount); q != 0; q--)
|
||||
if (OPCODE(header) != QUERY)
|
||||
notimp = 1;
|
||||
else
|
||||
{
|
||||
unsigned int flag = 0;
|
||||
int found = 0;
|
||||
@@ -147,7 +149,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
{
|
||||
auth = 0;
|
||||
out_of_zone = 1;
|
||||
continue;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((qtype == T_PTR || qtype == T_SOA || qtype == T_NS) &&
|
||||
@@ -162,7 +164,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
{
|
||||
out_of_zone = 1;
|
||||
auth = 0;
|
||||
continue;
|
||||
goto done;
|
||||
}
|
||||
else if (qtype == T_SOA)
|
||||
soa = 1, found = 1;
|
||||
@@ -210,7 +212,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (local_query || in_zone(zone, intr->name, NULL))
|
||||
{
|
||||
found = 1;
|
||||
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0);
|
||||
log_query(log_flags | flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
T_PTR, C_IN, "d", intr->name))
|
||||
@@ -234,7 +236,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
strcat(name, ".");
|
||||
strcat(name, zone->domain);
|
||||
}
|
||||
log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0);
|
||||
log_query(log_flags | flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0);
|
||||
found = 1;
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
@@ -243,7 +245,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
}
|
||||
else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL)))
|
||||
{
|
||||
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid), 0);
|
||||
log_query(log_flags | (crecp->flags & ~F_FORWARD), name, &addr, record_source(crecp->uid), 0);
|
||||
found = 1;
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
@@ -257,7 +259,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
|
||||
if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL)))
|
||||
{
|
||||
log_query(F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0);
|
||||
log_query(log_flags | F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0);
|
||||
found = 1;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
@@ -269,9 +271,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (found)
|
||||
nxdomain = 0;
|
||||
else
|
||||
log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0);
|
||||
log_query(log_flags | flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0);
|
||||
|
||||
continue;
|
||||
goto done;
|
||||
}
|
||||
|
||||
cname_restart:
|
||||
@@ -288,7 +290,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
{
|
||||
out_of_zone = 1;
|
||||
auth = 0;
|
||||
continue;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +302,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (rc == 2 && qtype == T_MX)
|
||||
{
|
||||
found = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_MX, C_IN, "sd", rec->weight, rec->target))
|
||||
anscount++;
|
||||
@@ -315,7 +317,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (rc == 2 && qtype == T_SRV)
|
||||
{
|
||||
found = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0);
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_SRV, C_IN, "sssd",
|
||||
rec->priority, rec->weight, rec->srvport, rec->target))
|
||||
@@ -349,7 +351,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (rc == 2 && txt->class == qtype)
|
||||
{
|
||||
found = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class);
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, txt->class, C_IN, "t", txt->len, txt->txt))
|
||||
anscount++;
|
||||
@@ -363,7 +365,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (rc == 2 && qtype == T_TXT)
|
||||
{
|
||||
found = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0);
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_TXT, C_IN, "t", txt->len, txt->txt))
|
||||
anscount++;
|
||||
@@ -377,7 +379,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (rc == 2 && qtype == T_NAPTR)
|
||||
{
|
||||
found = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0);
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_NAPTR, C_IN, "sszzzd",
|
||||
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
|
||||
@@ -407,7 +409,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
continue;
|
||||
|
||||
found = 1;
|
||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0);
|
||||
log_query(log_flags | F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||
qtype == T_A ? "4" : "6", &addrlist->addr))
|
||||
@@ -419,7 +421,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
{
|
||||
nxdomain = 0;
|
||||
|
||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0);
|
||||
log_query(log_flags | F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr))
|
||||
anscount++;
|
||||
@@ -432,7 +434,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (qtype == T_SOA)
|
||||
{
|
||||
auth = soa = 1; /* inhibits auth section */
|
||||
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0);
|
||||
log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0);
|
||||
}
|
||||
else if (qtype == T_AXFR)
|
||||
{
|
||||
@@ -468,13 +470,13 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
ns = 1; /* ensure we include NS records! */
|
||||
axfr = 1;
|
||||
axfroffset = nameoffset;
|
||||
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0);
|
||||
log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0);
|
||||
}
|
||||
else if (qtype == T_NS)
|
||||
{
|
||||
auth = 1;
|
||||
ns = 1; /* inhibits auth section */
|
||||
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 0);
|
||||
log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,7 +494,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
(local_query || filter_zone(zone, flag, &(crecp->addr))))
|
||||
{
|
||||
*cut = '.'; /* restore domain part */
|
||||
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
|
||||
log_query(log_flags | crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
|
||||
*cut = 0; /* remove domain part */
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||
@@ -513,7 +515,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
nxdomain = 0;
|
||||
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
|
||||
{
|
||||
log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr, record_source(crecp->uid), 0);
|
||||
log_query(log_flags | (crecp->flags & ~F_REVERSE), name, &crecp->addr, record_source(crecp->uid), 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||
qtype == T_A ? "4" : "6", &crecp->addr))
|
||||
@@ -560,7 +562,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
|
||||
if (candidate)
|
||||
{
|
||||
log_query(F_CONFIG | F_CNAME, name, NULL, NULL, 0);
|
||||
log_query(log_flags | F_CONFIG | F_CNAME, name, NULL, NULL, 0);
|
||||
strcpy(name, candidate->target);
|
||||
if (!strchr(name, '.'))
|
||||
{
|
||||
@@ -578,10 +580,12 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
else if (cache_find_non_terminal(name, now))
|
||||
nxdomain = 0;
|
||||
|
||||
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0);
|
||||
log_query(log_flags | flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* Add auth section */
|
||||
if (auth && zone)
|
||||
@@ -873,7 +877,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (!(ansp = skip_questions(header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
anscount = authcount = 0;
|
||||
log_query(F_AUTH, "reply", NULL, "truncated", 0);
|
||||
log_query(log_flags | F_AUTH, "reply", NULL, "truncated", 0);
|
||||
}
|
||||
|
||||
if ((auth || local_query) && nxdomain)
|
||||
@@ -885,14 +889,23 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
header->nscount = htons(authcount);
|
||||
header->arcount = htons(0);
|
||||
|
||||
if (!local_query && out_of_zone)
|
||||
if ((!local_query && out_of_zone) || notimp)
|
||||
{
|
||||
SET_RCODE(header, REFUSED);
|
||||
if (out_of_zone)
|
||||
{
|
||||
addr.log.rcode = REFUSED;
|
||||
addr.log.ede = EDE_NOT_AUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr.log.rcode = NOTIMP;
|
||||
addr.log.ede = EDE_UNSET;
|
||||
}
|
||||
|
||||
SET_RCODE(header, addr.log.rcode);
|
||||
header->ancount = htons(0);
|
||||
header->nscount = htons(0);
|
||||
addr.log.rcode = REFUSED;
|
||||
addr.log.ede = EDE_NOT_AUTH;
|
||||
log_query(F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0);
|
||||
log_query(log_flags | F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0);
|
||||
return resize_packet(header, ansp - (unsigned char *)header, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
+174
-143
@@ -799,14 +799,16 @@ void cache_end_insert(void)
|
||||
char *name = cache_get_name(new_chain);
|
||||
ssize_t m = strlen(name);
|
||||
unsigned int flags = new_chain->flags;
|
||||
unsigned char op = PIPE_OP_RR;
|
||||
#ifdef HAVE_DNSSEC
|
||||
u16 class = new_chain->uid;
|
||||
#endif
|
||||
|
||||
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)name, m, RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), RW_WRITE);
|
||||
|
||||
if (flags & F_RR)
|
||||
@@ -838,27 +840,29 @@ void cache_end_insert(void)
|
||||
/* signal end of cache insert in master process */
|
||||
if (daemon->pipe_to_parent != -1)
|
||||
{
|
||||
ssize_t m = -1;
|
||||
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), RW_WRITE);
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* Sneak out possibly updated crypto HWM values. */
|
||||
read_write(daemon->pipe_to_parent,
|
||||
(unsigned char *)&daemon->metrics[METRIC_CRYPTO_HWM],
|
||||
sizeof(daemon->metrics[METRIC_CRYPTO_HWM]), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent,
|
||||
(unsigned char *)&daemon->metrics[METRIC_SIG_FAIL_HWM],
|
||||
sizeof(daemon->metrics[METRIC_SIG_FAIL_HWM]), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent,
|
||||
(unsigned char *)&daemon->metrics[METRIC_WORK_HWM],
|
||||
sizeof(daemon->metrics[METRIC_WORK_HWM]), RW_WRITE);
|
||||
#endif
|
||||
unsigned char op = PIPE_OP_END;
|
||||
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
|
||||
}
|
||||
|
||||
new_chain = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
void cache_update_hwm(void)
|
||||
{
|
||||
/* Sneak out possibly updated crypto HWM values. */
|
||||
unsigned char op = PIPE_OP_STATS;
|
||||
|
||||
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent,
|
||||
(unsigned char *)&daemon->metrics[METRIC_CRYPTO_HWM],
|
||||
sizeof(daemon->metrics[METRIC_CRYPTO_HWM]), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent,
|
||||
(unsigned char *)&daemon->metrics[METRIC_SIG_FAIL_HWM],
|
||||
sizeof(daemon->metrics[METRIC_SIG_FAIL_HWM]), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent,
|
||||
(unsigned char *)&daemon->metrics[METRIC_WORK_HWM],
|
||||
sizeof(daemon->metrics[METRIC_WORK_HWM]), RW_WRITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* A marshalled cache entry arrives on fd, read, unmarshall and insert into cache of master process. */
|
||||
int cache_recv_insert(time_t now, int fd)
|
||||
@@ -869,139 +873,150 @@ int cache_recv_insert(time_t now, int fd)
|
||||
time_t ttd;
|
||||
unsigned int flags;
|
||||
struct crec *crecp = NULL;
|
||||
unsigned char op;
|
||||
|
||||
cache_start_insert();
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&m, sizeof(m), RW_READ))
|
||||
if (!read_write(fd, &op, sizeof(op), RW_READ))
|
||||
return 0;
|
||||
|
||||
if (m == -1)
|
||||
switch (op)
|
||||
{
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* Sneak in possibly updated crypto HWM. */
|
||||
unsigned int val;
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&val, sizeof(val), RW_READ))
|
||||
return 0;
|
||||
if (val > daemon->metrics[METRIC_CRYPTO_HWM])
|
||||
daemon->metrics[METRIC_CRYPTO_HWM] = val;
|
||||
if (!read_write(fd, (unsigned char *)&val, sizeof(val), RW_READ))
|
||||
return 0;
|
||||
if (val > daemon->metrics[METRIC_SIG_FAIL_HWM])
|
||||
daemon->metrics[METRIC_SIG_FAIL_HWM] = val;
|
||||
if (!read_write(fd, (unsigned char *)&val, sizeof(val), RW_READ))
|
||||
return 0;
|
||||
if (val > daemon->metrics[METRIC_WORK_HWM])
|
||||
daemon->metrics[METRIC_WORK_HWM] = val;
|
||||
#endif
|
||||
case PIPE_OP_END:
|
||||
cache_end_insert();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* UDP validation moved to TCP to avoid truncation.
|
||||
Restart UDP validation process with the returned result. */
|
||||
if (m == -2)
|
||||
{
|
||||
int status, uid, keycount, validatecount;
|
||||
int *keycountp, *validatecountp;
|
||||
size_t ret_len;
|
||||
case PIPE_OP_STATS:
|
||||
{
|
||||
/* Sneak in possibly updated crypto HWM. */
|
||||
unsigned int val;
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&val, sizeof(val), RW_READ))
|
||||
return 0;
|
||||
if (val > daemon->metrics[METRIC_CRYPTO_HWM])
|
||||
daemon->metrics[METRIC_CRYPTO_HWM] = val;
|
||||
if (!read_write(fd, (unsigned char *)&val, sizeof(val), RW_READ))
|
||||
return 0;
|
||||
if (val > daemon->metrics[METRIC_SIG_FAIL_HWM])
|
||||
daemon->metrics[METRIC_SIG_FAIL_HWM] = val;
|
||||
if (!read_write(fd, (unsigned char *)&val, sizeof(val), RW_READ))
|
||||
return 0;
|
||||
if (val > daemon->metrics[METRIC_WORK_HWM])
|
||||
daemon->metrics[METRIC_WORK_HWM] = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct frec *forward;
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&status, sizeof(status), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&ret_len, sizeof(ret_len), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)daemon->packet, ret_len, RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&forward, sizeof(forward), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&uid, sizeof(uid), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&keycount, sizeof(keycount), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&keycountp, sizeof(keycountp), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&validatecount, sizeof(validatecount), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&validatecountp, sizeof(validatecountp), RW_READ))
|
||||
return 0;
|
||||
|
||||
/* There's a tiny chance that the frec may have been freed
|
||||
and reused before the TCP process returns. Detect that with
|
||||
the uid field which is unique modulo 2^32 for each use. */
|
||||
if (uid == forward->uid)
|
||||
{
|
||||
/* repatriate the work counters from the child process. */
|
||||
*keycountp = keycount;
|
||||
*validatecountp = validatecount;
|
||||
|
||||
if (!forward->dependent)
|
||||
return_reply(now, forward, (struct dns_header *)daemon->packet, ret_len, status);
|
||||
else
|
||||
pop_and_retry_query(forward, status, now);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
case PIPE_OP_RESULT:
|
||||
{
|
||||
/* UDP validation moved to TCP to avoid truncation.
|
||||
Restart UDP validation process with the returned result. */
|
||||
int status, uid, keycount, validatecount;
|
||||
int *keycountp, *validatecountp;
|
||||
size_t ret_len;
|
||||
|
||||
struct frec *forward;
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&status, sizeof(status), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&ret_len, sizeof(ret_len), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)daemon->packet, ret_len, RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&forward, sizeof(forward), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&uid, sizeof(uid), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&keycount, sizeof(keycount), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&keycountp, sizeof(keycountp), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&validatecount, sizeof(validatecount), RW_READ))
|
||||
return 0;
|
||||
if (!read_write(fd, (unsigned char *)&validatecountp, sizeof(validatecountp), RW_READ))
|
||||
return 0;
|
||||
|
||||
/* There's a tiny chance that the frec may have been freed
|
||||
and reused before the TCP process returns. Detect that with
|
||||
the uid field which is unique modulo 2^32 for each use. */
|
||||
if (uid == forward->uid)
|
||||
{
|
||||
/* repatriate the work counters from the child process. */
|
||||
*keycountp = keycount;
|
||||
*validatecountp = validatecount;
|
||||
|
||||
if (!forward->dependent)
|
||||
return_reply(now, forward, (struct dns_header *)daemon->packet, ret_len, status);
|
||||
else
|
||||
pop_and_retry_query(forward, status, now);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!read_write(fd, (unsigned char *)daemon->namebuff, m, RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&ttd, sizeof(ttd), RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&flags, sizeof(flags), RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&addr, sizeof(addr), RW_READ))
|
||||
return 0;
|
||||
|
||||
daemon->namebuff[m] = 0;
|
||||
|
||||
ttl = difftime(ttd, now);
|
||||
|
||||
if (flags & F_CNAME)
|
||||
{
|
||||
struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
|
||||
/* This relies on the fact that the target of a CNAME immediately precedes
|
||||
it because of the order of extraction in extract_addresses, and
|
||||
the order reversal on the new_chain. */
|
||||
if (newc)
|
||||
|
||||
case PIPE_OP_RR:
|
||||
if (!read_write(fd, (unsigned char *)&m, sizeof(m), RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)daemon->namebuff, m, RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&ttd, sizeof(ttd), RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&flags, sizeof(flags), RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&addr, sizeof(addr), RW_READ))
|
||||
return 0;
|
||||
|
||||
daemon->namebuff[m] = 0;
|
||||
|
||||
ttl = difftime(ttd, now);
|
||||
|
||||
if (flags & F_CNAME)
|
||||
{
|
||||
newc->addr.cname.is_name_ptr = 0;
|
||||
|
||||
if (!crecp)
|
||||
newc->addr.cname.target.cache = NULL;
|
||||
else
|
||||
struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
|
||||
/* This relies on the fact that the target of a CNAME immediately precedes
|
||||
it because of the order of extraction in extract_addresses, and
|
||||
the order reversal on the new_chain. */
|
||||
if (newc)
|
||||
{
|
||||
next_uid(crecp);
|
||||
newc->addr.cname.target.cache = crecp;
|
||||
newc->addr.cname.uid = crecp->uid;
|
||||
newc->addr.cname.is_name_ptr = 0;
|
||||
|
||||
if (!crecp)
|
||||
newc->addr.cname.target.cache = NULL;
|
||||
else
|
||||
{
|
||||
next_uid(crecp);
|
||||
newc->addr.cname.target.cache = crecp;
|
||||
newc->addr.cname.uid = crecp->uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short class = C_IN;
|
||||
|
||||
if ((flags & F_RR) && !(flags & F_NEG) && (flags & F_KEYTAG)
|
||||
&& !(addr.rrblock.rrdata = blockdata_read(fd, addr.rrblock.datalen)))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
unsigned short class = C_IN;
|
||||
|
||||
if ((flags & F_RR) && !(flags & F_NEG) && (flags & F_KEYTAG)
|
||||
&& !(addr.rrblock.rrdata = blockdata_read(fd, addr.rrblock.datalen)))
|
||||
return 0;
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
if (!read_write(fd, (unsigned char *)&class, sizeof(class), RW_READ) ||
|
||||
!(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
|
||||
return 0;
|
||||
}
|
||||
else if (flags & F_DS)
|
||||
{
|
||||
if (!read_write(fd, (unsigned char *)&class, sizeof(class), RW_READ) ||
|
||||
(!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
|
||||
return 0;
|
||||
}
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
if (!read_write(fd, (unsigned char *)&class, sizeof(class), RW_READ) ||
|
||||
!(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
|
||||
return 0;
|
||||
}
|
||||
else if (flags & F_DS)
|
||||
{
|
||||
if (!read_write(fd, (unsigned char *)&class, sizeof(class), RW_READ) ||
|
||||
(!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
|
||||
crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
|
||||
}
|
||||
|
||||
/* loop reading RRs, since we don't want to go back to the poll() loop
|
||||
and start processing other queries which might pollute the insertion
|
||||
chain. The child will never block between the first OP_RR and the OP_END */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2180,12 +2195,17 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||
char *extra = "";
|
||||
char *gap = " ";
|
||||
char portstring[7]; /* space for #<portnum> */
|
||||
|
||||
char opcodestring[3]; /* maximum is 15 */
|
||||
|
||||
if (!option_bool(OPT_LOG))
|
||||
return;
|
||||
|
||||
/* F_NOERR is reused here to indicate logs arrising from auth queries */
|
||||
if (!(flags & F_NOERR) && option_bool(OPT_AUTH_LOG))
|
||||
return;
|
||||
|
||||
/* build query type string if requested */
|
||||
if (!(flags & (F_SERVER | F_IPSET)) && type > 0)
|
||||
if (!(flags & (F_SERVER | F_IPSET | F_QUERY)) && type > 0)
|
||||
arg = querystr(arg, type);
|
||||
|
||||
dest = arg;
|
||||
@@ -2218,6 +2238,8 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||
dest = "SERVFAIL";
|
||||
else if (rcode == REFUSED)
|
||||
dest = "REFUSED";
|
||||
else if (rcode == FORMERR)
|
||||
dest = "FORMERR";
|
||||
else if (rcode == NOTIMP)
|
||||
dest = "not implemented";
|
||||
else
|
||||
@@ -2276,6 +2298,8 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||
source = arg;
|
||||
else if (flags & F_UPSTREAM)
|
||||
source = "reply";
|
||||
else if (flags & F_AUTH)
|
||||
source = "auth";
|
||||
else if (flags & F_SECSTAT)
|
||||
{
|
||||
if (addr && addr->log.ede != EDE_UNSET && option_bool(OPT_EXTRALOG))
|
||||
@@ -2286,8 +2310,6 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||
source = "validation";
|
||||
dest = arg;
|
||||
}
|
||||
else if (flags & F_AUTH)
|
||||
source = "auth";
|
||||
else if (flags & F_DNSSEC)
|
||||
{
|
||||
source = arg;
|
||||
@@ -2298,11 +2320,6 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||
source = "forwarded";
|
||||
verb = "to";
|
||||
}
|
||||
else if (flags & F_QUERY)
|
||||
{
|
||||
source = arg;
|
||||
verb = "from";
|
||||
}
|
||||
else if (flags & F_IPSET)
|
||||
{
|
||||
source = type ? "ipset add" : "nftset add";
|
||||
@@ -2314,7 +2331,21 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||
source = "cached-stale";
|
||||
else
|
||||
source = "cached";
|
||||
|
||||
|
||||
if (flags & F_QUERY)
|
||||
{
|
||||
if (flags & F_CONFIG)
|
||||
{
|
||||
sprintf(opcodestring, "%u", type & 0xf);
|
||||
source = "non-query opcode";
|
||||
name = opcodestring;
|
||||
}
|
||||
else if (!(flags & F_AUTH))
|
||||
source = "query";
|
||||
|
||||
verb = "from";
|
||||
}
|
||||
|
||||
if (!name)
|
||||
gap = name = "";
|
||||
else if (!name[0])
|
||||
|
||||
+4
-4
@@ -768,10 +768,10 @@ static DBusMessage *dbus_get_server_metrics(DBusMessage* message)
|
||||
add_dict_entry(&dict_array, "address", daemon->namebuff);
|
||||
|
||||
add_dict_int(&dict_array, "port", port);
|
||||
add_dict_int(&dict_array, "queries", serv->queries);
|
||||
add_dict_int(&dict_array, "failed_queries", serv->failed_queries);
|
||||
add_dict_int(&dict_array, "nxdomain", serv->nxdomain_replies);
|
||||
add_dict_int(&dict_array, "retries", serv->retrys);
|
||||
add_dict_int(&dict_array, "queries", queries);
|
||||
add_dict_int(&dict_array, "failed_queries", failed_queries);
|
||||
add_dict_int(&dict_array, "nxdomain", nxdomain_replies);
|
||||
add_dict_int(&dict_array, "retries", retrys);
|
||||
add_dict_int(&dict_array, "latency", sigma_latency/count_latency);
|
||||
|
||||
dbus_message_iter_close_container(&server_array, &dict_array);
|
||||
|
||||
+9
-2
@@ -2124,6 +2124,10 @@ static void do_tcp_connection(struct listener *listener, time_t now, int slot)
|
||||
|
||||
if (!option_bool(OPT_DEBUG))
|
||||
{
|
||||
#ifdef HAVE_DNSSEC
|
||||
cache_update_hwm(); /* Sneak out possibly updated crypto HWM values. */
|
||||
#endif
|
||||
|
||||
close(daemon->pipe_to_parent);
|
||||
flush_log();
|
||||
_exit(0);
|
||||
@@ -2229,10 +2233,10 @@ int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header
|
||||
|
||||
if (!option_bool(OPT_DEBUG))
|
||||
{
|
||||
ssize_t m = -2;
|
||||
unsigned char op = PIPE_OP_RESULT;
|
||||
|
||||
/* tell our parent we're done, and what the result was then exit. */
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&status, sizeof(status), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)plen, sizeof(*plen), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)header, *plen, RW_WRITE);
|
||||
@@ -2242,6 +2246,9 @@ int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&keycount, sizeof(keycount), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)validatecount, sizeof(*validatecount), RW_WRITE);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&validatecount, sizeof(validatecount), RW_WRITE);
|
||||
|
||||
cache_update_hwm(); /* Sneak out possibly updated crypto HWM values. */
|
||||
|
||||
close(daemon->pipe_to_parent);
|
||||
|
||||
flush_log();
|
||||
|
||||
+9
-1
@@ -281,7 +281,8 @@ struct event_desc {
|
||||
#define OPT_LOG_PROTO 73
|
||||
#define OPT_NO_0x20 74
|
||||
#define OPT_DO_0x20 75
|
||||
#define OPT_LAST 76
|
||||
#define OPT_AUTH_LOG 76
|
||||
#define OPT_LAST 77
|
||||
|
||||
#define OPTION_BITS (sizeof(unsigned int)*8)
|
||||
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
|
||||
@@ -536,6 +537,10 @@ struct crec {
|
||||
#define SRC_HOSTS 2
|
||||
#define SRC_AH 3
|
||||
|
||||
#define PIPE_OP_RR 1 /* Resource record */
|
||||
#define PIPE_OP_END 2 /* Cache entry complete: commit */
|
||||
#define PIPE_OP_RESULT 3 /* validation result. */
|
||||
#define PIPE_OP_STATS 4 /* Update parent's stats */
|
||||
|
||||
/* struct sockaddr is not large enough to hold any address,
|
||||
and specifically not big enough to hold an IPv6 address.
|
||||
@@ -1353,6 +1358,9 @@ void cache_end_insert(void);
|
||||
void cache_start_insert(void);
|
||||
unsigned int cache_remove_uid(const unsigned int uid);
|
||||
int cache_recv_insert(time_t now, int fd);
|
||||
#ifdef HAVE_DNSSEC
|
||||
void cache_update_hwm(void);
|
||||
#endif
|
||||
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned int flags);
|
||||
void cache_reload(void);
|
||||
|
||||
+6
-6
@@ -1816,14 +1816,14 @@ void receive_query(struct listener *listen, time_t now)
|
||||
#endif
|
||||
|
||||
if (OPCODE(header) != QUERY)
|
||||
log_query_mysockaddr(F_QUERY | F_FORWARD, "opcode", &source_addr, "non-query", 0);
|
||||
log_query_mysockaddr((auth_dns ? F_NOERR : 0) | F_QUERY | F_FORWARD | F_CONFIG, NULL, &source_addr, NULL, OPCODE(header));
|
||||
else if (extract_request(header, (size_t)n, daemon->namebuff, &type, NULL))
|
||||
{
|
||||
#ifdef HAVE_AUTH
|
||||
struct auth_zone *zone;
|
||||
#endif
|
||||
log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
|
||||
&source_addr, auth_dns ? "auth" : "query", type);
|
||||
log_query_mysockaddr((auth_dns ? F_NOERR | F_AUTH : 0 ) | F_QUERY | F_FORWARD, daemon->namebuff,
|
||||
&source_addr, NULL, type);
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
/* Find queries for zones we're authoritative for, and answer them directly.
|
||||
@@ -2459,7 +2459,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||
|
||||
if (OPCODE(header) != QUERY)
|
||||
{
|
||||
log_query_mysockaddr(F_QUERY | F_FORWARD, "opcode", &peer_addr, "non-query", 0);
|
||||
log_query_mysockaddr((auth_dns ? F_NOERR : 0) | F_QUERY | F_FORWARD | F_CONFIG, NULL, &peer_addr, NULL, OPCODE(header));
|
||||
gotname = 0;
|
||||
flags = F_RCODE;
|
||||
}
|
||||
@@ -2488,8 +2488,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||
saved_question = blockdata_alloc((char *)header, (size_t)size);
|
||||
saved_size = size;
|
||||
|
||||
log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
|
||||
&peer_addr, auth_dns ? "auth" : "query", qtype);
|
||||
log_query_mysockaddr((auth_dns ? F_NOERR | F_AUTH : 0) | F_QUERY | F_FORWARD, daemon->namebuff,
|
||||
&peer_addr, NULL, qtype);
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
/* Find queries for zones we're authoritative for, and answer them directly.
|
||||
|
||||
@@ -3435,6 +3435,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
set_option_bool(OPT_EXTRALOG);
|
||||
set_option_bool(OPT_LOG_PROTO);
|
||||
}
|
||||
else if (strcmp(arg, "auth") == 0)
|
||||
set_option_bool(OPT_AUTH_LOG);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in new issue
Block a user