mirror of
https://github.com/systemd/systemd
synced 2025-10-01 09:44:46 +02:00
Compare commits
10 Commits
0e703bb48d
...
ccb4072e21
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ccb4072e21 | ||
![]() |
b52eac2010 | ||
![]() |
8d186a35cb | ||
![]() |
1d123e772d | ||
![]() |
13eb76ef06 | ||
![]() |
1e69eaddf8 | ||
![]() |
ff05157f82 | ||
![]() |
5c1790d1ce | ||
![]() |
43fc4baa26 | ||
![]() |
6f055e43b8 |
2
README
2
README
@ -44,7 +44,7 @@ REQUIREMENTS:
|
|||||||
CONFIG_SIGNALFD
|
CONFIG_SIGNALFD
|
||||||
CONFIG_TIMERFD
|
CONFIG_TIMERFD
|
||||||
CONFIG_EPOLL
|
CONFIG_EPOLL
|
||||||
CONFIG_NET
|
CONFIG_UNIX (it requires CONFIG_NET, but every other flag in it is not necessary)
|
||||||
CONFIG_SYSFS
|
CONFIG_SYSFS
|
||||||
CONFIG_PROC_FS
|
CONFIG_PROC_FS
|
||||||
CONFIG_FHANDLE (libudev, mount and bind mount handling)
|
CONFIG_FHANDLE (libudev, mount and bind mount handling)
|
||||||
|
@ -1344,16 +1344,15 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
set, then the gateway address provided by DHCPv4 or IPv6 RA is used.</para>
|
set, then the gateway address provided by DHCPv4 or IPv6 RA is used.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>GatewayOnLink=</varname></term>
|
<term><varname>GatewayOnLink=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Takes a boolean. If set to true, the kernel does not have
|
<para>Takes a boolean. If set to true, the kernel does not have to check if the gateway is
|
||||||
to check if the gateway is reachable directly by the current machine (i.e., the kernel does
|
reachable directly by the current machine (i.e., the kernel does not need to check if the
|
||||||
not need to check if the gateway is attached to the local network), so that we can insert the
|
gateway is attached to the local network), so that we can insert the route in the kernel
|
||||||
route in the kernel table without it being complained about. Defaults to <literal>no</literal>.
|
table without it being complained about. Defaults to <literal>no</literal>.</para>
|
||||||
</para>
|
</listitem>
|
||||||
</listitem>
|
</varlistentry>
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Destination=</varname></term>
|
<term><varname>Destination=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -155,9 +155,22 @@ static void print_source(uint64_t flags, usec_t rtt) {
|
|||||||
assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100));
|
assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100));
|
||||||
|
|
||||||
printf(" in %s.%s\n"
|
printf(" in %s.%s\n"
|
||||||
"%s-- Data is authenticated: %s%s\n",
|
"%s-- Data is authenticated: %s; Data was acquired via local or encrypted transport: %s%s\n",
|
||||||
rtt_str, ansi_normal(),
|
rtt_str, ansi_normal(),
|
||||||
ansi_grey(), yes_no(flags & SD_RESOLVED_AUTHENTICATED), ansi_normal());
|
ansi_grey(),
|
||||||
|
yes_no(flags & SD_RESOLVED_AUTHENTICATED),
|
||||||
|
yes_no(flags & SD_RESOLVED_CONFIDENTIAL),
|
||||||
|
ansi_normal());
|
||||||
|
|
||||||
|
if ((flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC)) != 0)
|
||||||
|
printf("%s-- Data from:%s%s%s%s%s%s\n",
|
||||||
|
ansi_grey(),
|
||||||
|
FLAGS_SET(flags, SD_RESOLVED_SYNTHETIC) ? " synthetic" : "",
|
||||||
|
FLAGS_SET(flags, SD_RESOLVED_FROM_CACHE) ? " cache" : "",
|
||||||
|
FLAGS_SET(flags, SD_RESOLVED_FROM_ZONE) ? " zone" : "",
|
||||||
|
FLAGS_SET(flags, SD_RESOLVED_FROM_TRUST_ANCHOR) ? " trust-anchor" : "",
|
||||||
|
FLAGS_SET(flags, SD_RESOLVED_FROM_NETWORK) ? " network" : "",
|
||||||
|
ansi_normal());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_ifindex_comment(int printed_so_far, int ifindex) {
|
static void print_ifindex_comment(int printed_so_far, int ifindex) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "bus-message-util.h"
|
#include "bus-message-util.h"
|
||||||
#include "bus-polkit.h"
|
#include "bus-polkit.h"
|
||||||
#include "dns-domain.h"
|
#include "dns-domain.h"
|
||||||
|
#include "format-util.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "missing_capability.h"
|
#include "missing_capability.h"
|
||||||
#include "resolved-bus.h"
|
#include "resolved-bus.h"
|
||||||
@ -252,7 +253,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
|
|||||||
r = sd_bus_message_append(
|
r = sd_bus_message_append(
|
||||||
reply, "st",
|
reply, "st",
|
||||||
normalized,
|
normalized,
|
||||||
SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
|
dns_query_reply_flags_make(q));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
@ -367,13 +368,39 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_message_append(reply, "st", canonical,
|
r = sd_bus_message_append(reply, "st", canonical,
|
||||||
SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true));
|
SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true, true) |
|
||||||
|
SD_RESOLVED_SYNTHETIC);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return sd_bus_send(sd_bus_message_get_bus(m), reply, NULL);
|
return sd_bus_send(sd_bus_message_get_bus(m), reply, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bus_client_log(sd_bus_message *m, const char *what) {
|
||||||
|
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||||
|
const char *comm = NULL;
|
||||||
|
uid_t uid = UID_INVALID;
|
||||||
|
pid_t pid = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
assert(what);
|
||||||
|
|
||||||
|
if (!DEBUG_LOGGING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
|
||||||
|
if (r < 0)
|
||||||
|
return (void) log_debug_errno(r, "Failed to query client credentials, ignoring: %m");
|
||||||
|
|
||||||
|
(void) sd_bus_creds_get_uid(creds, &uid);
|
||||||
|
(void) sd_bus_creds_get_pid(creds, &pid);
|
||||||
|
(void) sd_bus_creds_get_comm(creds, &comm);
|
||||||
|
|
||||||
|
log_debug("D-Bus %s request from client PID " PID_FMT " (%s) with UID " UID_FMT,
|
||||||
|
what, pid, strna(comm), uid);
|
||||||
|
}
|
||||||
|
|
||||||
static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
_cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
|
_cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
@ -420,6 +447,8 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
|
|||||||
if (r < 0 && r != -EALREADY)
|
if (r < 0 && r != -EALREADY)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
bus_client_log(message, "hostname resolution");
|
||||||
|
|
||||||
r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, NULL, ifindex, flags);
|
r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, NULL, ifindex, flags);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -510,7 +539,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
|
r = sd_bus_message_append(reply, "t", dns_query_reply_flags_make(q));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
@ -562,6 +591,8 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
bus_client_log(message, "address resolution");
|
||||||
|
|
||||||
r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
|
r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -672,7 +703,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
|
r = sd_bus_message_append(reply, "t", dns_query_reply_flags_make(q));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
@ -738,6 +769,8 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
bus_client_log(message, "resource record resolution");
|
||||||
|
|
||||||
/* Setting SD_RESOLVED_CLAMP_TTL: let's request that the TTL is fixed up for locally cached entries,
|
/* Setting SD_RESOLVED_CLAMP_TTL: let's request that the TTL is fixed up for locally cached entries,
|
||||||
* after all we return it in the wire format blob. */
|
* after all we return it in the wire format blob. */
|
||||||
r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH|SD_RESOLVED_CLAMP_TTL);
|
r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH|SD_RESOLVED_CLAMP_TTL);
|
||||||
@ -1048,7 +1081,7 @@ static void resolve_service_all_complete(DnsQuery *q) {
|
|||||||
reply,
|
reply,
|
||||||
"ssst",
|
"ssst",
|
||||||
name, type, domain,
|
name, type, domain,
|
||||||
SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
|
dns_query_reply_flags_make(q));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
@ -1270,6 +1303,8 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
bus_client_log(message, "service resolution");
|
||||||
|
|
||||||
r = dns_query_new(m, &q, question_utf8, question_idna, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
|
r = dns_query_new(m, &q, question_utf8, question_idna, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1662,6 +1697,8 @@ static int bus_method_reset_statistics(sd_bus_message *message, void *userdata,
|
|||||||
assert(message);
|
assert(message);
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
|
bus_client_log(message, "statistics reset");
|
||||||
|
|
||||||
LIST_FOREACH(scopes, s, m->dns_scopes)
|
LIST_FOREACH(scopes, s, m->dns_scopes)
|
||||||
s->cache.n_hit = s->cache.n_miss = 0;
|
s->cache.n_hit = s->cache.n_miss = 0;
|
||||||
|
|
||||||
@ -1774,6 +1811,8 @@ static int bus_method_flush_caches(sd_bus_message *message, void *userdata, sd_b
|
|||||||
assert(message);
|
assert(message);
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
|
bus_client_log(message, "cache flush");
|
||||||
|
|
||||||
manager_flush_caches(m, LOG_INFO);
|
manager_flush_caches(m, LOG_INFO);
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
@ -1785,6 +1824,8 @@ static int bus_method_reset_server_features(sd_bus_message *message, void *userd
|
|||||||
assert(message);
|
assert(message);
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
|
bus_client_log(message, "server feature reset");
|
||||||
|
|
||||||
manager_reset_server_features(m);
|
manager_reset_server_features(m);
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
return sd_bus_reply_method_return(message, NULL);
|
||||||
|
@ -13,3 +13,5 @@ int bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex
|
|||||||
int bus_property_get_resolve_support(sd_bus *bus, const char *path, const char *interface,
|
int bus_property_get_resolve_support(sd_bus *bus, const char *path, const char *interface,
|
||||||
const char *property, sd_bus_message *reply,
|
const char *property, sd_bus_message *reply,
|
||||||
void *userdata, sd_bus_error *error);
|
void *userdata, sd_bus_error *error);
|
||||||
|
|
||||||
|
void bus_client_log(sd_bus_message *m, const char *what);
|
||||||
|
@ -52,8 +52,28 @@
|
|||||||
/* Input: If reply is answered from cache, the TTLs will be adjusted by age of cache entry */
|
/* Input: If reply is answered from cache, the TTLs will be adjusted by age of cache entry */
|
||||||
#define SD_RESOLVED_CLAMP_TTL (UINT64_C(1) << 17)
|
#define SD_RESOLVED_CLAMP_TTL (UINT64_C(1) << 17)
|
||||||
|
|
||||||
|
/* Output: Result was only sent via encrypted channels, or never left this system */
|
||||||
|
#define SD_RESOLVED_CONFIDENTIAL (UINT64_C(1) << 18)
|
||||||
|
|
||||||
|
/* Output: Result was (at least partially) synthesized locally */
|
||||||
|
#define SD_RESOLVED_SYNTHETIC (UINT64_C(1) << 19)
|
||||||
|
|
||||||
|
/* Output: Result was (at least partially) answered from cache */
|
||||||
|
#define SD_RESOLVED_FROM_CACHE (UINT64_C(1) << 20)
|
||||||
|
|
||||||
|
/* Output: Result was (at least partially) answered from local zone */
|
||||||
|
#define SD_RESOLVED_FROM_ZONE (UINT64_C(1) << 21)
|
||||||
|
|
||||||
|
/* Output: Result was (at least partially) answered from trust anchor */
|
||||||
|
#define SD_RESOLVED_FROM_TRUST_ANCHOR (UINT64_C(1) << 22)
|
||||||
|
|
||||||
|
/* Output: Result was (at least partially) answered from network */
|
||||||
|
#define SD_RESOLVED_FROM_NETWORK (UINT64_C(1) << 23)
|
||||||
|
|
||||||
#define SD_RESOLVED_LLMNR (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6)
|
#define SD_RESOLVED_LLMNR (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6)
|
||||||
#define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6)
|
#define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6)
|
||||||
#define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS)
|
#define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS)
|
||||||
|
|
||||||
|
#define SD_RESOLVED_FROM_MASK (SD_RESOLVED_FROM_CACHE|SD_RESOLVED_FROM_ZONE|SD_RESOLVED_FROM_TRUST_ANCHOR|SD_RESOLVED_FROM_NETWORK)
|
||||||
|
|
||||||
#define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC)
|
#define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC)
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
* now) */
|
* now) */
|
||||||
#define CACHE_TTL_STRANGE_RCODE_USEC (10 * USEC_PER_SEC)
|
#define CACHE_TTL_STRANGE_RCODE_USEC (10 * USEC_PER_SEC)
|
||||||
|
|
||||||
|
#define CACHEABLE_QUERY_FLAGS (SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL)
|
||||||
|
|
||||||
typedef enum DnsCacheItemType DnsCacheItemType;
|
typedef enum DnsCacheItemType DnsCacheItemType;
|
||||||
typedef struct DnsCacheItem DnsCacheItem;
|
typedef struct DnsCacheItem DnsCacheItem;
|
||||||
|
|
||||||
@ -41,8 +43,8 @@ struct DnsCacheItem {
|
|||||||
int rcode;
|
int rcode;
|
||||||
|
|
||||||
usec_t until;
|
usec_t until;
|
||||||
bool authenticated:1;
|
|
||||||
bool shared_owner:1;
|
bool shared_owner:1;
|
||||||
|
uint64_t query_flags; /* SD_RESOLVED_AUTHENTICATED and/or SD_RESOLVED_CONFIDENTIAL */
|
||||||
DnssecResult dnssec_result;
|
DnssecResult dnssec_result;
|
||||||
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
@ -353,7 +355,7 @@ static void dns_cache_item_update_positive(
|
|||||||
DnsResourceRecord *rr,
|
DnsResourceRecord *rr,
|
||||||
DnsAnswer *answer,
|
DnsAnswer *answer,
|
||||||
DnsPacket *full_packet,
|
DnsPacket *full_packet,
|
||||||
bool authenticated,
|
uint64_t query_flags,
|
||||||
bool shared_owner,
|
bool shared_owner,
|
||||||
DnssecResult dnssec_result,
|
DnssecResult dnssec_result,
|
||||||
usec_t timestamp,
|
usec_t timestamp,
|
||||||
@ -390,7 +392,7 @@ static void dns_cache_item_update_positive(
|
|||||||
i->full_packet = full_packet;
|
i->full_packet = full_packet;
|
||||||
|
|
||||||
i->until = calculate_until(rr, UINT32_MAX, timestamp, false);
|
i->until = calculate_until(rr, UINT32_MAX, timestamp, false);
|
||||||
i->authenticated = authenticated;
|
i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS;
|
||||||
i->shared_owner = shared_owner;
|
i->shared_owner = shared_owner;
|
||||||
i->dnssec_result = dnssec_result;
|
i->dnssec_result = dnssec_result;
|
||||||
|
|
||||||
@ -407,7 +409,7 @@ static int dns_cache_put_positive(
|
|||||||
DnsResourceRecord *rr,
|
DnsResourceRecord *rr,
|
||||||
DnsAnswer *answer,
|
DnsAnswer *answer,
|
||||||
DnsPacket *full_packet,
|
DnsPacket *full_packet,
|
||||||
bool authenticated,
|
uint64_t query_flags,
|
||||||
bool shared_owner,
|
bool shared_owner,
|
||||||
DnssecResult dnssec_result,
|
DnssecResult dnssec_result,
|
||||||
usec_t timestamp,
|
usec_t timestamp,
|
||||||
@ -448,7 +450,7 @@ static int dns_cache_put_positive(
|
|||||||
rr,
|
rr,
|
||||||
answer,
|
answer,
|
||||||
full_packet,
|
full_packet,
|
||||||
authenticated,
|
query_flags,
|
||||||
shared_owner,
|
shared_owner,
|
||||||
dnssec_result,
|
dnssec_result,
|
||||||
timestamp,
|
timestamp,
|
||||||
@ -476,7 +478,7 @@ static int dns_cache_put_positive(
|
|||||||
.answer = dns_answer_ref(answer),
|
.answer = dns_answer_ref(answer),
|
||||||
.full_packet = dns_packet_ref(full_packet),
|
.full_packet = dns_packet_ref(full_packet),
|
||||||
.until = calculate_until(rr, (uint32_t) -1, timestamp, false),
|
.until = calculate_until(rr, (uint32_t) -1, timestamp, false),
|
||||||
.authenticated = authenticated,
|
.query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
|
||||||
.shared_owner = shared_owner,
|
.shared_owner = shared_owner,
|
||||||
.dnssec_result = dnssec_result,
|
.dnssec_result = dnssec_result,
|
||||||
.ifindex = ifindex,
|
.ifindex = ifindex,
|
||||||
@ -495,8 +497,9 @@ static int dns_cache_put_positive(
|
|||||||
|
|
||||||
(void) in_addr_to_string(i->owner_family, &i->owner_address, &t);
|
(void) in_addr_to_string(i->owner_family, &i->owner_address, &t);
|
||||||
|
|
||||||
log_debug("Added positive %s%s cache entry for %s "USEC_FMT"s on %s/%s/%s",
|
log_debug("Added positive %s %s%s cache entry for %s "USEC_FMT"s on %s/%s/%s",
|
||||||
i->authenticated ? "authenticated" : "unauthenticated",
|
FLAGS_SET(i->query_flags, SD_RESOLVED_AUTHENTICATED) ? "authenticated" : "unauthenticated",
|
||||||
|
FLAGS_SET(i->query_flags, SD_RESOLVED_CONFIDENTIAL) ? "confidential" : "non-confidential",
|
||||||
i->shared_owner ? " shared" : "",
|
i->shared_owner ? " shared" : "",
|
||||||
dns_resource_key_to_string(i->key, key_str, sizeof key_str),
|
dns_resource_key_to_string(i->key, key_str, sizeof key_str),
|
||||||
(i->until - timestamp) / USEC_PER_SEC,
|
(i->until - timestamp) / USEC_PER_SEC,
|
||||||
@ -515,7 +518,7 @@ static int dns_cache_put_negative(
|
|||||||
int rcode,
|
int rcode,
|
||||||
DnsAnswer *answer,
|
DnsAnswer *answer,
|
||||||
DnsPacket *full_packet,
|
DnsPacket *full_packet,
|
||||||
bool authenticated,
|
uint64_t query_flags,
|
||||||
DnssecResult dnssec_result,
|
DnssecResult dnssec_result,
|
||||||
uint32_t nsec_ttl,
|
uint32_t nsec_ttl,
|
||||||
usec_t timestamp,
|
usec_t timestamp,
|
||||||
@ -566,7 +569,7 @@ static int dns_cache_put_negative(
|
|||||||
.type =
|
.type =
|
||||||
rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA :
|
rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA :
|
||||||
rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE,
|
rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE,
|
||||||
.authenticated = authenticated,
|
.query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
|
||||||
.dnssec_result = dnssec_result,
|
.dnssec_result = dnssec_result,
|
||||||
.owner_family = owner_family,
|
.owner_family = owner_family,
|
||||||
.owner_address = *owner_address,
|
.owner_address = *owner_address,
|
||||||
@ -669,7 +672,7 @@ int dns_cache_put(
|
|||||||
int rcode,
|
int rcode,
|
||||||
DnsAnswer *answer,
|
DnsAnswer *answer,
|
||||||
DnsPacket *full_packet,
|
DnsPacket *full_packet,
|
||||||
bool authenticated,
|
uint64_t query_flags,
|
||||||
DnssecResult dnssec_result,
|
DnssecResult dnssec_result,
|
||||||
uint32_t nsec_ttl,
|
uint32_t nsec_ttl,
|
||||||
int owner_family,
|
int owner_family,
|
||||||
@ -761,7 +764,8 @@ int dns_cache_put(
|
|||||||
item->rr,
|
item->rr,
|
||||||
primary ? answer : NULL,
|
primary ? answer : NULL,
|
||||||
primary ? full_packet : NULL,
|
primary ? full_packet : NULL,
|
||||||
item->flags & DNS_ANSWER_AUTHENTICATED,
|
((item->flags & DNS_ANSWER_AUTHENTICATED) ? SD_RESOLVED_AUTHENTICATED : 0) |
|
||||||
|
(query_flags & SD_RESOLVED_CONFIDENTIAL),
|
||||||
item->flags & DNS_ANSWER_SHARED_OWNER,
|
item->flags & DNS_ANSWER_SHARED_OWNER,
|
||||||
dnssec_result,
|
dnssec_result,
|
||||||
timestamp,
|
timestamp,
|
||||||
@ -802,7 +806,8 @@ int dns_cache_put(
|
|||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
/* Refuse using the SOA data if it is unsigned, but the key is
|
/* Refuse using the SOA data if it is unsigned, but the key is
|
||||||
* signed */
|
* signed */
|
||||||
if (authenticated && (flags & DNS_ANSWER_AUTHENTICATED) == 0)
|
if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) &&
|
||||||
|
(flags & DNS_ANSWER_AUTHENTICATED) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,7 +824,7 @@ int dns_cache_put(
|
|||||||
rcode,
|
rcode,
|
||||||
answer,
|
answer,
|
||||||
full_packet,
|
full_packet,
|
||||||
authenticated,
|
query_flags,
|
||||||
dnssec_result,
|
dnssec_result,
|
||||||
nsec_ttl,
|
nsec_ttl,
|
||||||
timestamp,
|
timestamp,
|
||||||
@ -951,7 +956,7 @@ int dns_cache_lookup(
|
|||||||
int *ret_rcode,
|
int *ret_rcode,
|
||||||
DnsAnswer **ret_answer,
|
DnsAnswer **ret_answer,
|
||||||
DnsPacket **ret_full_packet,
|
DnsPacket **ret_full_packet,
|
||||||
bool *ret_authenticated,
|
uint64_t *ret_query_flags,
|
||||||
DnssecResult *ret_dnssec_result) {
|
DnssecResult *ret_dnssec_result) {
|
||||||
|
|
||||||
_cleanup_(dns_packet_unrefp) DnsPacket *full_packet = NULL;
|
_cleanup_(dns_packet_unrefp) DnsPacket *full_packet = NULL;
|
||||||
@ -961,7 +966,7 @@ int dns_cache_lookup(
|
|||||||
int r;
|
int r;
|
||||||
bool nxdomain = false;
|
bool nxdomain = false;
|
||||||
DnsCacheItem *j, *first, *nsec = NULL;
|
DnsCacheItem *j, *first, *nsec = NULL;
|
||||||
bool have_authenticated = false, have_non_authenticated = false;
|
bool have_authenticated = false, have_non_authenticated = false, have_confidential = false, have_non_confidential = false;
|
||||||
usec_t current;
|
usec_t current;
|
||||||
int found_rcode = -1;
|
int found_rcode = -1;
|
||||||
DnssecResult dnssec_result = -1;
|
DnssecResult dnssec_result = -1;
|
||||||
@ -1013,11 +1018,16 @@ int dns_cache_lookup(
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j->authenticated)
|
if (FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
have_authenticated = true;
|
have_authenticated = true;
|
||||||
else
|
else
|
||||||
have_non_authenticated = true;
|
have_non_authenticated = true;
|
||||||
|
|
||||||
|
if (FLAGS_SET(j->query_flags, SD_RESOLVED_CONFIDENTIAL))
|
||||||
|
have_confidential = true;
|
||||||
|
else
|
||||||
|
have_non_confidential = true;
|
||||||
|
|
||||||
if (j->dnssec_result < 0) {
|
if (j->dnssec_result < 0) {
|
||||||
have_dnssec_result = false; /* an entry without dnssec result? then invalidate things for good */
|
have_dnssec_result = false; /* an entry without dnssec result? then invalidate things for good */
|
||||||
dnssec_result = _DNSSEC_RESULT_INVALID;
|
dnssec_result = _DNSSEC_RESULT_INVALID;
|
||||||
@ -1049,7 +1059,14 @@ int dns_cache_lookup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (j->rr) {
|
} else if (j->rr) {
|
||||||
r = answer_add_clamp_ttl(&answer, j->rr, j->ifindex, j->authenticated ? DNS_ANSWER_AUTHENTICATED : 0, NULL, query_flags, j->until, current);
|
r = answer_add_clamp_ttl(&answer,
|
||||||
|
j->rr,
|
||||||
|
j->ifindex,
|
||||||
|
FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
|
||||||
|
NULL,
|
||||||
|
query_flags,
|
||||||
|
j->until,
|
||||||
|
current);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -1072,8 +1089,8 @@ int dns_cache_lookup(
|
|||||||
*ret_answer = TAKE_PTR(answer);
|
*ret_answer = TAKE_PTR(answer);
|
||||||
if (ret_full_packet)
|
if (ret_full_packet)
|
||||||
*ret_full_packet = TAKE_PTR(full_packet);
|
*ret_full_packet = TAKE_PTR(full_packet);
|
||||||
if (ret_authenticated)
|
if (ret_query_flags)
|
||||||
*ret_authenticated = false;
|
*ret_query_flags = 0;
|
||||||
if (ret_dnssec_result)
|
if (ret_dnssec_result)
|
||||||
*ret_dnssec_result = dnssec_result;
|
*ret_dnssec_result = dnssec_result;
|
||||||
|
|
||||||
@ -1097,8 +1114,8 @@ int dns_cache_lookup(
|
|||||||
*ret_answer = TAKE_PTR(answer);
|
*ret_answer = TAKE_PTR(answer);
|
||||||
if (ret_full_packet)
|
if (ret_full_packet)
|
||||||
*ret_full_packet = TAKE_PTR(full_packet);
|
*ret_full_packet = TAKE_PTR(full_packet);
|
||||||
if (ret_authenticated)
|
if (ret_query_flags)
|
||||||
*ret_authenticated = nsec->authenticated;
|
*ret_query_flags = nsec->query_flags;
|
||||||
if (ret_dnssec_result)
|
if (ret_dnssec_result)
|
||||||
*ret_dnssec_result = nsec->dnssec_result;
|
*ret_dnssec_result = nsec->dnssec_result;
|
||||||
|
|
||||||
@ -1127,8 +1144,10 @@ int dns_cache_lookup(
|
|||||||
*ret_answer = TAKE_PTR(answer);
|
*ret_answer = TAKE_PTR(answer);
|
||||||
if (ret_full_packet)
|
if (ret_full_packet)
|
||||||
*ret_full_packet = TAKE_PTR(full_packet);
|
*ret_full_packet = TAKE_PTR(full_packet);
|
||||||
if (ret_authenticated)
|
if (ret_query_flags)
|
||||||
*ret_authenticated = have_authenticated && !have_non_authenticated;
|
*ret_query_flags =
|
||||||
|
((have_authenticated && !have_non_authenticated) ? SD_RESOLVED_AUTHENTICATED : 0) |
|
||||||
|
((have_confidential && !have_non_confidential) ? SD_RESOLVED_CONFIDENTIAL : 0);
|
||||||
if (ret_dnssec_result)
|
if (ret_dnssec_result)
|
||||||
*ret_dnssec_result = dnssec_result;
|
*ret_dnssec_result = dnssec_result;
|
||||||
|
|
||||||
@ -1143,8 +1162,10 @@ int dns_cache_lookup(
|
|||||||
*ret_answer = TAKE_PTR(answer);
|
*ret_answer = TAKE_PTR(answer);
|
||||||
if (ret_full_packet)
|
if (ret_full_packet)
|
||||||
*ret_full_packet = TAKE_PTR(full_packet);
|
*ret_full_packet = TAKE_PTR(full_packet);
|
||||||
if (ret_authenticated)
|
if (ret_query_flags)
|
||||||
*ret_authenticated = have_authenticated && !have_non_authenticated;
|
*ret_query_flags =
|
||||||
|
((have_authenticated && !have_non_authenticated) ? SD_RESOLVED_AUTHENTICATED : 0) |
|
||||||
|
((have_confidential && !have_non_confidential) ? SD_RESOLVED_CONFIDENTIAL : 0);
|
||||||
if (ret_dnssec_result)
|
if (ret_dnssec_result)
|
||||||
*ret_dnssec_result = dnssec_result;
|
*ret_dnssec_result = dnssec_result;
|
||||||
|
|
||||||
@ -1157,8 +1178,8 @@ miss:
|
|||||||
*ret_answer = NULL;
|
*ret_answer = NULL;
|
||||||
if (ret_full_packet)
|
if (ret_full_packet)
|
||||||
*ret_full_packet = NULL;
|
*ret_full_packet = NULL;
|
||||||
if (ret_authenticated)
|
if (ret_query_flags)
|
||||||
*ret_authenticated = false;
|
*ret_query_flags = 0;
|
||||||
if (ret_dnssec_result)
|
if (ret_dnssec_result)
|
||||||
*ret_dnssec_result = _DNSSEC_RESULT_INVALID;
|
*ret_dnssec_result = _DNSSEC_RESULT_INVALID;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ int dns_cache_put(
|
|||||||
int rcode,
|
int rcode,
|
||||||
DnsAnswer *answer,
|
DnsAnswer *answer,
|
||||||
DnsPacket *full_packet,
|
DnsPacket *full_packet,
|
||||||
bool authenticated,
|
uint64_t query_flags,
|
||||||
DnssecResult dnssec_result,
|
DnssecResult dnssec_result,
|
||||||
uint32_t nsec_ttl,
|
uint32_t nsec_ttl,
|
||||||
int owner_family,
|
int owner_family,
|
||||||
@ -43,7 +43,7 @@ int dns_cache_lookup(
|
|||||||
int *ret_rcode,
|
int *ret_rcode,
|
||||||
DnsAnswer **ret_answer,
|
DnsAnswer **ret_answer,
|
||||||
DnsPacket **ret_full_packet,
|
DnsPacket **ret_full_packet,
|
||||||
bool *ret_authenticated,
|
uint64_t *ret_query_flags,
|
||||||
DnssecResult *ret_dnssec_result);
|
DnssecResult *ret_dnssec_result);
|
||||||
|
|
||||||
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
|
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
|
||||||
|
@ -269,12 +269,17 @@ DnsProtocol dns_protocol_from_string(const char *s) _pure_;
|
|||||||
|
|
||||||
extern const struct hash_ops dns_packet_hash_ops;
|
extern const struct hash_ops dns_packet_hash_ops;
|
||||||
|
|
||||||
static inline uint64_t SD_RESOLVED_FLAGS_MAKE(DnsProtocol protocol, int family, bool authenticated) {
|
static inline uint64_t SD_RESOLVED_FLAGS_MAKE(
|
||||||
|
DnsProtocol protocol,
|
||||||
|
int family,
|
||||||
|
bool authenticated,
|
||||||
|
bool confidential) {
|
||||||
uint64_t f;
|
uint64_t f;
|
||||||
|
|
||||||
/* Converts a protocol + family into a flags field as used in queries and responses */
|
/* Converts a protocol + family into a flags field as used in queries and responses */
|
||||||
|
|
||||||
f = authenticated ? SD_RESOLVED_AUTHENTICATED : 0;
|
f = (authenticated ? SD_RESOLVED_AUTHENTICATED : 0) |
|
||||||
|
(confidential ? SD_RESOLVED_CONFIDENTIAL : 0);
|
||||||
|
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case DNS_PROTOCOL_DNS:
|
case DNS_PROTOCOL_DNS:
|
||||||
|
@ -346,7 +346,7 @@ static void dns_query_reset_answer(DnsQuery *q) {
|
|||||||
q->answer_rcode = 0;
|
q->answer_rcode = 0;
|
||||||
q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
||||||
q->answer_errno = 0;
|
q->answer_errno = 0;
|
||||||
q->answer_authenticated = false;
|
q->answer_query_flags = 0;
|
||||||
q->answer_protocol = _DNS_PROTOCOL_INVALID;
|
q->answer_protocol = _DNS_PROTOCOL_INVALID;
|
||||||
q->answer_family = AF_UNSPEC;
|
q->answer_family = AF_UNSPEC;
|
||||||
q->answer_search_domain = dns_search_domain_unref(q->answer_search_domain);
|
q->answer_search_domain = dns_search_domain_unref(q->answer_search_domain);
|
||||||
@ -630,7 +630,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
|
|||||||
q->answer_rcode = DNS_RCODE_NXDOMAIN;
|
q->answer_rcode = DNS_RCODE_NXDOMAIN;
|
||||||
q->answer_protocol = dns_synthesize_protocol(q->flags);
|
q->answer_protocol = dns_synthesize_protocol(q->flags);
|
||||||
q->answer_family = dns_synthesize_family(q->flags);
|
q->answer_family = dns_synthesize_family(q->flags);
|
||||||
q->answer_authenticated = true;
|
q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC;
|
||||||
*state = DNS_TRANSACTION_RCODE_FAILURE;
|
*state = DNS_TRANSACTION_RCODE_FAILURE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -644,7 +644,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
|
|||||||
q->answer_rcode = DNS_RCODE_SUCCESS;
|
q->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
q->answer_protocol = dns_synthesize_protocol(q->flags);
|
q->answer_protocol = dns_synthesize_protocol(q->flags);
|
||||||
q->answer_family = dns_synthesize_family(q->flags);
|
q->answer_family = dns_synthesize_family(q->flags);
|
||||||
q->answer_authenticated = true;
|
q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC;
|
||||||
|
|
||||||
*state = DNS_TRANSACTION_SUCCESS;
|
*state = DNS_TRANSACTION_SUCCESS;
|
||||||
|
|
||||||
@ -676,7 +676,7 @@ static int dns_query_try_etc_hosts(DnsQuery *q) {
|
|||||||
q->answer_rcode = DNS_RCODE_SUCCESS;
|
q->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
q->answer_protocol = dns_synthesize_protocol(q->flags);
|
q->answer_protocol = dns_synthesize_protocol(q->flags);
|
||||||
q->answer_family = dns_synthesize_family(q->flags);
|
q->answer_family = dns_synthesize_family(q->flags);
|
||||||
q->answer_authenticated = true;
|
q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -795,7 +795,7 @@ fail:
|
|||||||
|
|
||||||
static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
||||||
DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
|
DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
|
||||||
bool has_authenticated = false, has_non_authenticated = false;
|
bool has_authenticated = false, has_non_authenticated = false, has_confidential = false, has_non_confidential = false;
|
||||||
DnssecResult dnssec_result_authenticated = _DNSSEC_RESULT_INVALID, dnssec_result_non_authenticated = _DNSSEC_RESULT_INVALID;
|
DnssecResult dnssec_result_authenticated = _DNSSEC_RESULT_INVALID, dnssec_result_non_authenticated = _DNSSEC_RESULT_INVALID;
|
||||||
DnsTransaction *t;
|
DnsTransaction *t;
|
||||||
int r;
|
int r;
|
||||||
@ -817,7 +817,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
|||||||
q->answer = dns_answer_unref(q->answer);
|
q->answer = dns_answer_unref(q->answer);
|
||||||
q->answer_rcode = 0;
|
q->answer_rcode = 0;
|
||||||
q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
q->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
||||||
q->answer_authenticated = false;
|
q->answer_query_flags = 0;
|
||||||
q->answer_errno = c->error_code;
|
q->answer_errno = c->error_code;
|
||||||
q->answer_full_packet = dns_packet_unref(q->answer_full_packet);
|
q->answer_full_packet = dns_packet_unref(q->answer_full_packet);
|
||||||
}
|
}
|
||||||
@ -833,10 +833,14 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
|||||||
r = dns_answer_extend(&q->answer, t->answer);
|
r = dns_answer_extend(&q->answer, t->answer);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
q->answer_query_flags |= dns_transaction_source_to_query_flags(t->answer_source);
|
||||||
} else {
|
} else {
|
||||||
/* Override non-successful previous answers */
|
/* Override non-successful previous answers */
|
||||||
dns_answer_unref(q->answer);
|
dns_answer_unref(q->answer);
|
||||||
q->answer = dns_answer_ref(t->answer);
|
q->answer = dns_answer_ref(t->answer);
|
||||||
|
|
||||||
|
q->answer_query_flags = dns_transaction_source_to_query_flags(t->answer_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
q->answer_rcode = t->answer_rcode;
|
q->answer_rcode = t->answer_rcode;
|
||||||
@ -845,7 +849,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
|||||||
dns_packet_unref(q->answer_full_packet);
|
dns_packet_unref(q->answer_full_packet);
|
||||||
q->answer_full_packet = dns_packet_ref(t->received);
|
q->answer_full_packet = dns_packet_ref(t->received);
|
||||||
|
|
||||||
if (t->answer_authenticated) {
|
if (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) {
|
||||||
has_authenticated = true;
|
has_authenticated = true;
|
||||||
dnssec_result_authenticated = t->answer_dnssec_result;
|
dnssec_result_authenticated = t->answer_dnssec_result;
|
||||||
} else {
|
} else {
|
||||||
@ -853,6 +857,11 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
|||||||
dnssec_result_non_authenticated = t->answer_dnssec_result;
|
dnssec_result_non_authenticated = t->answer_dnssec_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL))
|
||||||
|
has_confidential = true;
|
||||||
|
else
|
||||||
|
has_non_confidential = true;
|
||||||
|
|
||||||
state = DNS_TRANSACTION_SUCCESS;
|
state = DNS_TRANSACTION_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -870,14 +879,15 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If there's already an authenticated negative reply stored, then prefer that over any unauthenticated one */
|
/* If there's already an authenticated negative reply stored, then prefer that over any unauthenticated one */
|
||||||
if (q->answer_authenticated && !t->answer_authenticated)
|
if (FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED) &&
|
||||||
|
!FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dns_answer_unref(q->answer);
|
dns_answer_unref(q->answer);
|
||||||
q->answer = dns_answer_ref(t->answer);
|
q->answer = dns_answer_ref(t->answer);
|
||||||
q->answer_rcode = t->answer_rcode;
|
q->answer_rcode = t->answer_rcode;
|
||||||
q->answer_dnssec_result = t->answer_dnssec_result;
|
q->answer_dnssec_result = t->answer_dnssec_result;
|
||||||
q->answer_authenticated = t->answer_authenticated;
|
q->answer_query_flags = t->answer_query_flags | dns_transaction_source_to_query_flags(t->answer_source);
|
||||||
q->answer_errno = t->answer_errno;
|
q->answer_errno = t->answer_errno;
|
||||||
dns_packet_unref(q->answer_full_packet);
|
dns_packet_unref(q->answer_full_packet);
|
||||||
q->answer_full_packet = dns_packet_ref(t->received);
|
q->answer_full_packet = dns_packet_ref(t->received);
|
||||||
@ -888,8 +898,9 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == DNS_TRANSACTION_SUCCESS) {
|
if (state == DNS_TRANSACTION_SUCCESS) {
|
||||||
q->answer_authenticated = has_authenticated && !has_non_authenticated;
|
SET_FLAG(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED, has_authenticated && !has_non_authenticated);
|
||||||
q->answer_dnssec_result = q->answer_authenticated ? dnssec_result_authenticated : dnssec_result_non_authenticated;
|
SET_FLAG(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, has_confidential && !has_non_confidential);
|
||||||
|
q->answer_dnssec_result = FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED) ? dnssec_result_authenticated : dnssec_result_non_authenticated;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->answer_protocol = c->scope->protocol;
|
q->answer_protocol = c->scope->protocol;
|
||||||
@ -1049,8 +1060,10 @@ int dns_query_process_cname(DnsQuery *q) {
|
|||||||
if (q->flags & SD_RESOLVED_NO_CNAME)
|
if (q->flags & SD_RESOLVED_NO_CNAME)
|
||||||
return -ELOOP;
|
return -ELOOP;
|
||||||
|
|
||||||
if (!q->answer_authenticated)
|
if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
q->previous_redirect_unauthenticated = true;
|
q->previous_redirect_unauthenticated = true;
|
||||||
|
if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL))
|
||||||
|
q->previous_redirect_non_confidential = true;
|
||||||
|
|
||||||
/* OK, let's actually follow the CNAME */
|
/* OK, let's actually follow the CNAME */
|
||||||
r = dns_query_cname_redirect(q, cname);
|
r = dns_query_cname_redirect(q, cname);
|
||||||
@ -1119,5 +1132,11 @@ const char *dns_query_string(DnsQuery *q) {
|
|||||||
bool dns_query_fully_authenticated(DnsQuery *q) {
|
bool dns_query_fully_authenticated(DnsQuery *q) {
|
||||||
assert(q);
|
assert(q);
|
||||||
|
|
||||||
return q->answer_authenticated && !q->previous_redirect_unauthenticated;
|
return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED) && !q->previous_redirect_unauthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dns_query_fully_confidential(DnsQuery *q) {
|
||||||
|
assert(q);
|
||||||
|
|
||||||
|
return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) && !q->previous_redirect_non_confidential;
|
||||||
}
|
}
|
||||||
|
@ -66,12 +66,13 @@ struct DnsQuery {
|
|||||||
DnsAnswer *answer;
|
DnsAnswer *answer;
|
||||||
int answer_rcode;
|
int answer_rcode;
|
||||||
DnssecResult answer_dnssec_result;
|
DnssecResult answer_dnssec_result;
|
||||||
bool answer_authenticated;
|
uint64_t answer_query_flags;
|
||||||
DnsProtocol answer_protocol;
|
DnsProtocol answer_protocol;
|
||||||
int answer_family;
|
int answer_family;
|
||||||
DnsSearchDomain *answer_search_domain;
|
DnsSearchDomain *answer_search_domain;
|
||||||
int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
|
int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
|
||||||
bool previous_redirect_unauthenticated;
|
bool previous_redirect_unauthenticated;
|
||||||
|
bool previous_redirect_non_confidential;
|
||||||
DnsPacket *answer_full_packet;
|
DnsPacket *answer_full_packet;
|
||||||
|
|
||||||
/* Bus + Varlink client information */
|
/* Bus + Varlink client information */
|
||||||
@ -132,3 +133,14 @@ const char *dns_query_string(DnsQuery *q);
|
|||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
|
||||||
|
|
||||||
bool dns_query_fully_authenticated(DnsQuery *q);
|
bool dns_query_fully_authenticated(DnsQuery *q);
|
||||||
|
bool dns_query_fully_confidential(DnsQuery *q);
|
||||||
|
|
||||||
|
static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
|
||||||
|
assert(q);
|
||||||
|
|
||||||
|
return SD_RESOLVED_FLAGS_MAKE(q->answer_protocol,
|
||||||
|
q->answer_family,
|
||||||
|
dns_query_fully_authenticated(q),
|
||||||
|
dns_query_fully_confidential(q)) |
|
||||||
|
(q->answer_query_flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC));
|
||||||
|
}
|
||||||
|
@ -477,6 +477,65 @@ static DnsScopeMatch match_link_local_reverse_lookups(const char *domain) {
|
|||||||
return _DNS_SCOPE_MATCH_INVALID;
|
return _DNS_SCOPE_MATCH_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DnsScopeMatch match_subnet_reverse_lookups(
|
||||||
|
DnsScope *s,
|
||||||
|
const char *domain,
|
||||||
|
bool exclude_own) {
|
||||||
|
|
||||||
|
union in_addr_union ia;
|
||||||
|
LinkAddress *a;
|
||||||
|
int f, r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
assert(domain);
|
||||||
|
|
||||||
|
/* Checks whether the specified domain is a reverse address domain (i.e. in the .in-addr.arpa or
|
||||||
|
* .ip6.arpa area), and if so, whether the address matches any of the local subnets of the link the
|
||||||
|
* scope is associated with. If so, our scope should consider itself relevant for any lookup in the
|
||||||
|
* domain, since it apparently refers to hosts on this link's subnet.
|
||||||
|
*
|
||||||
|
* If 'exclude_own' is true this will return DNS_SCOPE_NO for any IP addresses assigned locally. This
|
||||||
|
* is useful for LLMNR/mDNS as we never want to look up our own hostname on LLMNR/mDNS but always use
|
||||||
|
* the locally synthesized one. */
|
||||||
|
|
||||||
|
if (!s->link)
|
||||||
|
return _DNS_SCOPE_MATCH_INVALID; /* No link, hence no local addresses to check */
|
||||||
|
|
||||||
|
r = dns_name_address(domain, &f, &ia);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to determine whether '%s' is an address domain: %m", domain);
|
||||||
|
if (r <= 0)
|
||||||
|
return _DNS_SCOPE_MATCH_INVALID;
|
||||||
|
|
||||||
|
if (s->family != AF_UNSPEC && f != s->family)
|
||||||
|
return _DNS_SCOPE_MATCH_INVALID; /* Don't look for IPv4 addresses on LLMNR/mDNS over IPv6 and vice versa */
|
||||||
|
|
||||||
|
LIST_FOREACH(addresses, a, s->link->addresses) {
|
||||||
|
|
||||||
|
if (a->family != f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Equals our own address? nah, let's not use this scope. The local synthesizer will pick it up for us. */
|
||||||
|
if (exclude_own &&
|
||||||
|
in_addr_equal(f, &a->in_addr, &ia) > 0)
|
||||||
|
return DNS_SCOPE_NO;
|
||||||
|
|
||||||
|
if (a->prefixlen == UCHAR_MAX) /* don't know subnet mask */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Check if the address is in the local subnet */
|
||||||
|
r = in_addr_prefix_covers(f, &a->in_addr, a->prefixlen, &ia);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to determine whether link address covers lookup address '%s': %m", domain);
|
||||||
|
if (r > 0)
|
||||||
|
/* Note that we only claim zero labels match. This is so that this is at the same
|
||||||
|
* priority a DNS scope with "." as routing domain is. */
|
||||||
|
return DNS_SCOPE_YES_BASE + 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _DNS_SCOPE_MATCH_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
DnsScopeMatch dns_scope_good_domain(
|
DnsScopeMatch dns_scope_good_domain(
|
||||||
DnsScope *s,
|
DnsScope *s,
|
||||||
int ifindex,
|
int ifindex,
|
||||||
@ -505,7 +564,7 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
|
if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
|
||||||
return DNS_SCOPE_NO;
|
return DNS_SCOPE_NO;
|
||||||
|
|
||||||
if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, 0) & flags) == 0)
|
if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, false, false) & flags) == 0)
|
||||||
return DNS_SCOPE_NO;
|
return DNS_SCOPE_NO;
|
||||||
|
|
||||||
/* Never resolve any loopback hostname or IP address via DNS, LLMNR or mDNS. Instead, always rely on
|
/* Never resolve any loopback hostname or IP address via DNS, LLMNR or mDNS. Instead, always rely on
|
||||||
@ -533,6 +592,7 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
|
|
||||||
case DNS_PROTOCOL_DNS: {
|
case DNS_PROTOCOL_DNS: {
|
||||||
bool has_search_domains = false;
|
bool has_search_domains = false;
|
||||||
|
DnsScopeMatch m;
|
||||||
int n_best = -1;
|
int n_best = -1;
|
||||||
|
|
||||||
/* Never route things to scopes that lack DNS servers */
|
/* Never route things to scopes that lack DNS servers */
|
||||||
@ -579,6 +639,13 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
dns_name_endswith(domain, "local") > 0)
|
dns_name_endswith(domain, "local") > 0)
|
||||||
return DNS_SCOPE_NO;
|
return DNS_SCOPE_NO;
|
||||||
|
|
||||||
|
/* If the IP address to look up matches the local subnet, then implicity synthesizes
|
||||||
|
* DNS_SCOPE_YES_BASE + 0 on this interface, i.e. preferably resolve IP addresses via the DNS
|
||||||
|
* server belonging to this interface. */
|
||||||
|
m = match_subnet_reverse_lookups(s, domain, false);
|
||||||
|
if (m >= 0)
|
||||||
|
return m;
|
||||||
|
|
||||||
/* If there was no match at all, then see if this scope is suitable as default route. */
|
/* If there was no match at all, then see if this scope is suitable as default route. */
|
||||||
if (!dns_scope_is_default_route(s))
|
if (!dns_scope_is_default_route(s))
|
||||||
return DNS_SCOPE_NO;
|
return DNS_SCOPE_NO;
|
||||||
@ -593,6 +660,10 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
if (m >= 0)
|
if (m >= 0)
|
||||||
return m;
|
return m;
|
||||||
|
|
||||||
|
m = match_subnet_reverse_lookups(s, domain, true);
|
||||||
|
if (m >= 0)
|
||||||
|
return m;
|
||||||
|
|
||||||
if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
|
if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
|
||||||
(s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0))
|
(s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0))
|
||||||
return DNS_SCOPE_MAYBE;
|
return DNS_SCOPE_MAYBE;
|
||||||
@ -612,6 +683,10 @@ DnsScopeMatch dns_scope_good_domain(
|
|||||||
if (m >= 0)
|
if (m >= 0)
|
||||||
return m;
|
return m;
|
||||||
|
|
||||||
|
m = match_subnet_reverse_lookups(s, domain, true);
|
||||||
|
if (m >= 0)
|
||||||
|
return m;
|
||||||
|
|
||||||
if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
|
if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
|
||||||
(s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0))
|
(s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0))
|
||||||
return DNS_SCOPE_MAYBE;
|
return DNS_SCOPE_MAYBE;
|
||||||
|
@ -281,16 +281,15 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
|
|||||||
if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
|
if (s->packet_bad_opt && level >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
|
||||||
level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1;
|
level = DNS_SERVER_FEATURE_LEVEL_EDNS0 - 1;
|
||||||
|
|
||||||
/* Even if we successfully receive a reply to a request announcing support for large packets,
|
/* Even if we successfully receive a reply to a request announcing support for large packets, that
|
||||||
that does not mean we can necessarily receive large packets. */
|
* does not mean we can necessarily receive large packets. */
|
||||||
if (level == DNS_SERVER_FEATURE_LEVEL_LARGE)
|
if (level == DNS_SERVER_FEATURE_LEVEL_LARGE)
|
||||||
level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1;
|
level = DNS_SERVER_FEATURE_LEVEL_LARGE - 1;
|
||||||
|
|
||||||
dns_server_verified(s, level);
|
dns_server_verified(s, level);
|
||||||
|
|
||||||
/* Remember the size of the largest UDP packet we received from a server,
|
/* Remember the size of the largest UDP packet we received from a server, we know that we can always
|
||||||
we know that we can always announce support for packets with at least
|
* announce support for packets with at least this size. */
|
||||||
this size. */
|
|
||||||
if (protocol == IPPROTO_UDP && s->received_udp_packet_max < size)
|
if (protocol == IPPROTO_UDP && s->received_udp_packet_max < size)
|
||||||
s->received_udp_packet_max = size;
|
s->received_udp_packet_max = size;
|
||||||
}
|
}
|
||||||
@ -299,15 +298,16 @@ void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel le
|
|||||||
assert(s);
|
assert(s);
|
||||||
assert(s->manager);
|
assert(s->manager);
|
||||||
|
|
||||||
if (s->possible_feature_level == level) {
|
if (s->possible_feature_level != level)
|
||||||
if (protocol == IPPROTO_UDP)
|
return;
|
||||||
s->n_failed_udp++;
|
|
||||||
else if (protocol == IPPROTO_TCP) {
|
if (protocol == IPPROTO_UDP)
|
||||||
if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(level))
|
s->n_failed_udp++;
|
||||||
s->n_failed_tls++;
|
else if (protocol == IPPROTO_TCP) {
|
||||||
else
|
if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(level))
|
||||||
s->n_failed_tcp++;
|
s->n_failed_tls++;
|
||||||
}
|
else
|
||||||
|
s->n_failed_tcp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ static void dns_transaction_reset_answer(DnsTransaction *t) {
|
|||||||
t->answer_rcode = 0;
|
t->answer_rcode = 0;
|
||||||
t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
||||||
t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
|
t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID;
|
||||||
t->answer_authenticated = false;
|
t->answer_query_flags = 0;
|
||||||
t->answer_nsec_ttl = (uint32_t) -1;
|
t->answer_nsec_ttl = (uint32_t) -1;
|
||||||
t->answer_errno = 0;
|
t->answer_errno = 0;
|
||||||
}
|
}
|
||||||
@ -410,7 +410,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
|
|||||||
else
|
else
|
||||||
st = dns_transaction_state_to_string(state);
|
st = dns_transaction_state_to_string(state);
|
||||||
|
|
||||||
log_debug("%s transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s).",
|
log_debug("%s transaction %" PRIu16 " for <%s> on scope %s on %s/%s now complete with <%s> from %s (%s; %s).",
|
||||||
t->bypass ? "Bypass" : "Regular",
|
t->bypass ? "Bypass" : "Regular",
|
||||||
t->id,
|
t->id,
|
||||||
dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str),
|
dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str),
|
||||||
@ -420,7 +420,8 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
|
|||||||
st,
|
st,
|
||||||
t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
|
t->answer_source < 0 ? "none" : dns_transaction_source_to_string(t->answer_source),
|
||||||
FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) ? "not validated" :
|
FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) ? "not validated" :
|
||||||
(t->answer_authenticated ? "authenticated" : "unsigned"));
|
(FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED) ? "authenticated" : "unsigned"),
|
||||||
|
FLAGS_SET(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) ? "confidential" : "non-confidential");
|
||||||
|
|
||||||
t->state = state;
|
t->state = state;
|
||||||
|
|
||||||
@ -561,10 +562,15 @@ static void on_transaction_stream_error(DnsTransaction *t, int error) {
|
|||||||
dns_transaction_complete_errno(t, error);
|
dns_transaction_complete_errno(t, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) {
|
static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsStream *s, DnsPacket *p) {
|
||||||
|
bool encrypted;
|
||||||
|
|
||||||
assert(t);
|
assert(t);
|
||||||
|
assert(s);
|
||||||
assert(p);
|
assert(p);
|
||||||
|
|
||||||
|
encrypted = s->encrypted;
|
||||||
|
|
||||||
dns_transaction_close_connection(t, true);
|
dns_transaction_close_connection(t, true);
|
||||||
|
|
||||||
if (dns_packet_validate_reply(p) <= 0) {
|
if (dns_packet_validate_reply(p) <= 0) {
|
||||||
@ -576,7 +582,7 @@ static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) {
|
|||||||
dns_scope_check_conflicts(t->scope, p);
|
dns_scope_check_conflicts(t->scope, p);
|
||||||
|
|
||||||
t->block_gc++;
|
t->block_gc++;
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, encrypted);
|
||||||
t->block_gc--;
|
t->block_gc--;
|
||||||
|
|
||||||
/* If the response wasn't useful, then complete the transition
|
/* If the response wasn't useful, then complete the transition
|
||||||
@ -621,12 +627,12 @@ static int on_stream_packet(DnsStream *s) {
|
|||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
/* Take ownership of packet to be able to receive new packets */
|
/* Take ownership of packet to be able to receive new packets */
|
||||||
p = dns_stream_take_read_packet(s);
|
assert_se(p = dns_stream_take_read_packet(s));
|
||||||
assert(p);
|
|
||||||
|
|
||||||
t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
|
t = hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
|
||||||
if (t)
|
if (t && t->stream == s) /* Validate that the stream we got this on actually is the stream the
|
||||||
return dns_transaction_on_stream_packet(t, p);
|
* transaction was using. */
|
||||||
|
return dns_transaction_on_stream_packet(t, s, p);
|
||||||
|
|
||||||
/* Ignore incorrect transaction id as an old transaction can have been canceled. */
|
/* Ignore incorrect transaction id as an old transaction can have been canceled. */
|
||||||
log_debug("Received unexpected TCP reply packet with id %" PRIu16 ", ignoring.", DNS_PACKET_ID(p));
|
log_debug("Received unexpected TCP reply packet with id %" PRIu16 ", ignoring.", DNS_PACKET_ID(p));
|
||||||
@ -793,7 +799,7 @@ static void dns_transaction_cache_answer(DnsTransaction *t) {
|
|||||||
* since our usecase for caching them
|
* since our usecase for caching them
|
||||||
* is "bypass" mode which is only
|
* is "bypass" mode which is only
|
||||||
* enabled for CD packets. */
|
* enabled for CD packets. */
|
||||||
t->answer_authenticated,
|
t->answer_query_flags,
|
||||||
t->answer_dnssec_result,
|
t->answer_dnssec_result,
|
||||||
t->answer_nsec_ttl,
|
t->answer_nsec_ttl,
|
||||||
t->received->family,
|
t->received->family,
|
||||||
@ -990,7 +996,7 @@ static int dns_transaction_fix_rcode(DnsTransaction *t) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
|
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(t);
|
assert(t);
|
||||||
@ -1231,7 +1237,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
|
|||||||
t->answer = dns_answer_ref(p->answer);
|
t->answer = dns_answer_ref(p->answer);
|
||||||
t->answer_rcode = DNS_PACKET_RCODE(p);
|
t->answer_rcode = DNS_PACKET_RCODE(p);
|
||||||
t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
t->answer_dnssec_result = _DNSSEC_RESULT_INVALID;
|
||||||
t->answer_authenticated = false;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
|
||||||
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, encrypted);
|
||||||
|
|
||||||
r = dns_transaction_fix_rcode(t);
|
r = dns_transaction_fix_rcode(t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1315,7 +1322,7 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1519,7 +1526,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
|||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
t->answer_rcode = DNS_RCODE_SUCCESS;
|
t->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
|
t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
|
||||||
t->answer_authenticated = true;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true);
|
||||||
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
|
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1538,7 +1545,8 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
|||||||
|
|
||||||
t->answer_rcode = DNS_RCODE_SUCCESS;
|
t->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
|
t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
|
||||||
t->answer_authenticated = false;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
|
||||||
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_CONFIDENTIAL, true);
|
||||||
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
|
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
|
||||||
} else
|
} else
|
||||||
/* If we are not in downgrade mode, then fail the lookup, because we cannot
|
/* If we are not in downgrade mode, then fail the lookup, because we cannot
|
||||||
@ -1559,7 +1567,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
|||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
t->answer_rcode = DNS_RCODE_SUCCESS;
|
t->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
t->answer_source = DNS_TRANSACTION_ZONE;
|
t->answer_source = DNS_TRANSACTION_ZONE;
|
||||||
t->answer_authenticated = true;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL, true);
|
||||||
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
|
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1582,7 +1590,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
|||||||
&t->answer_rcode,
|
&t->answer_rcode,
|
||||||
&t->answer,
|
&t->answer,
|
||||||
&t->received,
|
&t->received,
|
||||||
&t->answer_authenticated,
|
&t->answer_query_flags,
|
||||||
&t->answer_dnssec_result);
|
&t->answer_dnssec_result);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -2566,7 +2574,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
|
|||||||
* RRs we are looking at. If it discovered signed DS
|
* RRs we are looking at. If it discovered signed DS
|
||||||
* RRs, then we need to be signed, too. */
|
* RRs, then we need to be signed, too. */
|
||||||
|
|
||||||
if (!dt->answer_authenticated)
|
if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
|
return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
|
||||||
@ -2618,7 +2626,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return t->answer_authenticated;
|
return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2642,12 +2650,10 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We found the transaction that was supposed to find
|
/* We found the transaction that was supposed to find the SOA RR for us. It was
|
||||||
* the SOA RR for us. It was successful, but found no
|
* successful, but found no RR for us. This means we are not at a zone cut. In this
|
||||||
* RR for us. This means we are not at a zone cut. In
|
* case, we require authentication if the SOA lookup was authenticated too. */
|
||||||
* this case, we require authentication if the SOA
|
return FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
* lookup was authenticated too. */
|
|
||||||
return t->answer_authenticated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2788,7 +2794,7 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return dt->answer_authenticated;
|
return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If in doubt, require NSEC/NSEC3 */
|
/* If in doubt, require NSEC/NSEC3 */
|
||||||
@ -2832,11 +2838,10 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* OK, we found an auxiliary DNSKEY
|
/* OK, we found an auxiliary DNSKEY lookup. If that lookup is authenticated,
|
||||||
* lookup. If that lookup is
|
* report this. */
|
||||||
* authenticated, report this. */
|
|
||||||
|
|
||||||
if (dt->answer_authenticated)
|
if (FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
@ -2849,12 +2854,10 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* OK, we found an auxiliary DS
|
/* OK, we found an auxiliary DS lookup. If that lookup is authenticated and
|
||||||
* lookup. If that lookup is
|
* non-zero, we won! */
|
||||||
* authenticated and non-zero, we
|
|
||||||
* won! */
|
|
||||||
|
|
||||||
if (!dt->answer_authenticated)
|
if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
|
return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
|
||||||
@ -2942,7 +2945,7 @@ static int dns_transaction_copy_validated(DnsTransaction *t) {
|
|||||||
if (DNS_TRANSACTION_IS_LIVE(dt->state))
|
if (DNS_TRANSACTION_IS_LIVE(dt->state))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!dt->answer_authenticated)
|
if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = dns_answer_extend(&t->validated_keys, dt->answer);
|
r = dns_answer_extend(&t->validated_keys, dt->answer);
|
||||||
@ -3244,7 +3247,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
|||||||
/* Our own stuff needs no validation */
|
/* Our own stuff needs no validation */
|
||||||
if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
|
if (IN_SET(t->answer_source, DNS_TRANSACTION_ZONE, DNS_TRANSACTION_TRUST_ANCHOR)) {
|
||||||
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
||||||
t->answer_authenticated = true;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3332,11 +3335,11 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
|||||||
/* The answer is fully authenticated, yay. */
|
/* The answer is fully authenticated, yay. */
|
||||||
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
||||||
t->answer_rcode = DNS_RCODE_SUCCESS;
|
t->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
t->answer_authenticated = true;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, true);
|
||||||
} else {
|
} else {
|
||||||
/* The answer is not fully authenticated. */
|
/* The answer is not fully authenticated. */
|
||||||
t->answer_dnssec_result = DNSSEC_UNSIGNED;
|
t->answer_dnssec_result = DNSSEC_UNSIGNED;
|
||||||
t->answer_authenticated = false;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (r == 0) {
|
} else if (r == 0) {
|
||||||
@ -3355,7 +3358,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
|||||||
log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
|
log_debug("Proved NXDOMAIN via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
|
||||||
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
||||||
t->answer_rcode = DNS_RCODE_NXDOMAIN;
|
t->answer_rcode = DNS_RCODE_NXDOMAIN;
|
||||||
t->answer_authenticated = authenticated;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated);
|
||||||
|
|
||||||
manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
|
manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
|
||||||
break;
|
break;
|
||||||
@ -3365,7 +3368,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
|||||||
log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
|
log_debug("Proved NODATA via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
|
||||||
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
t->answer_dnssec_result = DNSSEC_VALIDATED;
|
||||||
t->answer_rcode = DNS_RCODE_SUCCESS;
|
t->answer_rcode = DNS_RCODE_SUCCESS;
|
||||||
t->answer_authenticated = authenticated;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, authenticated);
|
||||||
|
|
||||||
manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
|
manager_dnssec_verdict(t->scope->manager, authenticated ? DNSSEC_SECURE : DNSSEC_INSECURE, dns_transaction_key(t));
|
||||||
break;
|
break;
|
||||||
@ -3374,7 +3377,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
|||||||
/* NSEC3 says the data might not be signed */
|
/* NSEC3 says the data might not be signed */
|
||||||
log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
|
log_debug("Data is NSEC3 opt-out via NSEC/NSEC3 for transaction %u (%s)", t->id, key_str);
|
||||||
t->answer_dnssec_result = DNSSEC_UNSIGNED;
|
t->answer_dnssec_result = DNSSEC_UNSIGNED;
|
||||||
t->answer_authenticated = false;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
|
||||||
|
|
||||||
manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
|
manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
|
||||||
break;
|
break;
|
||||||
@ -3390,7 +3393,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
|||||||
manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t));
|
manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, dns_transaction_key(t));
|
||||||
} else {
|
} else {
|
||||||
t->answer_dnssec_result = DNSSEC_UNSIGNED;
|
t->answer_dnssec_result = DNSSEC_UNSIGNED;
|
||||||
t->answer_authenticated = false;
|
SET_FLAG(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED, false);
|
||||||
manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
|
manager_dnssec_verdict(t->scope->manager, DNSSEC_INSECURE, dns_transaction_key(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,15 +77,12 @@ struct DnsTransaction {
|
|||||||
uint32_t answer_nsec_ttl;
|
uint32_t answer_nsec_ttl;
|
||||||
int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
|
int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
|
||||||
|
|
||||||
/* Indicates whether the primary answer is authenticated,
|
/* SD_RESOLVED_AUTHENTICATED here indicates whether the primary answer is authenticated, i.e. whether
|
||||||
* i.e. whether the RRs from answer which directly match the
|
* the RRs from answer which directly match the question are authenticated, or, if there are none,
|
||||||
* question are authenticated, or, if there are none, whether
|
* whether the NODATA or NXDOMAIN case is. It says nothing about additional RRs listed in the answer,
|
||||||
* the NODATA or NXDOMAIN case is. It says nothing about
|
* however they have their own DNS_ANSWER_AUTHORIZED FLAGS. Note that this bit is defined different
|
||||||
* additional RRs listed in the answer, however they have
|
* than the AD bit in DNS packets, as that covers more than just the actual primary answer. */
|
||||||
* their own DNS_ANSWER_AUTHORIZED FLAGS. Note that this bit
|
uint64_t answer_query_flags;
|
||||||
* is defined different than the AD bit in DNS packets, as
|
|
||||||
* that covers more than just the actual primary answer. */
|
|
||||||
bool answer_authenticated;
|
|
||||||
|
|
||||||
/* Contains DNSKEY, DS, SOA RRs we already verified and need
|
/* Contains DNSKEY, DS, SOA RRs we already verified and need
|
||||||
* to authenticate this reply */
|
* to authenticate this reply */
|
||||||
@ -148,7 +145,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_gc);
|
|||||||
|
|
||||||
int dns_transaction_go(DnsTransaction *t);
|
int dns_transaction_go(DnsTransaction *t);
|
||||||
|
|
||||||
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p);
|
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypted);
|
||||||
void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
|
void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
|
||||||
|
|
||||||
void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source);
|
void dns_transaction_notify(DnsTransaction *t, DnsTransaction *source);
|
||||||
@ -172,6 +169,27 @@ static inline DnsResourceKey *dns_transaction_key(DnsTransaction *t) {
|
|||||||
return t->bypass->question->keys[0];
|
return t->bypass->question->keys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint64_t dns_transaction_source_to_query_flags(DnsTransactionSource s) {
|
||||||
|
|
||||||
|
switch (s) {
|
||||||
|
|
||||||
|
case DNS_TRANSACTION_NETWORK:
|
||||||
|
return SD_RESOLVED_FROM_NETWORK;
|
||||||
|
|
||||||
|
case DNS_TRANSACTION_CACHE:
|
||||||
|
return SD_RESOLVED_FROM_CACHE;
|
||||||
|
|
||||||
|
case DNS_TRANSACTION_ZONE:
|
||||||
|
return SD_RESOLVED_FROM_ZONE;
|
||||||
|
|
||||||
|
case DNS_TRANSACTION_TRUST_ANCHOR:
|
||||||
|
return SD_RESOLVED_FROM_TRUST_ANCHOR;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
|
const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
|
||||||
DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
|
DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
@ -296,6 +296,8 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bus_client_log(message, "DNS server change");
|
||||||
|
|
||||||
dns_server_mark_all(l->dns_servers);
|
dns_server_mark_all(l->dns_servers);
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
@ -404,6 +406,8 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "dns domains change");
|
||||||
|
|
||||||
dns_search_domain_mark_all(l->search_domains);
|
dns_search_domain_mark_all(l->search_domains);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -477,6 +481,8 @@ int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, s
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "dns default route change");
|
||||||
|
|
||||||
if (l->default_route != b) {
|
if (l->default_route != b) {
|
||||||
l->default_route = b;
|
l->default_route = b;
|
||||||
|
|
||||||
@ -523,6 +529,8 @@ int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_er
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "LLMNR change");
|
||||||
|
|
||||||
l->llmnr_support = mode;
|
l->llmnr_support = mode;
|
||||||
link_allocate_scopes(l);
|
link_allocate_scopes(l);
|
||||||
link_add_rrs(l, false);
|
link_add_rrs(l, false);
|
||||||
@ -568,6 +576,8 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "mDNS change");
|
||||||
|
|
||||||
l->mdns_support = mode;
|
l->mdns_support = mode;
|
||||||
link_allocate_scopes(l);
|
link_allocate_scopes(l);
|
||||||
link_add_rrs(l, false);
|
link_add_rrs(l, false);
|
||||||
@ -613,6 +623,8 @@ int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "D-o-T change");
|
||||||
|
|
||||||
link_set_dns_over_tls_mode(l, mode);
|
link_set_dns_over_tls_mode(l, mode);
|
||||||
|
|
||||||
(void) link_save_user(l);
|
(void) link_save_user(l);
|
||||||
@ -657,6 +669,8 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "DNSSEC change");
|
||||||
|
|
||||||
link_set_dnssec_mode(l, mode);
|
link_set_dnssec_mode(l, mode);
|
||||||
|
|
||||||
(void) link_save_user(l);
|
(void) link_save_user(l);
|
||||||
@ -715,6 +729,8 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "DNSSEC NTA change");
|
||||||
|
|
||||||
set_free_free(l->dnssec_negative_trust_anchors);
|
set_free_free(l->dnssec_negative_trust_anchors);
|
||||||
l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
|
l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
|
||||||
|
|
||||||
@ -748,6 +764,8 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 1; /* Polkit will call us back */
|
return 1; /* Polkit will call us back */
|
||||||
|
|
||||||
|
bus_client_log(message, "revert");
|
||||||
|
|
||||||
link_flush_settings(l);
|
link_flush_settings(l);
|
||||||
link_allocate_scopes(l);
|
link_allocate_scopes(l);
|
||||||
link_add_rrs(l, false);
|
link_add_rrs(l, false);
|
||||||
|
@ -802,6 +802,7 @@ int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr
|
|||||||
.family = family,
|
.family = family,
|
||||||
.in_addr = *in_addr,
|
.in_addr = *in_addr,
|
||||||
.link = l,
|
.link = l,
|
||||||
|
.prefixlen = UCHAR_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
LIST_PREPEND(addresses, l->addresses, a);
|
LIST_PREPEND(addresses, l->addresses, a);
|
||||||
@ -1094,6 +1095,7 @@ fail:
|
|||||||
|
|
||||||
int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
|
int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(a);
|
assert(a);
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
@ -1101,7 +1103,8 @@ int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
sd_rtnl_message_addr_get_scope(m, &a->scope);
|
(void) sd_rtnl_message_addr_get_prefixlen(m, &a->prefixlen);
|
||||||
|
(void) sd_rtnl_message_addr_get_scope(m, &a->scope);
|
||||||
|
|
||||||
link_allocate_scopes(a->link);
|
link_allocate_scopes(a->link);
|
||||||
link_add_rrs(a->link, false);
|
link_add_rrs(a->link, false);
|
||||||
|
@ -23,6 +23,7 @@ struct LinkAddress {
|
|||||||
|
|
||||||
int family;
|
int family;
|
||||||
union in_addr_union in_addr;
|
union in_addr_union in_addr;
|
||||||
|
unsigned char prefixlen;
|
||||||
|
|
||||||
unsigned char flags, scope;
|
unsigned char flags, scope;
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *u
|
|||||||
|
|
||||||
t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
|
t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
|
||||||
if (t)
|
if (t)
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, false);
|
||||||
|
|
||||||
} else if (dns_packet_validate_query(p) > 0) {
|
} else if (dns_packet_validate_query(p) > 0) {
|
||||||
log_debug("Got LLMNR UDP query packet for id %u", DNS_PACKET_ID(p));
|
log_debug("Got LLMNR UDP query packet for id %u", DNS_PACKET_ID(p));
|
||||||
|
@ -303,20 +303,20 @@ static int on_mdns_packet(sd_event_source *s, int fd, uint32_t revents, void *us
|
|||||||
|
|
||||||
t = dns_scope_find_transaction(scope, rr->key, SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
t = dns_scope_find_transaction(scope, rr->key, SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
||||||
if (t)
|
if (t)
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, false);
|
||||||
|
|
||||||
/* Also look for the various types of ANY transactions */
|
/* Also look for the various types of ANY transactions */
|
||||||
t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(rr->key->class, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
||||||
if (t)
|
if (t)
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, false);
|
||||||
|
|
||||||
t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, rr->key->type, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, rr->key->type, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
||||||
if (t)
|
if (t)
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, false);
|
||||||
|
|
||||||
t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
t = dns_scope_find_transaction(scope, &DNS_RESOURCE_KEY_CONST(DNS_CLASS_ANY, DNS_TYPE_ANY, dns_resource_key_name(rr->key)), SD_RESOLVED_NO_CACHE|SD_RESOLVED_NO_ZONE);
|
||||||
if (t)
|
if (t)
|
||||||
dns_transaction_process_reply(t, p);
|
dns_transaction_process_reply(t, p, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cache_put(&scope->cache, scope->manager->enable_cache, NULL, DNS_PACKET_RCODE(p), p->answer, NULL, false, _DNSSEC_RESULT_INVALID, (uint32_t) -1, p->family, &p->sender);
|
dns_cache_put(&scope->cache, scope->manager->enable_cache, NULL, DNS_PACKET_RCODE(p), p->answer, NULL, false, _DNSSEC_RESULT_INVALID, (uint32_t) -1, p->family, &p->sender);
|
||||||
|
@ -222,7 +222,7 @@ static void vl_method_resolve_hostname_complete(DnsQuery *q) {
|
|||||||
JSON_BUILD_OBJECT(
|
JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("addresses", JSON_BUILD_VARIANT(array)),
|
JSON_BUILD_PAIR("addresses", JSON_BUILD_VARIANT(array)),
|
||||||
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(normalized)),
|
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(normalized)),
|
||||||
JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q))))));
|
JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(dns_query_reply_flags_make(q)))));
|
||||||
finish:
|
finish:
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error_errno(r, "Failed to send hostname reply: %m");
|
log_error_errno(r, "Failed to send hostname reply: %m");
|
||||||
@ -267,7 +267,8 @@ static int parse_as_address(Varlink *link, LookupParameters *p) {
|
|||||||
JSON_BUILD_PAIR("family", JSON_BUILD_INTEGER(ff)),
|
JSON_BUILD_PAIR("family", JSON_BUILD_INTEGER(ff)),
|
||||||
JSON_BUILD_PAIR("address", JSON_BUILD_BYTE_ARRAY(&parsed, FAMILY_ADDRESS_SIZE(ff)))))),
|
JSON_BUILD_PAIR("address", JSON_BUILD_BYTE_ARRAY(&parsed, FAMILY_ADDRESS_SIZE(ff)))))),
|
||||||
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(canonical)),
|
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(canonical)),
|
||||||
JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(p->flags), ff, true)))));
|
JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(p->flags), ff, true, true)|
|
||||||
|
SD_RESOLVED_SYNTHETIC))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vl_method_resolve_hostname(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
|
static int vl_method_resolve_hostname(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
|
||||||
@ -440,7 +441,7 @@ static void vl_method_resolve_address_complete(DnsQuery *q) {
|
|||||||
r = varlink_replyb(q->varlink_request,
|
r = varlink_replyb(q->varlink_request,
|
||||||
JSON_BUILD_OBJECT(
|
JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("names", JSON_BUILD_VARIANT(array)),
|
JSON_BUILD_PAIR("names", JSON_BUILD_VARIANT(array)),
|
||||||
JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q))))));
|
JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(dns_query_reply_flags_make(q)))));
|
||||||
finish:
|
finish:
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error_errno(r, "Failed to send address reply: %m");
|
log_error_errno(r, "Failed to send address reply: %m");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user