2020-11-09 13:23:58 +09:00
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2014-07-16 00:26:02 +02:00
2015-10-27 03:01:06 +01:00
# include "alloc-util.h"
2014-12-10 19:00:46 +01:00
# include "bus-common-errors.h"
2020-06-28 16:43:29 +02:00
# include "bus-get-properties.h"
2023-05-23 20:23:17 +02:00
# include "bus-locator.h"
2020-04-21 10:27:23 +02:00
# include "bus-log-control-api.h"
2020-07-19 12:32:21 +09:00
# include "bus-message-util.h"
2020-01-22 11:39:22 +01:00
# include "bus-polkit.h"
2015-06-02 11:49:43 -07:00
# include "dns-domain.h"
2020-11-09 22:20:16 +01:00
# include "format-util.h"
2019-03-13 12:02:21 +01:00
# include "memory-util.h"
2018-12-06 07:20:07 +01:00
# include "missing_capability.h"
2024-04-22 12:32:54 +02:00
# include "path-util.h"
2014-08-01 16:14:59 +02:00
# include "resolved-bus.h"
2014-08-14 01:00:15 +02:00
# include "resolved-def.h"
2024-03-01 21:46:46 +01:00
# include "resolved-dns-stream.h"
2016-02-13 20:26:30 +01:00
# include "resolved-dns-synthesize.h"
2017-10-23 14:46:13 +03:00
# include "resolved-dnssd-bus.h"
2019-03-13 12:02:21 +01:00
# include "resolved-dnssd.h"
2016-01-19 18:32:42 +01:00
# include "resolved-link-bus.h"
2020-09-29 17:25:15 +02:00
# include "resolved-resolv-conf.h"
2020-01-10 17:22:37 +01:00
# include "socket-netlink.h"
2019-10-24 15:14:09 +02:00
# include "stdio-util.h"
2019-10-25 15:19:36 +02:00
# include "strv.h"
2020-04-20 11:02:39 +02:00
# include "syslog-util.h"
2017-11-22 16:49:23 +02:00
# include "user-util.h"
2017-10-23 14:46:13 +03:00
# include "utf8.h"
2014-07-16 00:26:02 +02:00
2018-03-19 14:29:22 +09:00
BUS_DEFINE_PROPERTY_GET_ENUM ( bus_property_get_resolve_support , resolve_support , ResolveSupport ) ;
2020-08-16 13:43:51 +02:00
static int query_on_bus_track ( sd_bus_track * t , void * userdata ) {
2022-08-09 14:35:15 +02:00
DnsQuery * q = ASSERT_PTR ( userdata ) ;
2020-08-16 13:43:51 +02:00
assert ( t ) ;
if ( ! DNS_TRANSACTION_IS_LIVE ( q - > state ) )
return 0 ;
log_debug ( " Client of active query vanished, aborting query. " ) ;
dns_query_complete ( q , DNS_TRANSACTION_ABORTED ) ;
return 0 ;
}
static int dns_query_bus_track ( DnsQuery * q , sd_bus_message * m ) {
int r ;
assert ( q ) ;
assert ( m ) ;
if ( ! q - > bus_track ) {
r = sd_bus_track_new ( sd_bus_message_get_bus ( m ) , & q - > bus_track , query_on_bus_track , q ) ;
if ( r < 0 )
return r ;
}
r = sd_bus_track_add_sender ( q - > bus_track , m ) ;
if ( r < 0 )
return r ;
return 0 ;
}
2022-02-17 11:48:31 +01:00
static sd_bus_message * dns_query_steal_request ( DnsQuery * q ) {
assert ( q ) ;
/* Find the main query, it's the one that owns the message */
while ( q - > auxiliary_for )
q = q - > auxiliary_for ;
/* Let's take the request message out of the DnsQuery object, so that we never send requests twice */
return TAKE_PTR ( q - > bus_request ) ;
}
_sd_printf_ ( 3 , 4 ) static int reply_method_errorf (
DnsQuery * query ,
const char * error_name ,
const char * format ,
. . . ) {
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * req = NULL ;
va_list ap ;
int r ;
assert ( query ) ;
assert ( format ) ;
req = dns_query_steal_request ( query ) ;
if ( ! req ) /* No bus message set anymore? then we already replied already, let's not answer a second time */
return 0 ;
va_start ( ap , format ) ;
r = sd_bus_reply_method_errorfv ( req , error_name , format , ap ) ;
va_end ( ap ) ;
return r ;
}
2014-07-16 20:15:47 +02:00
2022-02-17 11:48:31 +01:00
_sd_printf_ ( 3 , 4 ) static int reply_method_errnof (
DnsQuery * query ,
int err ,
const char * format ,
. . . ) {
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * req = NULL ;
int r ;
assert ( query ) ;
req = dns_query_steal_request ( query ) ;
if ( ! req ) /* No bus message set anymore? then we already replied already, let's not answer a second time */
return 0 ;
if ( format ) {
va_list ap ;
va_start ( ap , format ) ;
r = sd_bus_reply_method_errnofv ( req , err , format , ap ) ;
va_end ( ap ) ;
} else
r = sd_bus_reply_method_errno ( req , err , NULL ) ;
return r ;
}
static int reply_query_state ( DnsQuery * q ) {
2020-08-16 14:36:20 +02:00
assert ( q ) ;
2014-07-16 20:15:47 +02:00
switch ( q - > state ) {
2014-07-16 00:26:02 +02:00
2014-07-31 17:46:40 +02:00
case DNS_TRANSACTION_NO_SERVERS :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_NO_NAME_SERVERS , " No appropriate name servers or networks for name found " ) ;
2014-07-16 00:26:02 +02:00
2014-07-31 17:46:40 +02:00
case DNS_TRANSACTION_TIMEOUT :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , SD_BUS_ERROR_TIMEOUT , " Query timed out " ) ;
2014-07-16 00:26:02 +02:00
2014-07-31 17:46:40 +02:00
case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , SD_BUS_ERROR_TIMEOUT , " All attempts to contact name servers or networks failed " ) ;
2014-07-16 20:15:47 +02:00
2014-08-06 16:32:17 +02:00
case DNS_TRANSACTION_INVALID_REPLY :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_INVALID_REPLY , " Received invalid reply " ) ;
2014-08-06 16:32:17 +02:00
2016-01-22 17:22:23 +01:00
case DNS_TRANSACTION_ERRNO :
2022-02-17 11:48:31 +01:00
return reply_method_errnof ( q , q - > answer_errno , " Lookup failed due to system error: %m " ) ;
2014-07-16 20:15:47 +02:00
2014-08-06 16:32:17 +02:00
case DNS_TRANSACTION_ABORTED :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_ABORTED , " Query aborted " ) ;
2014-07-16 00:26:02 +02:00
resolved: chase DNSKEY/DS RRs when doing look-ups with DNSSEC enabled
This adds initial support for validating RRSIG/DNSKEY/DS chains when
doing lookups. Proof-of-non-existance, or proof-of-unsigned-zones is not
implemented yet.
With this change DnsTransaction objects will generate additional
DnsTransaction objects when looking for DNSKEY or DS RRs to validate an
RRSIG on a response. DnsTransaction objects are thus created for three
reasons now:
1) Because a user asked for something to be resolved, i.e. requested by
a DnsQuery/DnsQueryCandidate object.
2) As result of LLMNR RR probing, requested by a DnsZoneItem.
3) Because another DnsTransaction requires the requested RRs for
validation of its own response.
DnsTransactions are shared between all these users, and are GC
automatically as soon as all of these users don't need a specific
transaction anymore.
To unify the handling of these three reasons for existance for a
DnsTransaction, a new common naming is introduced: each DnsTransaction
now tracks its "owners" via a Set* object named "notify_xyz", containing
all owners to notify on completion.
A new DnsTransaction state is introduced called "VALIDATING" that is
entered after a response has been receieved which needs to be validated,
as long as we are still waiting for the DNSKEY/DS RRs from other
DnsTransactions.
This patch will request the DNSKEY/DS RRs bottom-up, and then validate
them top-down.
Caching of RRs is now only done after verification, so that the cache is
not poisoned with known invalid data.
The "DnsAnswer" object gained a substantial number of new calls, since
we need to add/remove RRs to it dynamically now.
2015-12-09 18:13:16 +01:00
case DNS_TRANSACTION_DNSSEC_FAILED :
2024-01-10 11:34:44 +09:00
return reply_method_errorf ( q , BUS_ERROR_DNSSEC_FAILED , " DNSSEC validation failed: %s%s%s%s%s%s " ,
dnssec_result_to_string ( q - > answer_dnssec_result ) ,
q - > answer_ede_rcode > = 0 ? " ( " : " " ,
q - > answer_ede_rcode > = 0 ? FORMAT_DNS_EDE_RCODE ( q - > answer_ede_rcode ) : " " ,
( q - > answer_ede_rcode > = 0 & & ! isempty ( q - > answer_ede_msg ) ) ? " : " : " " ,
q - > answer_ede_rcode > = 0 ? strempty ( q - > answer_ede_msg ) : " " ,
q - > answer_ede_rcode > = 0 ? " ) " : " " ) ;
resolved: chase DNSKEY/DS RRs when doing look-ups with DNSSEC enabled
This adds initial support for validating RRSIG/DNSKEY/DS chains when
doing lookups. Proof-of-non-existance, or proof-of-unsigned-zones is not
implemented yet.
With this change DnsTransaction objects will generate additional
DnsTransaction objects when looking for DNSKEY or DS RRs to validate an
RRSIG on a response. DnsTransaction objects are thus created for three
reasons now:
1) Because a user asked for something to be resolved, i.e. requested by
a DnsQuery/DnsQueryCandidate object.
2) As result of LLMNR RR probing, requested by a DnsZoneItem.
3) Because another DnsTransaction requires the requested RRs for
validation of its own response.
DnsTransactions are shared between all these users, and are GC
automatically as soon as all of these users don't need a specific
transaction anymore.
To unify the handling of these three reasons for existance for a
DnsTransaction, a new common naming is introduced: each DnsTransaction
now tracks its "owners" via a Set* object named "notify_xyz", containing
all owners to notify on completion.
A new DnsTransaction state is introduced called "VALIDATING" that is
entered after a response has been receieved which needs to be validated,
as long as we are still waiting for the DNSKEY/DS RRs from other
DnsTransactions.
This patch will request the DNSKEY/DS RRs bottom-up, and then validate
them top-down.
Caching of RRs is now only done after verification, so that the cache is
not poisoned with known invalid data.
The "DnsAnswer" object gained a substantial number of new calls, since
we need to add/remove RRs to it dynamically now.
2015-12-09 18:13:16 +01:00
2016-01-04 22:35:54 +01:00
case DNS_TRANSACTION_NO_TRUST_ANCHOR :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_NO_TRUST_ANCHOR , " No suitable trust anchor known " ) ;
2016-01-04 22:35:54 +01:00
2016-01-08 17:10:49 +01:00
case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_RR_TYPE_UNSUPPORTED , " Server does not support requested resource record type " ) ;
2016-01-08 17:10:49 +01:00
2016-01-20 21:28:22 +01:00
case DNS_TRANSACTION_NETWORK_DOWN :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_NETWORK_DOWN , " Network is down " ) ;
2016-01-20 21:28:22 +01:00
2016-01-22 12:09:38 +01:00
case DNS_TRANSACTION_NOT_FOUND :
/* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
* thus quickly know that we cannot resolve an in - addr . arpa or ip6 . arpa address . */
2023-02-07 14:38:28 +01:00
return reply_method_errorf ( q , BUS_ERROR_DNS_NXDOMAIN , " '%s' not found " , dns_query_string ( q ) ) ;
2016-01-22 12:09:38 +01:00
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
case DNS_TRANSACTION_NO_SOURCE :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_NO_SOURCE , " All suitable resolution sources turned off " ) ;
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
2020-11-05 16:27:55 +01:00
case DNS_TRANSACTION_STUB_LOOP :
2022-02-17 11:48:31 +01:00
return reply_method_errorf ( q , BUS_ERROR_STUB_LOOP , " Configured DNS server loops back to us " ) ;
2020-11-05 16:27:55 +01:00
2015-12-18 19:49:25 +01:00
case DNS_TRANSACTION_RCODE_FAILURE : {
tree-wide: expose "p"-suffix unref calls in public APIs to make gcc cleanup easy
GLIB has recently started to officially support the gcc cleanup
attribute in its public API, hence let's do the same for our APIs.
With this patch we'll define an xyz_unrefp() call for each public
xyz_unref() call, to make it easy to use inside a
__attribute__((cleanup())) expression. Then, all code is ported over to
make use of this.
The new calls are also documented in the man pages, with examples how to
use them (well, I only added docs where the _unref() call itself already
had docs, and the examples, only cover sd_bus_unrefp() and
sd_event_unrefp()).
This also renames sd_lldp_free() to sd_lldp_unref(), since that's how we
tend to call our destructors these days.
Note that this defines no public macro that wraps gcc's attribute and
makes it easier to use. While I think it's our duty in the library to
make our stuff easy to use, I figure it's not our duty to make gcc's own
features easy to use on its own. Most likely, client code which wants to
make use of this should define its own:
#define _cleanup_(function) __attribute__((cleanup(function)))
Or similar, to make the gcc feature easier to use.
Making this logic public has the benefit that we can remove three header
files whose only purpose was to define these functions internally.
See #2008.
2015-11-27 19:13:45 +01:00
_cleanup_ ( sd_bus_error_free ) sd_bus_error error = SD_BUS_ERROR_NULL ;
2022-02-17 11:48:31 +01:00
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * req = NULL ;
req = dns_query_steal_request ( q ) ;
if ( ! req ) /* No bus message set anymore? then we already replied already, let's not answer a second time */
return 0 ;
2014-07-16 00:26:02 +02:00
2014-07-22 21:48:41 +02:00
if ( q - > answer_rcode = = DNS_RCODE_NXDOMAIN )
2023-02-07 14:43:48 +01:00
sd_bus_error_setf ( & error , BUS_ERROR_DNS_NXDOMAIN , " Name '%s' not found " , dns_query_string ( q ) ) ;
2014-07-16 00:26:02 +02:00
else {
const char * rc , * n ;
2022-07-09 15:56:50 +09:00
rc = FORMAT_DNS_RCODE ( q - > answer_rcode ) ;
2015-02-03 02:05:59 +01:00
n = strjoina ( _BUS_ERROR_DNS , rc ) ;
2024-01-10 11:34:44 +09:00
sd_bus_error_setf ( & error , n , " Could not resolve '%s', server or network returned error: %s%s%s%s%s%s " ,
dns_query_string ( q ) , rc ,
q - > answer_ede_rcode > = 0 ? " ( " : " " ,
q - > answer_ede_rcode > = 0 ? FORMAT_DNS_EDE_RCODE ( q - > answer_ede_rcode ) : " " ,
( q - > answer_ede_rcode > = 0 & & ! isempty ( q - > answer_ede_msg ) ) ? " : " : " " ,
q - > answer_ede_rcode > = 0 ? strempty ( q - > answer_ede_msg ) : " " ,
q - > answer_ede_rcode > = 0 ? " ) " : " " ) ;
2014-07-16 00:26:02 +02:00
}
2022-02-17 11:48:31 +01:00
return sd_bus_reply_method_error ( req , & error ) ;
2014-07-16 00:26:02 +02:00
}
2014-07-31 17:46:40 +02:00
case DNS_TRANSACTION_NULL :
case DNS_TRANSACTION_PENDING :
2016-01-08 18:50:15 +01:00
case DNS_TRANSACTION_VALIDATING :
2014-07-31 17:46:40 +02:00
case DNS_TRANSACTION_SUCCESS :
2014-07-16 22:09:00 +02:00
default :
Drop the text argument from assert_not_reached()
In general we almost never hit those asserts in production code, so users see
them very rarely, if ever. But either way, we just need something that users
can pass to the developers.
We have quite a few of those asserts, and some have fairly nice messages, but
many are like "WTF?" or "???" or "unexpected something". The error that is
printed includes the file location, and function name. In almost all functions
there's at most one assert, so the function name alone is enough to identify
the failure for a developer. So we don't get much extra from the message, and
we might just as well drop them.
Dropping them makes our code a tiny bit smaller, and most importantly, improves
development experience by making it easy to insert such an assert in the code
without thinking how to phrase the argument.
2021-07-27 12:27:28 +02:00
assert_not_reached ( ) ;
2014-07-16 20:15:47 +02:00
}
}
2014-07-16 00:26:02 +02:00
2021-02-04 16:05:05 +01:00
static int append_address ( sd_bus_message * reply , DnsResourceRecord * rr , int ifindex ) {
2014-07-16 22:09:00 +02:00
int r ;
assert ( reply ) ;
assert ( rr ) ;
2021-02-04 16:05:05 +01:00
r = sd_bus_message_open_container ( reply , ' r ' , " iiay " ) ;
if ( r < 0 )
return r ;
2015-08-17 23:54:08 +02:00
r = sd_bus_message_append ( reply , " i " , ifindex ) ;
2014-07-16 22:09:00 +02:00
if ( r < 0 )
return r ;
2014-07-22 21:48:41 +02:00
if ( rr - > key - > type = = DNS_TYPE_A ) {
2014-07-18 16:09:30 +02:00
r = sd_bus_message_append ( reply , " i " , AF_INET ) ;
2014-07-16 22:09:00 +02:00
if ( r < 0 )
return r ;
r = sd_bus_message_append_array ( reply , ' y ' , & rr - > a . in_addr , sizeof ( struct in_addr ) ) ;
2014-07-22 21:48:41 +02:00
} else if ( rr - > key - > type = = DNS_TYPE_AAAA ) {
2014-07-18 16:09:30 +02:00
r = sd_bus_message_append ( reply , " i " , AF_INET6 ) ;
2014-07-16 22:09:00 +02:00
if ( r < 0 )
return r ;
r = sd_bus_message_append_array ( reply , ' y ' , & rr - > aaaa . in6_addr , sizeof ( struct in6_addr ) ) ;
2014-07-22 21:48:41 +02:00
} else
return - EAFNOSUPPORT ;
2014-07-16 22:09:00 +02:00
if ( r < 0 )
return r ;
2021-02-04 16:05:05 +01:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
return r ;
2014-07-16 22:09:00 +02:00
return 0 ;
}
2022-02-05 22:04:42 +09:00
static void bus_method_resolve_hostname_complete ( DnsQuery * query ) {
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
_cleanup_ ( dns_resource_record_unrefp ) DnsResourceRecord * canonical = NULL ;
tree-wide: expose "p"-suffix unref calls in public APIs to make gcc cleanup easy
GLIB has recently started to officially support the gcc cleanup
attribute in its public API, hence let's do the same for our APIs.
With this patch we'll define an xyz_unrefp() call for each public
xyz_unref() call, to make it easy to use inside a
__attribute__((cleanup())) expression. Then, all code is ported over to
make use of this.
The new calls are also documented in the man pages, with examples how to
use them (well, I only added docs where the _unref() call itself already
had docs, and the examples, only cover sd_bus_unrefp() and
sd_event_unrefp()).
This also renames sd_lldp_free() to sd_lldp_unref(), since that's how we
tend to call our destructors these days.
Note that this defines no public macro that wraps gcc's attribute and
makes it easier to use. While I think it's our duty in the library to
make our stuff easy to use, I figure it's not our duty to make gcc's own
features easy to use on its own. Most likely, client code which wants to
make use of this should define its own:
#define _cleanup_(function) __attribute__((cleanup(function)))
Or similar, to make the gcc feature easier to use.
Making this logic public has the benefit that we can remove three header
files whose only purpose was to define these functions internally.
See #2008.
2015-11-27 19:13:45 +01:00
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * reply = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = query ;
2016-02-16 14:17:53 +01:00
_cleanup_free_ char * normalized = NULL ;
2020-08-16 14:36:20 +02:00
DnsQuestion * question ;
2016-01-20 22:07:48 +01:00
DnsResourceRecord * rr ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
unsigned added = 0 ;
2016-01-20 22:07:48 +01:00
int ifindex , r ;
2014-07-16 00:26:02 +02:00
2014-07-16 20:15:47 +02:00
assert ( q ) ;
2014-07-16 00:26:02 +02:00
2014-07-31 17:46:40 +02:00
if ( q - > state ! = DNS_TRANSACTION_SUCCESS ) {
2014-07-16 20:15:47 +02:00
r = reply_query_state ( q ) ;
goto finish ;
}
2014-07-16 00:26:02 +02:00
2021-03-25 11:43:52 +01:00
r = dns_query_process_cname_many ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r = = - ELOOP ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_CNAME_LOOP , " CNAME loop detected, or CNAME resolving disabled on '%s' " , dns_query_string ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
}
if ( r < 0 )
goto finish ;
2022-02-05 22:04:42 +09:00
if ( r = = DNS_QUERY_CNAME ) {
/* This was a cname, and the query was restarted. */
TAKE_PTR ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
2022-02-05 22:04:42 +09:00
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2020-08-16 11:29:55 +02:00
r = sd_bus_message_new_method_return ( q - > bus_request , & reply ) ;
2014-07-16 20:15:47 +02:00
if ( r < 0 )
goto finish ;
2014-07-16 00:26:02 +02:00
2015-08-17 23:54:08 +02:00
r = sd_bus_message_open_container ( reply , ' a ' , " (iiay) " ) ;
2014-08-14 01:00:15 +02:00
if ( r < 0 )
goto finish ;
2014-07-16 22:09:00 +02:00
2020-08-16 14:36:20 +02:00
question = dns_query_question_for_protocol ( q , q - > answer_protocol ) ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
2020-08-16 14:36:20 +02:00
DNS_ANSWER_FOREACH_IFINDEX ( rr , ifindex , q - > answer ) {
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
2016-01-20 22:07:48 +01:00
r = dns_question_matches_rr ( question , rr , DNS_SEARCH_DOMAIN_NAME ( q - > answer_search_domain ) ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 )
continue ;
2014-07-16 00:26:02 +02:00
2021-02-04 16:05:05 +01:00
r = append_address ( reply , rr , ifindex ) ;
2016-01-20 22:07:48 +01:00
if ( r < 0 )
goto finish ;
2014-07-16 00:26:02 +02:00
2016-01-20 22:07:48 +01:00
if ( ! canonical )
canonical = dns_resource_record_ref ( rr ) ;
2014-07-16 22:50:41 +02:00
2016-02-22 20:32:04 -08:00
added + + ;
2014-07-16 22:09:00 +02:00
}
2014-07-16 00:26:02 +02:00
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( added < = 0 ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_RR , " '%s' does not have any RR of the requested type " , dns_query_string ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
2014-07-16 00:26:02 +02:00
}
2014-07-16 20:15:47 +02:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
goto finish ;
2020-08-16 14:36:20 +02:00
/* The key names are not necessarily normalized, make sure that they are when we return them to our
* bus clients . */
assert ( canonical ) ;
resolve: reject host names with leading or trailing dashes in /etc/hosts
https://tools.ietf.org/html/rfc1035#section-2.3.1 says (approximately)
that only letters, numbers, and non-leading non-trailing dashes are allowed
(for entries with A/AAAA records). We set no restrictions.
hosts(5) says:
> Host names may contain only alphanumeric characters, minus signs ("-"), and
> periods ("."). They must begin with an alphabetic character and end with an
> alphanumeric character.
nss-files follows those rules, and will ignore names in /etc/hosts that do not
follow this rule.
Let's follow the documented rules for /etc/hosts. In particular, this makes us
consitent with nss-files, reducing surprises for the user.
I'm pretty sure we should apply stricter filtering to names received over DNS
and LLMNR and MDNS, but it's a bigger project, because the rules differ
depepending on which level the label appears (rules for top-level names are
stricter), and this patch takes the minimalistic approach and only changes
behaviour for /etc/hosts.
Escape syntax is also disallowed in /etc/hosts, even if the resulting character
would be allowed. Other tools that parse /etc/hosts do not support this, and
there is no need to use it because no allowed characters benefit from escaping.
2018-11-21 22:58:13 +01:00
r = dns_name_normalize ( dns_resource_key_name ( canonical - > key ) , 0 , & normalized ) ;
2016-02-16 14:17:53 +01:00
if ( r < 0 )
goto finish ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
/* Return the precise spelling and uppercasing and CNAME target reported by the server */
r = sd_bus_message_append (
reply , " st " ,
2016-02-16 14:17:53 +01:00
normalized ,
2020-11-10 18:06:19 +01:00
dns_query_reply_flags_make ( q ) ) ;
2014-07-16 22:50:41 +02:00
if ( r < 0 )
goto finish ;
2022-02-17 11:48:31 +01:00
q - > bus_request = sd_bus_message_unref ( q - > bus_request ) ;
2014-07-16 20:15:47 +02:00
r = sd_bus_send ( q - > manager - > bus , reply , NULL ) ;
2014-07-16 00:26:02 +02:00
finish :
2014-07-30 19:23:27 +02:00
if ( r < 0 ) {
2014-11-28 13:19:16 +01:00
log_error_errno ( r , " Failed to send hostname reply: %m " ) ;
2022-02-17 11:48:31 +01:00
( void ) reply_method_errnof ( q , r , NULL ) ;
2014-07-30 19:23:27 +02:00
}
2014-07-16 00:26:02 +02:00
}
2020-09-29 11:53:31 +02:00
static int validate_and_mangle_flags (
const char * name ,
uint64_t * flags ,
uint64_t ok ,
sd_bus_error * error ) {
2014-08-14 01:00:15 +02:00
assert ( flags ) ;
2020-08-16 14:36:20 +02:00
/* Checks that the client supplied interface index and flags parameter actually are valid and make
* sense in our method call context . Specifically :
*
* 1. Checks that the interface index is either 0 ( meaning * all * interfaces ) or positive
*
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
* 2. Only the protocols flags and a bunch of NO_XYZ flags are set , at most . Plus additional flags
* specific to our method , passed in the " ok " parameter .
2020-08-16 14:36:20 +02:00
*
* 3. If zero protocol flags are specified it is automatically turned into * all * protocols . This way
* clients can simply pass 0 as flags and all will work as it should . They can also use this so
* that clients don ' t have to know all the protocols resolved implements , but can just specify 0
* to mean " all supported protocols " .
*/
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
if ( * flags & ~ ( SD_RESOLVED_PROTOCOLS_ALL |
SD_RESOLVED_NO_CNAME |
SD_RESOLVED_NO_VALIDATE |
SD_RESOLVED_NO_SYNTHESIZE |
SD_RESOLVED_NO_CACHE |
SD_RESOLVED_NO_ZONE |
SD_RESOLVED_NO_TRUST_ANCHOR |
SD_RESOLVED_NO_NETWORK |
2023-06-08 18:42:11 +05:30
SD_RESOLVED_NO_STALE |
2024-03-04 18:46:52 +01:00
SD_RESOLVED_RELAX_SINGLE_LABEL |
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
ok ) )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid flags parameter " ) ;
2014-08-14 01:00:15 +02:00
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( ( * flags & SD_RESOLVED_PROTOCOLS_ALL ) = = 0 ) /* If no protocol is enabled, enable all */
* flags | = SD_RESOLVED_PROTOCOLS_ALL ;
2014-08-14 01:00:15 +02:00
2020-09-29 11:53:31 +02:00
/* Imply SD_RESOLVED_NO_SEARCH if permitted and name is dot suffixed. */
if ( name & & FLAGS_SET ( ok , SD_RESOLVED_NO_SEARCH ) & & dns_name_dot_suffixed ( name ) > 0 )
* flags | = SD_RESOLVED_NO_SEARCH ;
2014-08-14 01:00:15 +02:00
return 0 ;
}
2016-02-13 20:26:30 +01:00
static int parse_as_address ( sd_bus_message * m , int ifindex , const char * hostname , int family , uint64_t flags ) {
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * reply = NULL ;
_cleanup_free_ char * canonical = NULL ;
union in_addr_union parsed ;
2016-06-14 23:37:16 +02:00
int r , ff , parsed_ifindex = 0 ;
2016-02-13 20:26:30 +01:00
/* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
* let ' s not attempt to look it up . */
2016-06-14 23:37:16 +02:00
r = in_addr_ifindex_from_string_auto ( hostname , & ff , & parsed , & parsed_ifindex ) ;
2016-02-13 20:26:30 +01:00
if ( r < 0 ) /* not an address */
return 0 ;
if ( family ! = AF_UNSPEC & & ff ! = family )
return sd_bus_reply_method_errorf ( m , BUS_ERROR_NO_SUCH_RR , " The specified address is not of the requested family. " ) ;
2016-06-14 23:37:16 +02:00
if ( ifindex > 0 & & parsed_ifindex > 0 & & parsed_ifindex ! = ifindex )
return sd_bus_reply_method_errorf ( m , BUS_ERROR_NO_SUCH_RR , " The specified address interface index does not match requested interface. " ) ;
if ( parsed_ifindex > 0 )
ifindex = parsed_ifindex ;
2016-02-13 20:26:30 +01:00
r = sd_bus_message_new_method_return ( m , & reply ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_open_container ( reply , ' a ' , " (iiay) " ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_open_container ( reply , ' r ' , " iiay " ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_append ( reply , " ii " , ifindex , ff ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_append_array ( reply , ' y ' , & parsed , FAMILY_ADDRESS_SIZE ( ff ) ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
return r ;
/* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
* look - up . However , we reformat it to make sure it ' s in a truly canonical form ( i . e . on IPv6 the inner
* omissions are always done the same way ) . */
2016-06-14 23:37:16 +02:00
r = in_addr_ifindex_to_string ( ff , & parsed , ifindex , & canonical ) ;
2016-02-13 20:26:30 +01:00
if ( r < 0 )
return r ;
r = sd_bus_message_append ( reply , " st " , canonical ,
2020-11-10 23:34:40 +01:00
SD_RESOLVED_FLAGS_MAKE ( dns_synthesize_protocol ( flags ) , ff , true , true ) |
SD_RESOLVED_SYNTHETIC ) ;
2016-02-13 20:26:30 +01:00
if ( r < 0 )
return r ;
return sd_bus_send ( sd_bus_message_get_bus ( m ) , reply , NULL ) ;
}
2020-11-09 22:20:16 +01:00
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 ) ;
}
2015-04-29 18:35:10 +02:00
static int bus_method_resolve_hostname ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
_cleanup_ ( dns_question_unrefp ) DnsQuestion * question_idna = NULL , * question_utf8 = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = NULL ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2014-07-16 00:26:02 +02:00
const char * hostname ;
2014-08-14 01:00:15 +02:00
int family , ifindex ;
uint64_t flags ;
2014-07-16 00:26:02 +02:00
int r ;
assert ( message ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
assert_cc ( sizeof ( int ) = = sizeof ( int32_t ) ) ;
2014-08-14 01:00:15 +02:00
r = sd_bus_message_read ( message , " isit " , & ifindex , & hostname , & family , & flags ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
2020-09-29 11:53:31 +02:00
if ( ifindex < 0 )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid interface index " ) ;
2020-09-29 11:53:31 +02:00
2014-07-16 00:26:02 +02:00
if ( ! IN_SET ( family , AF_INET , AF_INET6 , AF_UNSPEC ) )
2014-07-18 16:09:30 +02:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Unknown address family %i " , family ) ;
2014-07-16 00:26:02 +02:00
2020-09-29 11:53:31 +02:00
r = validate_and_mangle_flags ( hostname , & flags , SD_RESOLVED_NO_SEARCH , error ) ;
2014-07-31 19:53:59 +02:00
if ( r < 0 )
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return r ;
2014-07-16 00:26:02 +02:00
2016-02-13 20:26:30 +01:00
r = parse_as_address ( message , ifindex , hostname , family , flags ) ;
if ( r ! = 0 )
return r ;
r = dns_name_is_valid ( hostname ) ;
2014-08-14 01:00:15 +02:00
if ( r < 0 )
return r ;
2016-02-13 20:26:30 +01:00
if ( r = = 0 )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid hostname '%s' " , hostname ) ;
2014-08-14 01:00:15 +02:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_new_address ( & question_utf8 , family , hostname , false ) ;
if ( r < 0 )
return r ;
r = dns_question_new_address ( & question_idna , family , hostname , true ) ;
2017-07-11 04:42:21 -04:00
if ( r < 0 & & r ! = - EALREADY )
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return r ;
2014-07-16 00:26:02 +02:00
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " hostname resolution " ) ;
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
r = dns_query_new ( m , & q , question_utf8 , question_idna ? : question_utf8 , NULL , ifindex , flags ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
2020-08-16 11:29:55 +02:00
q - > bus_request = sd_bus_message_ref ( message ) ;
2014-07-16 00:26:02 +02:00
q - > request_family = family ;
q - > complete = bus_method_resolve_hostname_complete ;
2015-04-29 19:10:09 +02:00
r = dns_query_bus_track ( q , message ) ;
2014-08-06 16:32:55 +02:00
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
2014-08-06 16:32:55 +02:00
2014-07-17 19:38:37 +02:00
r = dns_query_go ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
2014-07-16 00:26:02 +02:00
2022-02-05 22:04:42 +09:00
TAKE_PTR ( q ) ;
2014-07-16 00:26:02 +02:00
return 1 ;
}
2022-02-05 22:04:42 +09:00
static void bus_method_resolve_address_complete ( DnsQuery * query ) {
tree-wide: expose "p"-suffix unref calls in public APIs to make gcc cleanup easy
GLIB has recently started to officially support the gcc cleanup
attribute in its public API, hence let's do the same for our APIs.
With this patch we'll define an xyz_unrefp() call for each public
xyz_unref() call, to make it easy to use inside a
__attribute__((cleanup())) expression. Then, all code is ported over to
make use of this.
The new calls are also documented in the man pages, with examples how to
use them (well, I only added docs where the _unref() call itself already
had docs, and the examples, only cover sd_bus_unrefp() and
sd_event_unrefp()).
This also renames sd_lldp_free() to sd_lldp_unref(), since that's how we
tend to call our destructors these days.
Note that this defines no public macro that wraps gcc's attribute and
makes it easier to use. While I think it's our duty in the library to
make our stuff easy to use, I figure it's not our duty to make gcc's own
features easy to use on its own. Most likely, client code which wants to
make use of this should define its own:
#define _cleanup_(function) __attribute__((cleanup(function)))
Or similar, to make the gcc feature easier to use.
Making this logic public has the benefit that we can remove three header
files whose only purpose was to define these functions internally.
See #2008.
2015-11-27 19:13:45 +01:00
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * reply = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = query ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DnsQuestion * question ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
DnsResourceRecord * rr ;
unsigned added = 0 ;
int ifindex , r ;
2014-07-16 00:26:02 +02:00
assert ( q ) ;
2014-07-31 17:46:40 +02:00
if ( q - > state ! = DNS_TRANSACTION_SUCCESS ) {
2014-07-16 20:15:47 +02:00
r = reply_query_state ( q ) ;
goto finish ;
}
2014-07-16 00:26:02 +02:00
2021-03-25 11:43:52 +01:00
r = dns_query_process_cname_many ( q ) ;
2015-11-26 03:58:08 +01:00
if ( r = = - ELOOP ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_CNAME_LOOP , " CNAME loop detected, or CNAME resolving disabled on '%s' " , dns_query_string ( q ) ) ;
2015-11-26 03:58:08 +01:00
goto finish ;
}
if ( r < 0 )
goto finish ;
2022-02-05 22:04:42 +09:00
if ( r = = DNS_QUERY_CNAME ) {
/* This was a cname, and the query was restarted. */
TAKE_PTR ( q ) ;
2015-11-26 03:58:08 +01:00
return ;
2022-02-05 22:04:42 +09:00
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2020-08-16 11:29:55 +02:00
r = sd_bus_message_new_method_return ( q - > bus_request , & reply ) ;
2014-07-16 20:15:47 +02:00
if ( r < 0 )
goto finish ;
2014-07-16 00:26:02 +02:00
2015-08-17 23:54:08 +02:00
r = sd_bus_message_open_container ( reply , ' a ' , " (is) " ) ;
2014-07-16 20:15:47 +02:00
if ( r < 0 )
goto finish ;
2014-07-16 00:26:02 +02:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
question = dns_query_question_for_protocol ( q , q - > answer_protocol ) ;
2014-07-16 00:26:02 +02:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DNS_ANSWER_FOREACH_IFINDEX ( rr , ifindex , q - > answer ) {
2016-02-16 14:17:53 +01:00
_cleanup_free_ char * normalized = NULL ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_matches_rr ( question , rr , NULL ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 )
continue ;
2014-07-16 00:26:02 +02:00
resolve: reject host names with leading or trailing dashes in /etc/hosts
https://tools.ietf.org/html/rfc1035#section-2.3.1 says (approximately)
that only letters, numbers, and non-leading non-trailing dashes are allowed
(for entries with A/AAAA records). We set no restrictions.
hosts(5) says:
> Host names may contain only alphanumeric characters, minus signs ("-"), and
> periods ("."). They must begin with an alphabetic character and end with an
> alphanumeric character.
nss-files follows those rules, and will ignore names in /etc/hosts that do not
follow this rule.
Let's follow the documented rules for /etc/hosts. In particular, this makes us
consitent with nss-files, reducing surprises for the user.
I'm pretty sure we should apply stricter filtering to names received over DNS
and LLMNR and MDNS, but it's a bigger project, because the rules differ
depepending on which level the label appears (rules for top-level names are
stricter), and this patch takes the minimalistic approach and only changes
behaviour for /etc/hosts.
Escape syntax is also disallowed in /etc/hosts, even if the resulting character
would be allowed. Other tools that parse /etc/hosts do not support this, and
there is no need to use it because no allowed characters benefit from escaping.
2018-11-21 22:58:13 +01:00
r = dns_name_normalize ( rr - > ptr . name , 0 , & normalized ) ;
2016-02-16 14:17:53 +01:00
if ( r < 0 )
goto finish ;
r = sd_bus_message_append ( reply , " (is) " , ifindex , normalized ) ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( r < 0 )
goto finish ;
2016-02-22 20:32:04 -08:00
added + + ;
2014-07-16 20:15:47 +02:00
}
2014-07-16 00:26:02 +02:00
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( added < = 0 ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_RR ,
2022-06-03 11:24:02 +02:00
" Address %s does not have any RR of requested type " ,
IN_ADDR_TO_STRING ( q - > request_family , & q - > request_address ) ) ;
2014-07-16 20:15:47 +02:00
goto finish ;
2014-07-16 00:26:02 +02:00
}
2014-07-16 20:15:47 +02:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
goto finish ;
2014-07-16 00:26:02 +02:00
2020-11-10 18:06:19 +01:00
r = sd_bus_message_append ( reply , " t " , dns_query_reply_flags_make ( q ) ) ;
2014-08-14 01:00:15 +02:00
if ( r < 0 )
goto finish ;
2022-02-17 11:48:31 +01:00
q - > bus_request = sd_bus_message_unref ( q - > bus_request ) ;
2014-07-16 20:15:47 +02:00
r = sd_bus_send ( q - > manager - > bus , reply , NULL ) ;
2014-07-16 00:26:02 +02:00
finish :
2014-07-30 19:23:27 +02:00
if ( r < 0 ) {
2014-11-28 13:19:16 +01:00
log_error_errno ( r , " Failed to send address reply: %m " ) ;
2022-02-17 11:48:31 +01:00
( void ) reply_method_errnof ( q , r , NULL ) ;
2014-07-30 19:23:27 +02:00
}
2014-07-16 00:26:02 +02:00
}
2015-04-29 18:35:10 +02:00
static int bus_method_resolve_address ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2014-07-22 21:48:41 +02:00
_cleanup_ ( dns_question_unrefp ) DnsQuestion * question = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = NULL ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2020-07-19 12:32:21 +09:00
union in_addr_union a ;
2014-07-22 21:48:41 +02:00
int family , ifindex ;
2014-08-14 01:00:15 +02:00
uint64_t flags ;
2014-07-16 00:26:02 +02:00
int r ;
assert ( message ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
assert_cc ( sizeof ( int ) = = sizeof ( int32_t ) ) ;
2020-07-19 12:32:21 +09:00
r = sd_bus_message_read ( message , " i " , & ifindex ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
2020-07-19 12:32:21 +09:00
r = bus_message_read_in_addr_auto ( message , error , & family , & a ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
2014-08-14 01:00:15 +02:00
r = sd_bus_message_read ( message , " t " , & flags ) ;
if ( r < 0 )
return r ;
2020-09-29 11:53:31 +02:00
if ( ifindex < 0 )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid interface index " ) ;
2020-09-29 11:53:31 +02:00
r = validate_and_mangle_flags ( NULL , & flags , 0 , error ) ;
2014-07-22 21:48:41 +02:00
if ( r < 0 )
return r ;
2020-07-19 12:32:21 +09:00
r = dns_question_new_reverse ( & question , family , & a ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " address resolution " ) ;
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
r = dns_query_new ( m , & q , question , question , NULL , ifindex , flags | SD_RESOLVED_NO_SEARCH ) ;
2014-07-16 00:26:02 +02:00
if ( r < 0 )
return r ;
2020-08-16 11:29:55 +02:00
q - > bus_request = sd_bus_message_ref ( message ) ;
2014-07-16 00:26:02 +02:00
q - > request_family = family ;
2020-07-19 12:32:21 +09:00
q - > request_address = a ;
2014-07-16 00:26:02 +02:00
q - > complete = bus_method_resolve_address_complete ;
2015-04-29 19:10:09 +02:00
r = dns_query_bus_track ( q , message ) ;
2014-08-06 16:32:55 +02:00
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
2014-08-06 16:32:55 +02:00
2014-07-17 19:38:37 +02:00
r = dns_query_go ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
2014-07-16 00:26:02 +02:00
2022-02-05 22:04:42 +09:00
TAKE_PTR ( q ) ;
2014-07-16 00:26:02 +02:00
return 1 ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
static int bus_message_append_rr ( sd_bus_message * m , DnsResourceRecord * rr , int ifindex ) {
int r ;
assert ( m ) ;
assert ( rr ) ;
r = sd_bus_message_open_container ( m , ' r ' , " iqqay " ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_append ( m , " iqq " ,
ifindex ,
rr - > key - > class ,
rr - > key - > type ) ;
if ( r < 0 )
return r ;
2015-12-02 21:05:21 +01:00
r = dns_resource_record_to_wire_format ( rr , false ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
2015-12-02 21:05:21 +01:00
r = sd_bus_message_append_array ( m , ' y ' , rr - > wire_format , rr - > wire_format_size ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
return sd_bus_message_close_container ( m ) ;
2014-07-16 00:26:02 +02:00
}
2022-02-05 22:04:42 +09:00
static void bus_method_resolve_record_complete ( DnsQuery * query ) {
tree-wide: expose "p"-suffix unref calls in public APIs to make gcc cleanup easy
GLIB has recently started to officially support the gcc cleanup
attribute in its public API, hence let's do the same for our APIs.
With this patch we'll define an xyz_unrefp() call for each public
xyz_unref() call, to make it easy to use inside a
__attribute__((cleanup())) expression. Then, all code is ported over to
make use of this.
The new calls are also documented in the man pages, with examples how to
use them (well, I only added docs where the _unref() call itself already
had docs, and the examples, only cover sd_bus_unrefp() and
sd_event_unrefp()).
This also renames sd_lldp_free() to sd_lldp_unref(), since that's how we
tend to call our destructors these days.
Note that this defines no public macro that wraps gcc's attribute and
makes it easier to use. While I think it's our duty in the library to
make our stuff easy to use, I figure it's not our duty to make gcc's own
features easy to use on its own. Most likely, client code which wants to
make use of this should define its own:
#define _cleanup_(function) __attribute__((cleanup(function)))
Or similar, to make the gcc feature easier to use.
Making this logic public has the benefit that we can remove three header
files whose only purpose was to define these functions internally.
See #2008.
2015-11-27 19:13:45 +01:00
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * reply = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = query ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DnsResourceRecord * rr ;
DnsQuestion * question ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
unsigned added = 0 ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
int ifindex ;
2014-07-30 19:23:27 +02:00
int r ;
assert ( q ) ;
2014-07-31 17:46:40 +02:00
if ( q - > state ! = DNS_TRANSACTION_SUCCESS ) {
2014-07-30 19:23:27 +02:00
r = reply_query_state ( q ) ;
goto finish ;
}
2021-03-25 11:43:52 +01:00
r = dns_query_process_cname_many ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r = = - ELOOP ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_CNAME_LOOP , " CNAME loop detected, or CNAME resolving disabled on '%s' " , dns_query_string ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
}
if ( r < 0 )
goto finish ;
2022-02-05 22:04:42 +09:00
if ( r = = DNS_QUERY_CNAME ) {
/* This was a cname, and the query was restarted. */
TAKE_PTR ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
2022-02-05 22:04:42 +09:00
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2020-08-16 11:29:55 +02:00
r = sd_bus_message_new_method_return ( q - > bus_request , & reply ) ;
2014-07-30 19:23:27 +02:00
if ( r < 0 )
goto finish ;
2015-08-17 23:54:08 +02:00
r = sd_bus_message_open_container ( reply , ' a ' , " (iqqay) " ) ;
2014-07-30 19:23:27 +02:00
if ( r < 0 )
goto finish ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
question = dns_query_question_for_protocol ( q , q - > answer_protocol ) ;
2014-07-30 19:23:27 +02:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DNS_ANSWER_FOREACH_IFINDEX ( rr , ifindex , q - > answer ) {
r = dns_question_matches_rr ( question , rr , NULL ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 )
continue ;
2014-07-30 19:23:27 +02:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = bus_message_append_rr ( reply , rr , ifindex ) ;
if ( r < 0 )
goto finish ;
2014-07-30 19:23:27 +02:00
2016-02-22 20:32:04 -08:00
added + + ;
2014-07-30 19:23:27 +02:00
}
if ( added < = 0 ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_RR , " Name '%s' does not have any RR of the requested type " , dns_query_string ( q ) ) ;
2014-07-30 19:23:27 +02:00
goto finish ;
}
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
goto finish ;
2020-11-10 18:06:19 +01:00
r = sd_bus_message_append ( reply , " t " , dns_query_reply_flags_make ( q ) ) ;
2014-08-14 01:00:15 +02:00
if ( r < 0 )
goto finish ;
2022-02-17 11:48:31 +01:00
q - > bus_request = sd_bus_message_unref ( q - > bus_request ) ;
2014-07-30 19:23:27 +02:00
r = sd_bus_send ( q - > manager - > bus , reply , NULL ) ;
finish :
if ( r < 0 ) {
2014-11-28 13:19:16 +01:00
log_error_errno ( r , " Failed to send record reply: %m " ) ;
2022-02-17 11:48:31 +01:00
( void ) reply_method_errnof ( q , r , NULL ) ;
2014-07-30 19:23:27 +02:00
}
}
2015-04-29 18:35:10 +02:00
static int bus_method_resolve_record ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2014-07-30 19:23:27 +02:00
_cleanup_ ( dns_resource_key_unrefp ) DnsResourceKey * key = NULL ;
_cleanup_ ( dns_question_unrefp ) DnsQuestion * question = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = NULL ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2014-07-30 19:23:27 +02:00
uint16_t class , type ;
const char * name ;
2014-08-14 01:00:15 +02:00
int r , ifindex ;
uint64_t flags ;
2014-07-30 19:23:27 +02:00
assert ( message ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
assert_cc ( sizeof ( int ) = = sizeof ( int32_t ) ) ;
2014-08-14 01:00:15 +02:00
r = sd_bus_message_read ( message , " isqqt " , & ifindex , & name , & class , & type , & flags ) ;
2014-07-30 19:23:27 +02:00
if ( r < 0 )
return r ;
2020-09-29 11:53:31 +02:00
if ( ifindex < 0 )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid interface index " ) ;
2020-09-29 11:53:31 +02:00
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = dns_name_is_valid ( name ) ;
2014-07-31 19:53:59 +02:00
if ( r < 0 )
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return r ;
if ( r = = 0 )
2014-07-31 19:53:59 +02:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid name '%s' " , name ) ;
2015-12-10 15:01:04 +01:00
if ( ! dns_type_is_valid_query ( type ) )
2016-01-11 20:19:10 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Specified resource record type % " PRIu16 " may not be used in a query. " , type ) ;
2023-12-18 16:38:44 -07:00
if ( dns_type_is_zone_transfer ( type ) )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Zone transfers not permitted via this programming interface. " ) ;
2016-01-11 20:05:29 +01:00
if ( dns_type_is_obsolete ( type ) )
2016-01-11 20:19:10 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Specified DNS resource record type % " PRIu16 " is obsolete. " , type ) ;
2015-12-10 15:01:04 +01:00
2020-09-29 11:53:31 +02:00
r = validate_and_mangle_flags ( name , & flags , 0 , error ) ;
2014-08-14 01:00:15 +02:00
if ( r < 0 )
return r ;
2014-07-30 19:23:27 +02:00
question = dns_question_new ( 1 ) ;
if ( ! question )
return - ENOMEM ;
key = dns_resource_key_new ( class , type , name ) ;
if ( ! key )
return - ENOMEM ;
2021-02-20 17:32:24 +03:00
r = dns_question_add ( question , key , 0 ) ;
2014-07-30 19:23:27 +02:00
if ( r < 0 )
return r ;
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " resource record resolution " ) ;
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
/* 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 . */
r = dns_query_new ( m , & q , question , question , NULL , ifindex , flags | SD_RESOLVED_NO_SEARCH | SD_RESOLVED_CLAMP_TTL ) ;
2014-07-30 19:23:27 +02:00
if ( r < 0 )
return r ;
2020-08-16 11:29:55 +02:00
q - > bus_request = sd_bus_message_ref ( message ) ;
2014-07-30 19:23:27 +02:00
q - > complete = bus_method_resolve_record_complete ;
2015-04-29 19:10:09 +02:00
r = dns_query_bus_track ( q , message ) ;
2014-08-06 16:32:55 +02:00
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
2014-08-06 16:32:55 +02:00
2014-07-30 19:23:27 +02:00
r = dns_query_go ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2022-02-05 22:04:42 +09:00
TAKE_PTR ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return 1 ;
}
static int append_srv ( DnsQuery * q , sd_bus_message * reply , DnsResourceRecord * rr ) {
_cleanup_ ( dns_resource_record_unrefp ) DnsResourceRecord * canonical = NULL ;
2016-02-16 14:17:53 +01:00
_cleanup_free_ char * normalized = NULL ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
int r ;
assert ( q ) ;
assert ( reply ) ;
assert ( rr ) ;
assert ( rr - > key ) ;
if ( rr - > key - > type ! = DNS_TYPE_SRV )
return 0 ;
if ( ( q - > flags & SD_RESOLVED_NO_ADDRESS ) = = 0 ) {
/* First, let's see if we could find an appropriate A or AAAA
* record for the SRV record */
LIST_FOREACH ( auxiliary_queries , aux , q - > auxiliary_queries ) {
DnsResourceRecord * zz ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DnsQuestion * question ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( aux - > state ! = DNS_TRANSACTION_SUCCESS )
continue ;
if ( aux - > auxiliary_result ! = 0 )
continue ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
question = dns_query_question_for_protocol ( aux , aux - > answer_protocol ) ;
r = dns_name_equal ( dns_question_first_name ( question ) , rr - > srv . name ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
if ( r = = 0 )
continue ;
DNS_ANSWER_FOREACH ( zz , aux - > answer ) {
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_matches_rr ( question , zz , NULL ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
if ( r = = 0 )
continue ;
canonical = dns_resource_record_ref ( zz ) ;
break ;
}
if ( canonical )
break ;
}
/* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
if ( ! canonical )
return 0 ;
}
r = sd_bus_message_open_container ( reply , ' r ' , " qqqsa(iiay)s " ) ;
if ( r < 0 )
return r ;
resolve: reject host names with leading or trailing dashes in /etc/hosts
https://tools.ietf.org/html/rfc1035#section-2.3.1 says (approximately)
that only letters, numbers, and non-leading non-trailing dashes are allowed
(for entries with A/AAAA records). We set no restrictions.
hosts(5) says:
> Host names may contain only alphanumeric characters, minus signs ("-"), and
> periods ("."). They must begin with an alphabetic character and end with an
> alphanumeric character.
nss-files follows those rules, and will ignore names in /etc/hosts that do not
follow this rule.
Let's follow the documented rules for /etc/hosts. In particular, this makes us
consitent with nss-files, reducing surprises for the user.
I'm pretty sure we should apply stricter filtering to names received over DNS
and LLMNR and MDNS, but it's a bigger project, because the rules differ
depepending on which level the label appears (rules for top-level names are
stricter), and this patch takes the minimalistic approach and only changes
behaviour for /etc/hosts.
Escape syntax is also disallowed in /etc/hosts, even if the resulting character
would be allowed. Other tools that parse /etc/hosts do not support this, and
there is no need to use it because no allowed characters benefit from escaping.
2018-11-21 22:58:13 +01:00
r = dns_name_normalize ( rr - > srv . name , 0 , & normalized ) ;
2016-02-16 14:17:53 +01:00
if ( r < 0 )
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = sd_bus_message_append (
reply ,
" qqqs " ,
2016-02-16 14:17:53 +01:00
rr - > srv . priority , rr - > srv . weight , rr - > srv . port , normalized ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
r = sd_bus_message_open_container ( reply , ' a ' , " (iiay) " ) ;
if ( r < 0 )
return r ;
if ( ( q - > flags & SD_RESOLVED_NO_ADDRESS ) = = 0 ) {
LIST_FOREACH ( auxiliary_queries , aux , q - > auxiliary_queries ) {
DnsResourceRecord * zz ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DnsQuestion * question ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
int ifindex ;
if ( aux - > state ! = DNS_TRANSACTION_SUCCESS )
continue ;
if ( aux - > auxiliary_result ! = 0 )
continue ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
question = dns_query_question_for_protocol ( aux , aux - > answer_protocol ) ;
r = dns_name_equal ( dns_question_first_name ( question ) , rr - > srv . name ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
if ( r = = 0 )
continue ;
DNS_ANSWER_FOREACH_IFINDEX ( zz , ifindex , aux - > answer ) {
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_matches_rr ( question , zz , NULL ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
if ( r = = 0 )
continue ;
2021-02-04 16:05:05 +01:00
r = append_address ( reply , zz , ifindex ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
}
}
}
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
return r ;
2016-02-16 14:17:53 +01:00
if ( canonical ) {
normalized = mfree ( normalized ) ;
resolve: reject host names with leading or trailing dashes in /etc/hosts
https://tools.ietf.org/html/rfc1035#section-2.3.1 says (approximately)
that only letters, numbers, and non-leading non-trailing dashes are allowed
(for entries with A/AAAA records). We set no restrictions.
hosts(5) says:
> Host names may contain only alphanumeric characters, minus signs ("-"), and
> periods ("."). They must begin with an alphabetic character and end with an
> alphanumeric character.
nss-files follows those rules, and will ignore names in /etc/hosts that do not
follow this rule.
Let's follow the documented rules for /etc/hosts. In particular, this makes us
consitent with nss-files, reducing surprises for the user.
I'm pretty sure we should apply stricter filtering to names received over DNS
and LLMNR and MDNS, but it's a bigger project, because the rules differ
depepending on which level the label appears (rules for top-level names are
stricter), and this patch takes the minimalistic approach and only changes
behaviour for /etc/hosts.
Escape syntax is also disallowed in /etc/hosts, even if the resulting character
would be allowed. Other tools that parse /etc/hosts do not support this, and
there is no need to use it because no allowed characters benefit from escaping.
2018-11-21 22:58:13 +01:00
r = dns_name_normalize ( dns_resource_key_name ( canonical - > key ) , 0 , & normalized ) ;
2016-02-16 14:17:53 +01:00
if ( r < 0 )
return r ;
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
/* Note that above we appended the hostname as encoded in the
* SRV , and here the canonical hostname this maps to . */
2016-02-16 14:17:53 +01:00
r = sd_bus_message_append ( reply , " s " , normalized ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
return r ;
return 1 ;
}
static int append_txt ( sd_bus_message * reply , DnsResourceRecord * rr ) {
int r ;
assert ( reply ) ;
assert ( rr ) ;
assert ( rr - > key ) ;
if ( rr - > key - > type ! = DNS_TYPE_TXT )
return 0 ;
LIST_FOREACH ( items , i , rr - > txt . items ) {
if ( i - > length < = 0 )
continue ;
r = sd_bus_message_append_array ( reply , ' y ' , i - > data , i - > length ) ;
if ( r < 0 )
return r ;
}
return 1 ;
}
2022-02-05 22:04:42 +09:00
static void resolve_service_all_complete ( DnsQuery * query ) {
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
_cleanup_ ( dns_resource_record_unrefp ) DnsResourceRecord * canonical = NULL ;
_cleanup_ ( sd_bus_message_unrefp ) sd_bus_message * reply = NULL ;
_cleanup_free_ char * name = NULL , * type = NULL , * domain = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = query ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DnsQuestion * question ;
DnsResourceRecord * rr ;
unsigned added = 0 ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
int r ;
assert ( q ) ;
2022-02-05 22:04:42 +09:00
if ( q - > block_all_complete > 0 ) {
TAKE_PTR ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
2022-02-05 22:04:42 +09:00
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( ( q - > flags & SD_RESOLVED_NO_ADDRESS ) = = 0 ) {
DnsQuery * bad = NULL ;
bool have_success = false ;
LIST_FOREACH ( auxiliary_queries , aux , q - > auxiliary_queries ) {
switch ( aux - > state ) {
case DNS_TRANSACTION_PENDING :
/* If an auxiliary query is still pending, let's wait */
2022-02-05 22:04:42 +09:00
TAKE_PTR ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
case DNS_TRANSACTION_SUCCESS :
if ( aux - > auxiliary_result = = 0 )
have_success = true ;
else
bad = aux ;
break ;
default :
bad = aux ;
break ;
}
}
if ( ! have_success ) {
/* We can only return one error, hence pick the last error we encountered */
assert ( bad ) ;
if ( bad - > state = = DNS_TRANSACTION_SUCCESS ) {
assert ( bad - > auxiliary_result ! = 0 ) ;
if ( bad - > auxiliary_result = = - ELOOP ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_CNAME_LOOP , " CNAME loop detected, or CNAME resolving disabled on '%s' " , dns_query_string ( bad ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
}
2021-11-22 14:37:54 +01:00
assert ( bad - > auxiliary_result < 0 ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = bad - > auxiliary_result ;
goto finish ;
}
r = reply_query_state ( bad ) ;
goto finish ;
}
}
2020-08-16 11:29:55 +02:00
r = sd_bus_message_new_method_return ( q - > bus_request , & reply ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
goto finish ;
r = sd_bus_message_open_container ( reply , ' a ' , " (qqqsa(iiay)s) " ) ;
if ( r < 0 )
goto finish ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
question = dns_query_question_for_protocol ( q , q - > answer_protocol ) ;
2020-08-16 14:36:20 +02:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DNS_ANSWER_FOREACH ( rr , q - > answer ) {
r = dns_question_matches_rr ( question , rr , NULL ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 )
continue ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = append_srv ( q , reply , rr ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 ) /* not an SRV record */
continue ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( ! canonical )
canonical = dns_resource_record_ref ( rr ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
added + + ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
if ( added < = 0 ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_RR , " '%s' does not have any RR of the requested type " , dns_query_string ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
}
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
goto finish ;
r = sd_bus_message_open_container ( reply , ' a ' , " ay " ) ;
if ( r < 0 )
goto finish ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DNS_ANSWER_FOREACH ( rr , q - > answer ) {
r = dns_question_matches_rr ( question , rr , NULL ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 )
continue ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = append_txt ( reply , rr ) ;
if ( r < 0 )
goto finish ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
goto finish ;
assert ( canonical ) ;
2016-02-13 14:54:15 -05:00
r = dns_service_split ( dns_resource_key_name ( canonical - > key ) , & name , & type , & domain ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
goto finish ;
2024-08-05 10:46:41 +09:00
if ( isempty ( type ) ) {
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_SERVICE , " '%s' does not provide valid service " , dns_query_string ( q ) ) ;
goto finish ;
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = sd_bus_message_append (
reply ,
" ssst " ,
name , type , domain ,
2020-11-10 18:06:19 +01:00
dns_query_reply_flags_make ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
goto finish ;
2022-02-17 11:48:31 +01:00
q - > bus_request = sd_bus_message_unref ( q - > bus_request ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = sd_bus_send ( q - > manager - > bus , reply , NULL ) ;
finish :
if ( r < 0 ) {
log_error_errno ( r , " Failed to send service reply: %m " ) ;
2022-02-17 11:48:31 +01:00
( void ) reply_method_errnof ( q , r , NULL ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
}
static void resolve_service_hostname_complete ( DnsQuery * q ) {
int r ;
assert ( q ) ;
assert ( q - > auxiliary_for ) ;
if ( q - > state ! = DNS_TRANSACTION_SUCCESS ) {
resolve_service_all_complete ( q - > auxiliary_for ) ;
return ;
}
2021-03-25 11:43:52 +01:00
r = dns_query_process_cname_many ( q ) ;
if ( r = = DNS_QUERY_CNAME ) /* This was a cname, and the query was restarted. */
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
/* This auxiliary lookup is finished or failed, let's see if all are finished now. */
2021-11-22 14:37:54 +01:00
q - > auxiliary_result = r < 0 ? r : 0 ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolve_service_all_complete ( q - > auxiliary_for ) ;
}
static int resolve_service_hostname ( DnsQuery * q , DnsResourceRecord * rr , int ifindex ) {
_cleanup_ ( dns_question_unrefp ) DnsQuestion * question = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * aux = NULL ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
int r ;
assert ( q ) ;
assert ( rr ) ;
assert ( rr - > key ) ;
assert ( rr - > key - > type = = DNS_TYPE_SRV ) ;
/* OK, we found an SRV record for the service. Let's resolve
* the hostname included in it */
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_new_address ( & question , q - > request_family , rr - > srv . name , false ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
r = dns_query_new ( q - > manager , & aux , question , question , NULL , ifindex , q - > flags | SD_RESOLVED_NO_SEARCH ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
aux - > request_family = q - > request_family ;
aux - > complete = resolve_service_hostname_complete ;
r = dns_query_make_auxiliary ( aux , q ) ;
2022-02-05 22:04:42 +09:00
if ( r = = - EAGAIN )
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
/* Too many auxiliary lookups? If so, don't complain,
* let ' s just not add this one , we already have more
* than enough */
return 0 ;
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
/* Note that auxiliary queries do not track the original bus
* client , only the primary request does that . */
r = dns_query_go ( aux ) ;
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2022-02-05 22:04:42 +09:00
TAKE_PTR ( aux ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return 1 ;
}
2022-02-05 22:04:42 +09:00
static void bus_method_resolve_service_complete ( DnsQuery * query ) {
_cleanup_ ( dns_query_freep ) DnsQuery * q = query ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
bool has_root_domain = false ;
DnsResourceRecord * rr ;
DnsQuestion * question ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
unsigned found = 0 ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
int ifindex , r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
assert ( q ) ;
if ( q - > state ! = DNS_TRANSACTION_SUCCESS ) {
r = reply_query_state ( q ) ;
goto finish ;
}
2021-03-25 11:43:52 +01:00
r = dns_query_process_cname_many ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r = = - ELOOP ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_CNAME_LOOP , " CNAME loop detected, or CNAME resolving disabled on '%s' " , dns_query_string ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
}
if ( r < 0 )
goto finish ;
2022-02-05 22:04:42 +09:00
if ( r = = DNS_QUERY_CNAME ) {
/* This was a cname, and the query was restarted. */
TAKE_PTR ( q ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
2022-02-05 22:04:42 +09:00
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
question = dns_query_question_for_protocol ( q , q - > answer_protocol ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
DNS_ANSWER_FOREACH_IFINDEX ( rr , ifindex , q - > answer ) {
r = dns_question_matches_rr ( question , rr , NULL ) ;
if ( r < 0 )
goto finish ;
if ( r = = 0 )
continue ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( rr - > key - > type ! = DNS_TYPE_SRV )
continue ;
2015-12-29 18:58:05 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( dns_name_is_root ( rr - > srv . name ) ) {
has_root_domain = true ;
continue ;
}
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( ( q - > flags & SD_RESOLVED_NO_ADDRESS ) = = 0 ) {
2016-02-22 20:32:04 -08:00
q - > block_all_complete + + ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = resolve_service_hostname ( q , rr , ifindex ) ;
2016-02-22 20:32:04 -08:00
q - > block_all_complete - - ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( r < 0 )
goto finish ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
2015-12-29 18:58:05 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
found + + ;
}
2015-12-29 18:58:05 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
if ( has_root_domain & & found < = 0 ) {
2022-02-17 11:48:31 +01:00
/* If there's exactly one SRV RR and it uses the root domain as hostname, then the service is
* explicitly not offered on the domain . Report this as a recognizable error . See RFC 2782 ,
* Section " Usage Rules " . */
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_SERVICE , " '%s' does not provide the requested service " , dns_query_string ( q ) ) ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
goto finish ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
if ( found < = 0 ) {
2022-02-17 11:48:31 +01:00
r = reply_method_errorf ( q , BUS_ERROR_NO_SUCH_RR , " '%s' does not have any RR of the requested type " , dns_query_string ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
goto finish ;
}
/* Maybe we are already finished? check now... */
2022-02-05 22:04:42 +09:00
resolve_service_all_complete ( TAKE_PTR ( q ) ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
return ;
finish :
2014-07-30 19:23:27 +02:00
if ( r < 0 ) {
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
log_error_errno ( r , " Failed to send service reply: %m " ) ;
2022-02-17 11:48:31 +01:00
( void ) reply_method_errnof ( q , r , NULL ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
}
}
static int bus_method_resolve_service ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
_cleanup_ ( dns_question_unrefp ) DnsQuestion * question_idna = NULL , * question_utf8 = NULL ;
2022-02-05 22:04:42 +09:00
_cleanup_ ( dns_query_freep ) DnsQuery * q = NULL ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
const char * name , * type , * domain ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
int family , ifindex ;
uint64_t flags ;
int r ;
assert ( message ) ;
assert_cc ( sizeof ( int ) = = sizeof ( int32_t ) ) ;
r = sd_bus_message_read ( message , " isssit " , & ifindex , & name , & type , & domain , & family , & flags ) ;
if ( r < 0 )
2014-07-30 19:23:27 +02:00
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2020-09-29 11:53:31 +02:00
if ( ifindex < 0 )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid interface index " ) ;
2020-09-29 11:53:31 +02:00
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( ! IN_SET ( family , AF_INET , AF_INET6 , AF_UNSPEC ) )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Unknown address family %i " , family ) ;
if ( isempty ( name ) )
name = NULL ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
else if ( ! dns_service_name_is_valid ( name ) )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid service name '%s' " , name ) ;
2014-07-30 19:23:27 +02:00
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( isempty ( type ) )
type = NULL ;
2015-11-25 21:15:07 +01:00
else if ( ! dns_srv_type_is_valid ( type ) )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid SRV service type '%s' " , type ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = dns_name_is_valid ( domain ) ;
if ( r < 0 )
return r ;
if ( r = = 0 )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid domain '%s' " , domain ) ;
if ( name & & ! type )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Service name cannot be specified without service type. " ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2020-09-29 11:53:31 +02:00
r = validate_and_mangle_flags ( name , & flags , SD_RESOLVED_NO_TXT | SD_RESOLVED_NO_ADDRESS , error ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_new_service ( & question_utf8 , name , type , domain , ! ( flags & SD_RESOLVED_NO_TXT ) , false ) ;
if ( r < 0 )
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.
Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.
With this change IDNA conversion is done only:
- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()
No IDNA encoding is done anymore:
- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name
Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 20:31:39 +01:00
r = dns_question_new_service ( & question_idna , name , type , domain , ! ( flags & SD_RESOLVED_NO_TXT ) , true ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " service resolution " ) ;
resolved: add support for answering DNSSEC questions on the stub
This substantially beefs up the local DNS stub feature set in order to
allow local clients to do DNSSEC validation through the stub.
Previously we'd return NOTIMP if we'd get a DO or DO+CD lookup. With
this change we'll instead:
1. If we get DO+CD requests (i.e. DNSSEC with no local checking) we'll
proxy DNS queries and response mostly unmodified to/from upstream DNS
servers if possible (this is called "bypass" mode). We will patch in
new request IDs, (and patch them back out on reply), so that we can
sanely keep track of things. We'll also maintain a minimal local
cache for such lookups, always keeping the whole DNS packets in it
(if we reply from cache we'll patch the TTLs of all included RRs).
2. If we get DO requests without CD (i.e. DNSSEC with local checking)
we'll resolve and validate locally. In this mode we will not proxy
packets, but generate our own. We will however cache the combination
of answer RRs (along with their packet section assignments) we got
back in the cache, and use this information to generate reply packets
from the DNS stub.
In both cases: if we determine a lookup is to be answered from LLMNR or
mDNS we'll always revert to non-DNSSEC, non-proxy operation as before.
Answers will lack the DO bit then, since the data cannot be validated
via DNSSEC by the clients.
To make this logic more debuggable, this also adds query flags for
turning off RR sources. i.e. cache/network/zone/trust anchor/local
synthesis may now be disabled individually for each lookup.
The cache is substantially updated to make all this work: in addition to
caching simple RRs for lookup RR keys, we'll now cache the whole packets
and the whole combination of RRs, so that we can answer DO and DO+CD
replies sensibly according to the rules described above. This sounds
wasteful, but given that the
DnsResourceRecord/DnsResourceKey/DnsAnswer/DnsPacket
objects are all ref-counted and we try to merge references the actual
additional memory used should be limited (but this might be something to
optimize further later on).
To implement classic RR key lookups and new-style packet proxy lookups
(i.e. the ones necessary for DO+CD packet proxying, as described above)
DnsTransaction and DnsQuery objects now always maintain either a
DnsResourceKey/DnsQuestion as lookup key or a DnsPacket for "bypass"
mode.
Fixes: #4621 #17218
2020-11-05 11:01:52 +01:00
r = dns_query_new ( m , & q , question_utf8 , question_idna , NULL , ifindex , flags | SD_RESOLVED_NO_SEARCH ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
if ( r < 0 )
return r ;
2020-08-16 11:29:55 +02:00
q - > bus_request = sd_bus_message_ref ( message ) ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
q - > request_family = family ;
q - > complete = bus_method_resolve_service_complete ;
r = dns_query_bus_track ( q , message ) ;
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
r = dns_query_go ( q ) ;
if ( r < 0 )
2022-02-05 22:04:42 +09:00
return r ;
resolved: add ResolveService() bus call for resolving SRV and DNS-SD services
This also adds client-side support for this to systemd-resolve-host.
Note that the ResolveService() API can deal both with DNS-SD service
(consisting of service name, type and domain), as well as classic SRV
services (consisting just of a type and a domain), all exposed in the
same call.
This patch also reworks CNAME handling in order to reuse it between
hostname, RR and service lookups.
In contrast to Avahi and Bonjour, this new API will actually reolve the
A/AAAA RRs the SRV RRs point to in one go (unless this is explicitly
disabled). This normally comes for free, as these RRs are sent along
the SRV responses anyway, hence let's make use of that. This makes the
API considerably easier to use, as a single ResolveService() invocation
will return all necessary data to pick a server and connect() to it.
Note that this only implements the DNS-SD resolving step, it does not
implement DNS-SD browsing, as that makes sense primarily on mDNS, due to
its continuous nature.
2015-11-23 21:25:40 +01:00
2022-02-05 22:04:42 +09:00
TAKE_PTR ( q ) ;
2014-07-30 19:23:27 +02:00
return 1 ;
}
2023-01-04 16:32:51 +01:00
int bus_dns_server_append (
sd_bus_message * reply ,
DnsServer * s ,
bool with_ifindex , /* include "ifindex" field */
bool extended ) { /* also include port number and server name */
2015-11-24 22:49:15 +01:00
int r ;
assert ( reply ) ;
2018-05-01 15:58:42 +09:00
if ( ! s ) {
2020-07-03 21:03:51 +09:00
if ( with_ifindex ) {
if ( extended )
return sd_bus_message_append ( reply , " (iiayqs) " , 0, AF_UNSPEC, 0, 0, NULL) ;
else
return sd_bus_message_append ( reply , " (iiay) " , 0, AF_UNSPEC, 0) ;
} else {
if ( extended )
return sd_bus_message_append ( reply , " (iayqs) " , AF_UNSPEC, 0, 0, NULL) ;
else
return sd_bus_message_append ( reply , " (iay) " , AF_UNSPEC, 0) ;
}
2018-05-01 15:58:42 +09:00
}
2015-11-24 22:49:15 +01:00
2023-01-04 16:32:51 +01:00
r = sd_bus_message_open_container (
reply ,
' r ' ,
with_ifindex ? ( extended ? " iiayqs " : " iiay " ) :
( extended ? " iayqs " : " iay " ) ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
2016-01-19 18:32:42 +01:00
if ( with_ifindex ) {
2016-06-03 21:29:14 +02:00
r = sd_bus_message_append ( reply , " i " , dns_server_ifindex ( s ) ) ;
2016-01-19 18:32:42 +01:00
if ( r < 0 )
return r ;
}
r = sd_bus_message_append ( reply , " i " , s - > family ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
r = sd_bus_message_append_array ( reply , ' y ' , & s - > address , FAMILY_ADDRESS_SIZE ( s - > family ) ) ;
if ( r < 0 )
return r ;
2020-07-03 21:03:51 +09:00
if ( extended ) {
r = sd_bus_message_append ( reply , " q " , s - > port ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_append ( reply , " s " , s - > server_name ) ;
if ( r < 0 )
return r ;
}
2015-11-24 22:49:15 +01:00
return sd_bus_message_close_container ( reply ) ;
}
2020-07-03 21:03:51 +09:00
static int bus_property_get_dns_servers_internal (
2015-11-24 22:49:15 +01:00
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
2020-07-03 21:03:51 +09:00
sd_bus_error * error ,
bool extended ) {
2015-11-24 22:49:15 +01:00
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2015-11-24 22:49:15 +01:00
Link * l ;
int r ;
assert ( reply ) ;
2020-07-03 21:03:51 +09:00
r = sd_bus_message_open_container ( reply , ' a ' , extended ? " (iiayqs) " : " (iiay) " ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
LIST_FOREACH ( servers , s , m - > dns_servers ) {
2020-07-03 21:03:51 +09:00
r = bus_dns_server_append ( reply , s , true , extended ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
}
2020-09-08 11:58:29 +02:00
HASHMAP_FOREACH ( l , m - > links )
2015-11-24 22:49:15 +01:00
LIST_FOREACH ( servers , s , l - > dns_servers ) {
2020-07-03 21:03:51 +09:00
r = bus_dns_server_append ( reply , s , true , extended ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
}
2018-05-11 16:03:17 +09:00
return sd_bus_message_close_container ( reply ) ;
}
2020-07-03 21:03:51 +09:00
static int bus_property_get_dns_servers (
2018-05-11 16:03:17 +09:00
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
2020-07-03 21:03:51 +09:00
return bus_property_get_dns_servers_internal ( bus , path , interface , property , reply , userdata , error , false ) ;
}
static int bus_property_get_dns_servers_ex (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
return bus_property_get_dns_servers_internal ( bus , path , interface , property , reply , userdata , error , true ) ;
}
static int bus_property_get_fallback_dns_servers_internal (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ,
bool extended ) {
2018-05-11 16:03:17 +09:00
2022-08-09 14:35:15 +02:00
DnsServer * * f = ASSERT_PTR ( userdata ) ;
2018-05-11 16:03:17 +09:00
int r ;
assert ( reply ) ;
2020-07-03 21:03:51 +09:00
r = sd_bus_message_open_container ( reply , ' a ' , extended ? " (iiayqs) " : " (iiay) " ) ;
2018-05-11 16:03:17 +09:00
if ( r < 0 )
return r ;
LIST_FOREACH ( servers , s , * f ) {
2020-07-03 21:03:51 +09:00
r = bus_dns_server_append ( reply , s , true , extended ) ;
2018-05-11 16:03:17 +09:00
if ( r < 0 )
return r ;
2015-11-24 22:49:15 +01:00
}
return sd_bus_message_close_container ( reply ) ;
}
2020-07-03 21:03:51 +09:00
static int bus_property_get_fallback_dns_servers (
2018-05-01 15:58:42 +09:00
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
2020-07-03 21:03:51 +09:00
return bus_property_get_fallback_dns_servers_internal ( bus , path , interface , property , reply , userdata , error , false ) ;
}
static int bus_property_get_fallback_dns_servers_ex (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
return bus_property_get_fallback_dns_servers_internal ( bus , path , interface , property , reply , userdata , error , true ) ;
}
static int bus_property_get_current_dns_server_internal (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ,
bool extended ) {
2018-05-01 15:58:42 +09:00
DnsServer * s ;
assert ( reply ) ;
assert ( userdata ) ;
s = * ( DnsServer * * ) userdata ;
2020-07-03 21:03:51 +09:00
return bus_dns_server_append ( reply , s , true , extended ) ;
}
static int bus_property_get_current_dns_server (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
return bus_property_get_current_dns_server_internal ( bus , path , interface , property , reply , userdata , error , false ) ;
}
static int bus_property_get_current_dns_server_ex (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
return bus_property_get_current_dns_server_internal ( bus , path , interface , property , reply , userdata , error , true ) ;
2018-05-01 15:58:42 +09:00
}
2016-02-13 20:03:01 +01:00
static int bus_property_get_domains (
2015-11-24 22:49:15 +01:00
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2015-11-24 22:49:15 +01:00
Link * l ;
int r ;
assert ( reply ) ;
2016-01-25 23:19:49 +01:00
r = sd_bus_message_open_container ( reply , ' a ' , " (isb) " ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
LIST_FOREACH ( domains , d , m - > search_domains ) {
2016-01-25 23:19:49 +01:00
r = sd_bus_message_append ( reply , " (isb) " , 0 , d - > name , d - > route_only ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
}
2020-09-08 11:58:29 +02:00
HASHMAP_FOREACH ( l , m - > links ) {
2015-11-24 22:49:15 +01:00
LIST_FOREACH ( domains , d , l - > search_domains ) {
2016-01-25 23:19:49 +01:00
r = sd_bus_message_append ( reply , " (isb) " , l - > ifindex , d - > name , d - > route_only ) ;
2015-11-24 22:49:15 +01:00
if ( r < 0 )
return r ;
}
}
return sd_bus_message_close_container ( reply ) ;
}
2015-12-23 19:06:36 +01:00
static int bus_property_get_transaction_statistics (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2015-12-23 19:06:36 +01:00
assert ( reply ) ;
return sd_bus_message_append ( reply , " (tt) " ,
( uint64_t ) hashmap_size ( m - > dns_transactions ) ,
( uint64_t ) m - > n_transactions_total ) ;
}
static int bus_property_get_cache_statistics (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
uint64_t size = 0 , hit = 0 , miss = 0 ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2015-12-23 19:06:36 +01:00
assert ( reply ) ;
LIST_FOREACH ( scopes , s , m - > dns_scopes ) {
size + = dns_cache_size ( & s - > cache ) ;
hit + = s - > cache . n_hit ;
miss + = s - > cache . n_miss ;
}
return sd_bus_message_append ( reply , " (ttt) " , size, hit, miss) ;
}
static int bus_property_get_dnssec_statistics (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2015-12-23 19:06:36 +01:00
assert ( reply ) ;
return sd_bus_message_append ( reply , " (tttt) " ,
2016-01-21 02:21:58 +01:00
( uint64_t ) m - > n_dnssec_verdict [ DNSSEC_SECURE ] ,
( uint64_t ) m - > n_dnssec_verdict [ DNSSEC_INSECURE ] ,
( uint64_t ) m - > n_dnssec_verdict [ DNSSEC_BOGUS ] ,
( uint64_t ) m - > n_dnssec_verdict [ DNSSEC_INDETERMINATE ] ) ;
2015-12-23 19:06:36 +01:00
}
2017-03-08 12:43:17 -08:00
static BUS_DEFINE_PROPERTY_GET_ENUM ( bus_property_get_dns_stub_listener_mode , dns_stub_listener_mode , DnsStubListenerMode ) ;
2018-05-14 10:04:21 +09:00
static BUS_DEFINE_PROPERTY_GET ( bus_property_get_dnssec_supported , " b " , Manager , manager_dnssec_supported ) ;
static BUS_DEFINE_PROPERTY_GET2 ( bus_property_get_dnssec_mode , " s " , Manager , manager_get_dnssec_mode , dnssec_mode_to_string ) ;
2018-06-13 20:26:24 +02:00
static BUS_DEFINE_PROPERTY_GET2 ( bus_property_get_dns_over_tls_mode , " s " , Manager , manager_get_dns_over_tls_mode , dns_over_tls_mode_to_string ) ;
2017-03-08 12:43:17 -08:00
2020-09-29 17:25:15 +02:00
static int bus_property_get_resolv_conf_mode (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
int r ;
assert ( reply ) ;
r = resolv_conf_mode ( ) ;
if ( r < 0 ) {
log_warning_errno ( r , " Failed to test /etc/resolv.conf mode, ignoring: %m " ) ;
return sd_bus_message_append ( reply , " s " , NULL ) ;
}
return sd_bus_message_append ( reply , " s " , resolv_conf_mode_to_string ( r ) ) ;
}
2015-12-23 19:06:36 +01:00
static int bus_method_reset_statistics ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2015-12-23 19:06:36 +01:00
assert ( message ) ;
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " statistics reset " ) ;
2023-08-15 16:15:58 +05:30
dns_manager_reset_statistics ( m ) ;
2015-12-23 19:06:36 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
}
2016-01-19 18:32:42 +01:00
static int get_any_link ( Manager * m , int ifindex , Link * * ret , sd_bus_error * error ) {
2016-01-19 17:16:12 +01:00
Link * l ;
assert ( m ) ;
2016-01-19 18:32:42 +01:00
assert ( ret ) ;
2016-01-19 17:16:12 +01:00
l = hashmap_get ( m - > links , INT_TO_PTR ( ifindex ) ) ;
if ( ! l )
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_LINK , " Link %i not known " , ifindex ) ;
2016-01-19 18:32:42 +01:00
* ret = l ;
return 0 ;
}
2016-01-19 21:20:13 +01:00
static int call_link_method ( Manager * m , sd_bus_message * message , sd_bus_message_handler_t handler , sd_bus_error * error ) {
2016-01-19 17:16:12 +01:00
int ifindex , r ;
2024-10-16 11:42:06 +01:00
Link * l = NULL ; /* avoid false maybe-uninitialized warning */
2016-01-19 17:16:12 +01:00
assert ( m ) ;
assert ( message ) ;
2016-01-19 21:20:13 +01:00
assert ( handler ) ;
2016-01-19 17:16:12 +01:00
2020-07-19 12:32:21 +09:00
r = bus_message_read_ifindex ( message , error , & ifindex ) ;
2016-01-19 17:16:12 +01:00
if ( r < 0 )
return r ;
2016-06-10 20:54:10 +02:00
r = get_any_link ( m , ifindex , & l , error ) ;
2016-01-19 17:16:12 +01:00
if ( r < 0 )
return r ;
2016-01-19 21:20:13 +01:00
return handler ( message , l , error ) ;
}
2016-01-19 17:16:12 +01:00
2016-01-19 21:20:13 +01:00
static int bus_method_set_link_dns_servers ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return call_link_method ( userdata , message , bus_link_method_set_dns_servers , error ) ;
}
2016-01-19 17:16:12 +01:00
2020-07-03 20:31:15 +09:00
static int bus_method_set_link_dns_servers_ex ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return call_link_method ( userdata , message , bus_link_method_set_dns_servers_ex , error ) ;
}
2016-02-13 20:03:01 +01:00
static int bus_method_set_link_domains ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return call_link_method ( userdata , message , bus_link_method_set_domains , error ) ;
2016-01-19 17:16:12 +01:00
}
2018-12-04 13:10:11 +01:00
static int bus_method_set_link_default_route ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return call_link_method ( userdata , message , bus_link_method_set_default_route , error ) ;
}
2016-01-19 17:16:12 +01:00
static int bus_method_set_link_llmnr ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2016-01-19 21:20:13 +01:00
return call_link_method ( userdata , message , bus_link_method_set_llmnr , error ) ;
2016-01-19 17:16:12 +01:00
}
static int bus_method_set_link_mdns ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2016-01-19 21:20:13 +01:00
return call_link_method ( userdata , message , bus_link_method_set_mdns , error ) ;
2016-01-19 17:16:12 +01:00
}
2018-06-13 20:26:24 +02:00
static int bus_method_set_link_dns_over_tls ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return call_link_method ( userdata , message , bus_link_method_set_dns_over_tls , error ) ;
2018-06-13 10:50:30 +09:00
}
2016-01-19 17:16:12 +01:00
static int bus_method_set_link_dnssec ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2016-01-19 21:20:13 +01:00
return call_link_method ( userdata , message , bus_link_method_set_dnssec , error ) ;
2016-01-19 17:16:12 +01:00
}
static int bus_method_set_link_dnssec_negative_trust_anchors ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2016-01-19 21:20:13 +01:00
return call_link_method ( userdata , message , bus_link_method_set_dnssec_negative_trust_anchors , error ) ;
2016-01-19 17:16:12 +01:00
}
static int bus_method_revert_link ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2016-01-19 21:20:13 +01:00
return call_link_method ( userdata , message , bus_link_method_revert , error ) ;
2016-01-19 17:16:12 +01:00
}
2016-01-19 18:32:42 +01:00
static int bus_method_get_link ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
_cleanup_free_ char * p = NULL ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2016-01-19 18:32:42 +01:00
int r , ifindex ;
2024-10-16 11:42:06 +01:00
Link * l = NULL ; /* avoid false maybe-uninitialized warning */
2016-01-19 18:32:42 +01:00
assert ( message ) ;
2020-07-19 12:32:21 +09:00
r = bus_message_read_ifindex ( message , error , & ifindex ) ;
2016-01-19 18:32:42 +01:00
if ( r < 0 )
return r ;
r = get_any_link ( m , ifindex , & l , error ) ;
if ( r < 0 )
return r ;
p = link_bus_path ( l ) ;
if ( ! p )
return - ENOMEM ;
return sd_bus_reply_method_return ( message , " o " , p ) ;
}
2016-06-10 20:40:30 +02:00
static int bus_method_flush_caches ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2016-06-10 20:40:30 +02:00
assert ( message ) ;
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " cache flush " ) ;
2020-11-05 14:17:37 +01:00
manager_flush_caches ( m , LOG_INFO ) ;
2016-06-10 20:40:30 +02:00
return sd_bus_reply_method_return ( message , NULL ) ;
}
2017-09-29 21:19:54 +02:00
static int bus_method_reset_server_features ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2017-09-29 21:19:54 +02:00
assert ( message ) ;
2020-11-09 22:20:16 +01:00
bus_client_log ( message , " server feature reset " ) ;
2024-03-01 21:46:46 +01:00
( void ) dns_stream_disconnect_all ( m ) ;
2017-09-29 21:19:54 +02:00
manager_reset_server_features ( m ) ;
return sd_bus_reply_method_return ( message , NULL ) ;
}
2020-08-16 13:43:51 +02:00
static int dnssd_service_on_bus_track ( sd_bus_track * t , void * userdata ) {
2022-08-09 14:35:15 +02:00
DnssdService * s = ASSERT_PTR ( userdata ) ;
2017-10-23 14:46:13 +03:00
assert ( t ) ;
log_debug ( " Client of active request vanished, destroying DNS-SD service. " ) ;
dnssd_service_free ( s ) ;
return 0 ;
}
static int bus_method_register_service ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2017-11-22 16:49:23 +02:00
_cleanup_ ( sd_bus_creds_unrefp ) sd_bus_creds * creds = NULL ;
2017-10-23 14:46:13 +03:00
_cleanup_ ( dnssd_service_freep ) DnssdService * service = NULL ;
_cleanup_ ( sd_bus_track_unrefp ) sd_bus_track * bus_track = NULL ;
2024-04-22 12:30:16 +02:00
const char * id , * name_template , * type ;
2017-10-23 14:46:13 +03:00
_cleanup_free_ char * path = NULL ;
DnssdService * s = NULL ;
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2017-11-22 16:49:23 +02:00
uid_t euid ;
2017-10-23 14:46:13 +03:00
int r ;
assert ( message ) ;
if ( m - > mdns_support ! = RESOLVE_SUPPORT_YES )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Support for MulticastDNS is disabled " ) ;
2017-10-23 14:46:13 +03:00
service = new0 ( DnssdService , 1 ) ;
if ( ! service )
return log_oom ( ) ;
2017-11-22 16:49:23 +02:00
r = sd_bus_query_sender_creds ( message , SD_BUS_CREDS_EUID , & creds ) ;
if ( r < 0 )
return r ;
r = sd_bus_creds_get_euid ( creds , & euid ) ;
if ( r < 0 )
return r ;
service - > originator = euid ;
2024-03-08 23:02:19 +00:00
service - > config_source = RESOLVE_CONFIG_SOURCE_DBUS ;
2017-11-22 16:49:23 +02:00
2024-04-22 12:30:16 +02:00
r = sd_bus_message_read ( message , " sssqqq " , & id , & name_template , & type ,
2017-10-23 14:46:13 +03:00
& service - > port , & service - > priority ,
& service - > weight ) ;
if ( r < 0 )
return r ;
2024-04-22 12:32:54 +02:00
if ( ! filename_part_is_valid ( id ) )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " DNS-SD service identifier '%s' is invalid " , id ) ;
2017-10-23 14:46:13 +03:00
if ( ! dnssd_srv_type_is_valid ( type ) )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " DNS-SD service type '%s' is invalid " , type ) ;
2024-04-22 12:32:54 +02:00
s = hashmap_get ( m - > dnssd_services , id ) ;
if ( s )
return sd_bus_error_setf ( error , BUS_ERROR_DNSSD_SERVICE_EXISTS , " DNS-SD service '%s' exists already " , id ) ;
2024-04-22 12:30:16 +02:00
service - > id = strdup ( id ) ;
if ( ! service - > id )
2017-10-23 14:46:13 +03:00
return log_oom ( ) ;
service - > name_template = strdup ( name_template ) ;
if ( ! service - > name_template )
return log_oom ( ) ;
service - > type = strdup ( type ) ;
if ( ! service - > type )
return log_oom ( ) ;
2022-05-15 10:23:25 +09:00
r = dnssd_render_instance_name ( m , service , NULL ) ;
2020-11-17 05:37:58 +01:00
if ( r < 0 )
return r ;
2017-11-29 11:03:44 +02:00
r = sd_bus_message_enter_container ( message , SD_BUS_TYPE_ARRAY , " a{say} " ) ;
2017-10-23 14:46:13 +03:00
if ( r < 0 )
2017-11-29 11:03:44 +02:00
return r ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
while ( ( r = sd_bus_message_enter_container ( message , SD_BUS_TYPE_ARRAY , " {say} " ) ) > 0 ) {
_cleanup_ ( dnssd_txtdata_freep ) DnssdTxtData * txt_data = NULL ;
DnsTxtItem * last = NULL ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
txt_data = new0 ( DnssdTxtData , 1 ) ;
if ( ! txt_data )
return log_oom ( ) ;
while ( ( r = sd_bus_message_enter_container ( message , SD_BUS_TYPE_DICT_ENTRY , " say " ) ) > 0 ) {
const char * key ;
const void * value ;
size_t size ;
DnsTxtItem * i ;
r = sd_bus_message_read ( message , " s " , & key ) ;
if ( r < 0 )
return r ;
if ( isempty ( key ) )
2021-04-07 15:59:27 +02:00
return sd_bus_error_set ( error , SD_BUS_ERROR_INVALID_ARGS , " Keys in DNS-SD TXT RRs can't be empty " ) ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
if ( ! ascii_is_valid ( key ) )
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " TXT key '%s' contains non-ASCII symbols " , key ) ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
r = sd_bus_message_read_array ( message , ' y ' , & value , & size ) ;
if ( r < 0 )
return r ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
r = dnssd_txt_item_new_from_data ( key , value , size , & i ) ;
if ( r < 0 )
return r ;
2022-06-29 14:17:44 +02:00
LIST_INSERT_AFTER ( items , txt_data - > txts , last , i ) ;
2017-11-29 11:03:44 +02:00
last = i ;
r = sd_bus_message_exit_container ( message ) ;
if ( r < 0 )
return r ;
}
2017-10-23 14:46:13 +03:00
if ( r < 0 )
2017-11-29 11:03:44 +02:00
return r ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
r = sd_bus_message_exit_container ( message ) ;
2017-10-23 14:46:13 +03:00
if ( r < 0 )
2017-11-29 11:03:44 +02:00
return r ;
2017-10-23 14:46:13 +03:00
2022-06-29 14:17:44 +02:00
if ( txt_data - > txts ) {
2017-11-29 11:03:44 +02:00
LIST_PREPEND ( items , service - > txt_data_items , txt_data ) ;
txt_data = NULL ;
}
2017-10-23 14:46:13 +03:00
}
2017-11-29 11:03:44 +02:00
if ( r < 0 )
return r ;
2017-10-23 14:46:13 +03:00
r = sd_bus_message_exit_container ( message ) ;
if ( r < 0 )
2017-11-29 11:03:44 +02:00
return r ;
if ( ! service - > txt_data_items ) {
_cleanup_ ( dnssd_txtdata_freep ) DnssdTxtData * txt_data = NULL ;
2017-10-23 14:46:13 +03:00
2017-11-29 11:03:44 +02:00
txt_data = new0 ( DnssdTxtData , 1 ) ;
if ( ! txt_data )
return log_oom ( ) ;
2022-06-29 14:17:44 +02:00
r = dns_txt_item_new_empty ( & txt_data - > txts ) ;
2017-10-23 14:46:13 +03:00
if ( r < 0 )
2017-11-29 11:03:44 +02:00
return r ;
LIST_PREPEND ( items , service - > txt_data_items , txt_data ) ;
txt_data = NULL ;
2017-10-23 14:46:13 +03:00
}
2024-04-22 12:30:16 +02:00
r = sd_bus_path_encode ( " /org/freedesktop/resolve1/dnssd " , service - > id , & path ) ;
2017-10-23 14:46:13 +03:00
if ( r < 0 )
return r ;
2023-11-22 18:56:19 +01:00
r = bus_verify_polkit_async (
message ,
" org.freedesktop.resolve1.register-service " ,
/* details= */ NULL ,
& m - > polkit_registry ,
error ) ;
2019-08-27 19:28:19 +02:00
if ( r < 0 )
return r ;
if ( r = = 0 )
return 1 ; /* Polkit will call us back */
2024-04-22 12:30:16 +02:00
r = hashmap_ensure_put ( & m - > dnssd_services , & string_hash_ops , service - > id , service ) ;
2017-10-23 14:46:13 +03:00
if ( r < 0 )
return r ;
2020-08-16 13:43:51 +02:00
r = sd_bus_track_new ( sd_bus_message_get_bus ( message ) , & bus_track , dnssd_service_on_bus_track , service ) ;
2017-10-23 14:46:13 +03:00
if ( r < 0 )
return r ;
r = sd_bus_track_add_sender ( bus_track , message ) ;
if ( r < 0 )
return r ;
service - > manager = m ;
service = NULL ;
manager_refresh_rrs ( m ) ;
return sd_bus_reply_method_return ( message , " o " , path ) ;
}
static int call_dnssd_method ( Manager * m , sd_bus_message * message , sd_bus_message_handler_t handler , sd_bus_error * error ) {
_cleanup_free_ char * name = NULL ;
DnssdService * s = NULL ;
const char * path ;
int r ;
assert ( m ) ;
assert ( message ) ;
assert ( handler ) ;
r = sd_bus_message_read ( message , " o " , & path ) ;
if ( r < 0 )
return r ;
r = sd_bus_path_decode ( path , " /org/freedesktop/resolve1/dnssd " , & name ) ;
if ( r = = 0 )
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_DNSSD_SERVICE , " DNS-SD service with object path '%s' does not exist " , path ) ;
if ( r < 0 )
return r ;
s = hashmap_get ( m - > dnssd_services , name ) ;
if ( ! s )
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_DNSSD_SERVICE , " DNS-SD service '%s' not known " , name ) ;
return handler ( message , s , error ) ;
}
static int bus_method_unregister_service ( sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2017-10-23 14:46:13 +03:00
assert ( message ) ;
return call_dnssd_method ( m , message , bus_dnssd_method_unregister , error ) ;
}
2014-07-16 00:26:02 +02:00
static const sd_bus_vtable resolve_vtable [ ] = {
SD_BUS_VTABLE_START ( 0 ) ,
2019-10-25 16:29:42 +02:00
SD_BUS_PROPERTY ( " LLMNRHostname " , " s " , NULL , offsetof ( Manager , llmnr_hostname ) , SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE ) ,
2018-03-19 14:29:22 +09:00
SD_BUS_PROPERTY ( " LLMNR " , " s " , bus_property_get_resolve_support , offsetof ( Manager , llmnr_support ) , 0 ) ,
SD_BUS_PROPERTY ( " MulticastDNS " , " s " , bus_property_get_resolve_support , offsetof ( Manager , mdns_support ) , 0 ) ,
2018-06-13 20:26:24 +02:00
SD_BUS_PROPERTY ( " DNSOverTLS " , " s " , bus_property_get_dns_over_tls_mode , 0 , 0 ) ,
2019-10-25 15:19:36 +02:00
SD_BUS_PROPERTY ( " DNS " , " a(iiay) " , bus_property_get_dns_servers , 0 , SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE ) ,
2020-07-03 21:03:51 +09:00
SD_BUS_PROPERTY ( " DNSEx " , " a(iiayqs) " , bus_property_get_dns_servers_ex , 0 , SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE ) ,
2018-05-11 16:03:17 +09:00
SD_BUS_PROPERTY ( " FallbackDNS " , " a(iiay) " , bus_property_get_fallback_dns_servers , offsetof ( Manager , fallback_dns_servers ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
2020-07-03 21:03:51 +09:00
SD_BUS_PROPERTY ( " FallbackDNSEx " , " a(iiayqs) " , bus_property_get_fallback_dns_servers_ex , offsetof ( Manager , fallback_dns_servers ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
2019-10-25 16:36:19 +02:00
SD_BUS_PROPERTY ( " CurrentDNSServer " , " (iiay) " , bus_property_get_current_dns_server , offsetof ( Manager , current_dns_server ) , SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE ) ,
2020-07-03 21:03:51 +09:00
SD_BUS_PROPERTY ( " CurrentDNSServerEx " , " (iiayqs) " , bus_property_get_current_dns_server_ex , offsetof ( Manager , current_dns_server ) , SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE ) ,
2016-02-13 20:03:01 +01:00
SD_BUS_PROPERTY ( " Domains " , " a(isb) " , bus_property_get_domains , 0 , 0 ) ,
2015-12-23 19:06:36 +01:00
SD_BUS_PROPERTY ( " TransactionStatistics " , " (tt) " , bus_property_get_transaction_statistics , 0 , 0 ) ,
SD_BUS_PROPERTY ( " CacheStatistics " , " (ttt) " , bus_property_get_cache_statistics , 0 , 0 ) ,
2018-03-19 14:29:22 +09:00
SD_BUS_PROPERTY ( " DNSSEC " , " s " , bus_property_get_dnssec_mode , 0 , 0 ) ,
2015-12-23 19:06:36 +01:00
SD_BUS_PROPERTY ( " DNSSECStatistics " , " (tttt) " , bus_property_get_dnssec_statistics , 0 , 0 ) ,
2016-01-19 17:11:28 +01:00
SD_BUS_PROPERTY ( " DNSSECSupported " , " b " , bus_property_get_dnssec_supported , 0 , 0 ) ,
2023-06-09 21:45:31 +02:00
SD_BUS_PROPERTY ( " DNSSECNegativeTrustAnchors " , " as " , bus_property_get_string_set , offsetof ( Manager , trust_anchor . negative_by_name ) , 0 ) ,
2017-03-08 12:43:17 -08:00
SD_BUS_PROPERTY ( " DNSStubListener " , " s " , bus_property_get_dns_stub_listener_mode , offsetof ( Manager , dns_stub_listener_mode ) , 0 ) ,
2020-09-29 17:25:15 +02:00
SD_BUS_PROPERTY ( " ResolvConfMode " , " s " , bus_property_get_resolv_conf_mode , 0 , 0 ) ,
2015-11-24 22:49:15 +01:00
2020-04-28 19:04:33 +02:00
SD_BUS_METHOD_WITH_ARGS ( " ResolveHostname " ,
SD_BUS_ARGS ( " i " , ifindex , " s " , name , " i " , family , " t " , flags ) ,
SD_BUS_RESULT ( " a(iiay) " , addresses , " s " , canonical , " t " , flags ) ,
bus_method_resolve_hostname ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " ResolveAddress " ,
SD_BUS_ARGS ( " i " , ifindex , " i " , family , " ay " , address , " t " , flags ) ,
SD_BUS_RESULT ( " a(is) " , names , " t " , flags ) ,
bus_method_resolve_address ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " ResolveRecord " ,
SD_BUS_ARGS ( " i " , ifindex , " s " , name , " q " , class , " q " , type , " t " , flags ) ,
SD_BUS_RESULT ( " a(iqqay) " , records , " t " , flags ) ,
bus_method_resolve_record ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " ResolveService " ,
SD_BUS_ARGS ( " i " , ifindex ,
" s " , name ,
" s " , type ,
" s " , domain ,
" i " , family ,
" t " , flags ) ,
SD_BUS_RESULT ( " a(qqqsa(iiay)s) " , srv_data ,
" aay " , txt_data ,
" s " , canonical_name ,
" s " , canonical_type ,
" s " , canonical_domain ,
" t " , flags ) ,
bus_method_resolve_service ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " GetLink " ,
SD_BUS_ARGS ( " i " , ifindex ) ,
SD_BUS_RESULT ( " o " , path ) ,
bus_method_get_link ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDNS " ,
SD_BUS_ARGS ( " i " , ifindex , " a(iay) " , addresses ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_dns_servers ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
2020-07-03 20:31:15 +09:00
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDNSEx " ,
SD_BUS_ARGS ( " i " , ifindex , " a(iayqs) " , addresses ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_dns_servers_ex ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
2020-04-28 19:04:33 +02:00
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDomains " ,
SD_BUS_ARGS ( " i " , ifindex , " a(sb) " , domains ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_domains ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDefaultRoute " ,
SD_BUS_ARGS ( " i " , ifindex , " b " , enable ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_default_route ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkLLMNR " ,
SD_BUS_ARGS ( " i " , ifindex , " s " , mode ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_llmnr ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkMulticastDNS " ,
SD_BUS_ARGS ( " i " , ifindex , " s " , mode ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_mdns ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDNSOverTLS " ,
SD_BUS_ARGS ( " i " , ifindex , " s " , mode ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_dns_over_tls ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDNSSEC " ,
SD_BUS_ARGS ( " i " , ifindex , " s " , mode ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_dnssec ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " SetLinkDNSSECNegativeTrustAnchors " ,
SD_BUS_ARGS ( " i " , ifindex , " as " , names ) ,
SD_BUS_NO_RESULT ,
bus_method_set_link_dnssec_negative_trust_anchors ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " RevertLink " ,
SD_BUS_ARGS ( " i " , ifindex ) ,
SD_BUS_NO_RESULT ,
bus_method_revert_link ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " RegisterService " ,
2024-04-22 12:30:16 +02:00
SD_BUS_ARGS ( " s " , id ,
2020-04-28 19:04:33 +02:00
" s " , name_template ,
" s " , type ,
" q " , service_port ,
" q " , service_priority ,
" q " , service_weight ,
2020-05-06 15:02:38 +02:00
" aa{say} " , txt_datas ) ,
2020-04-28 19:04:33 +02:00
SD_BUS_RESULT ( " o " , service_path ) ,
bus_method_register_service ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " UnregisterService " ,
SD_BUS_ARGS ( " o " , service_path ) ,
SD_BUS_NO_RESULT ,
bus_method_unregister_service ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " ResetStatistics " ,
SD_BUS_NO_ARGS ,
SD_BUS_NO_RESULT ,
bus_method_reset_statistics ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " FlushCaches " ,
SD_BUS_NO_ARGS ,
SD_BUS_NO_RESULT ,
bus_method_flush_caches ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD_WITH_ARGS ( " ResetServerFeatures " ,
SD_BUS_NO_ARGS ,
SD_BUS_NO_RESULT ,
bus_method_reset_server_features ,
SD_BUS_VTABLE_UNPRIVILEGED ) ,
2021-02-04 16:05:05 +01:00
2014-07-16 00:26:02 +02:00
SD_BUS_VTABLE_END ,
} ;
2020-04-23 12:45:47 +02:00
const BusObjectImplementation manager_object = {
" /org/freedesktop/resolve1 " ,
" org.freedesktop.resolve1.Manager " ,
. vtables = BUS_VTABLES ( resolve_vtable ) ,
. children = BUS_IMPLEMENTATIONS ( & link_object ,
& dnssd_object ) ,
} ;
2015-04-29 18:35:10 +02:00
static int match_prepare_for_sleep ( sd_bus_message * message , void * userdata , sd_bus_error * ret_error ) {
2022-08-09 14:35:15 +02:00
Manager * m = ASSERT_PTR ( userdata ) ;
2014-08-06 16:59:48 +02:00
int b , r ;
2015-04-29 18:35:10 +02:00
assert ( message ) ;
2014-08-06 16:59:48 +02:00
r = sd_bus_message_read ( message , " b " , & b ) ;
if ( r < 0 ) {
2020-07-11 18:13:01 +08:00
bus_log_parse_error ( r ) ;
2014-08-06 16:59:48 +02:00
return 0 ;
}
if ( b )
return 0 ;
2024-03-01 21:46:46 +01:00
log_debug ( " Coming back from suspend, closing all TCP connections... " ) ;
( void ) dns_stream_disconnect_all ( m ) ;
log_debug ( " Coming back from suspend, resetting all probed server features... " ) ;
manager_reset_server_features ( m ) ;
2014-08-06 16:59:48 +02:00
2024-03-01 21:46:46 +01:00
log_debug ( " Coming back from suspend, verifying all RRs... " ) ;
2014-08-06 16:59:48 +02:00
manager_verify_all ( m ) ;
2024-03-01 21:46:46 +01:00
2014-08-06 16:59:48 +02:00
return 0 ;
}
2014-07-16 00:26:02 +02:00
int manager_connect_bus ( Manager * m ) {
int r ;
assert ( m ) ;
if ( m - > bus )
return 0 ;
2018-04-17 23:56:17 +09:00
r = bus_open_system_watch_bind_with_description ( & m - > bus , " bus-api-resolve " ) ;
2017-12-19 15:54:30 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to connect to system bus: %m " ) ;
2014-07-16 00:26:02 +02:00
2020-04-23 12:45:47 +02:00
r = bus_add_implementation ( m - > bus , & manager_object , m ) ;
2016-01-19 18:32:42 +01:00
if ( r < 0 )
2020-04-23 12:45:47 +02:00
return r ;
2017-10-23 14:46:13 +03:00
2020-04-21 10:27:23 +02:00
r = bus_log_control_api_register ( m - > bus ) ;
if ( r < 0 )
return r ;
2018-09-19 10:04:33 +02:00
r = sd_bus_request_name_async ( m - > bus , NULL , " org.freedesktop.resolve1 " , 0 , NULL , NULL ) ;
2014-11-28 18:50:43 +01:00
if ( r < 0 )
2017-12-18 22:10:11 +01:00
return log_error_errno ( r , " Failed to request name: %m " ) ;
2014-07-16 00:26:02 +02:00
r = sd_bus_attach_event ( m - > bus , m - > event , 0 ) ;
2014-11-28 18:50:43 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to attach bus to event loop: %m " ) ;
2014-07-16 00:26:02 +02:00
2023-05-23 20:23:17 +02:00
r = bus_match_signal_async (
2017-12-19 12:29:04 +01:00
m - > bus ,
2018-07-18 18:12:50 +09:00
NULL ,
2023-05-23 20:23:17 +02:00
bus_login_mgr ,
2017-12-19 12:29:04 +01:00
" PrepareForSleep " ,
match_prepare_for_sleep ,
NULL ,
m ) ;
if ( r < 0 )
2017-12-19 15:54:30 +01:00
log_warning_errno ( r , " Failed to request match for PrepareForSleep, ignoring: %m " ) ;
2014-08-06 16:59:48 +02:00
2014-07-16 00:26:02 +02:00
return 0 ;
}
2019-10-25 15:19:36 +02:00
int _manager_send_changed ( Manager * manager , const char * property , . . . ) {
assert ( manager ) ;
2021-05-08 01:56:24 +09:00
if ( sd_bus_is_ready ( manager - > bus ) < = 0 )
return 0 ;
2019-10-25 15:19:36 +02:00
char * * l = strv_from_stdarg_alloca ( property ) ;
int r = sd_bus_emit_properties_changed_strv (
manager - > bus ,
" /org/freedesktop/resolve1 " ,
" org.freedesktop.resolve1.Manager " ,
l ) ;
if ( r < 0 )
log_notice_errno ( r , " Failed to emit notification about changed property %s: %m " , property ) ;
return r ;
}