mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
Merge pull request #3549 from poettering/resolved-more
resolved: more fixes, among them "systemctl-resolve --status" to see DNS configuration in effect, and a local DNS stub listener on 127.0.0.53
This commit is contained in:
@@ -125,6 +125,7 @@ dist_systemunit_DATA_busnames =
|
||||
dist_sysusers_DATA =
|
||||
check_PROGRAMS =
|
||||
check_DATA =
|
||||
dist_rootlibexec_DATA =
|
||||
tests=
|
||||
manual_tests =
|
||||
TEST_EXTENSIONS = .py
|
||||
@@ -5147,7 +5148,7 @@ systemd_export_LDADD = \
|
||||
$(ZLIB_LIBS) \
|
||||
-lbz2
|
||||
|
||||
dist_rootlibexec_DATA = \
|
||||
dist_rootlibexec_DATA += \
|
||||
src/import/import-pubring.gpg
|
||||
|
||||
nodist_systemunit_DATA += \
|
||||
@@ -5259,6 +5260,8 @@ systemd_resolved_SOURCES = \
|
||||
src/resolve/resolved-dns-stream.c \
|
||||
src/resolve/resolved-dns-trust-anchor.h \
|
||||
src/resolve/resolved-dns-trust-anchor.c \
|
||||
src/resolve/resolved-dns-stub.h \
|
||||
src/resolve/resolved-dns-stub.c \
|
||||
src/resolve/resolved-etc-hosts.h \
|
||||
src/resolve/resolved-etc-hosts.c \
|
||||
src/shared/gcrypt-util.c \
|
||||
@@ -5411,6 +5414,9 @@ EXTRA_DIST += \
|
||||
units/systemd-resolved.service.m4.in \
|
||||
src/resolve/resolved.conf.in
|
||||
|
||||
dist_rootlibexec_DATA += \
|
||||
src/resolve/resolv.conf
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
if ENABLE_NETWORKD
|
||||
rootlibexec_PROGRAMS += \
|
||||
|
||||
@@ -294,8 +294,15 @@
|
||||
<listitem><para>Flushes all DNS resource record caches the service maintains locally.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--status</option></term>
|
||||
|
||||
<listitem><para>Shows the global and per-link DNS settings in currently in effect.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -58,27 +58,45 @@
|
||||
|
||||
<para><command>systemd-resolved</command> is a system service that provides network name resolution to local
|
||||
applications. It implements a caching and validating DNS/DNSSEC stub resolver, as well as an LLMNR resolver and
|
||||
responder. In addition it maintains the <filename>/run/systemd/resolve/resolv.conf</filename> file for
|
||||
compatibility with traditional Linux programs. This file may be symlinked from
|
||||
<filename>/etc/resolv.conf</filename>.</para>
|
||||
responder. Local applications may submit network name resolution requests via three interfaces:</para>
|
||||
|
||||
<para>The glibc NSS module
|
||||
<citerefentry><refentrytitle>nss-resolve</refentrytitle><manvolnum>8</manvolnum></citerefentry> is required to
|
||||
permit glibc's NSS resolver functions to resolve host names via <command>systemd-resolved</command>.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>The native, fully-featured API <command>systemd-resolved</command> exposes on the bus. See the
|
||||
<ulink url="http://www.freedesktop.org/wiki/Software/systemd/resolved">API Documentation</ulink> for
|
||||
details. Usage of this API is generally recommended to clients as it is asynchronous and fully featured (for
|
||||
example, properly returns DNSSEC validation status and interface scope for addresses as necessary for supporting
|
||||
link-local networking).</para></listitem>
|
||||
|
||||
<para>The DNS servers contacted are determined from the global
|
||||
settings in <filename>/etc/systemd/resolved.conf</filename>, the
|
||||
per-link static settings in <filename>/etc/systemd/network/*.network</filename> files,
|
||||
and the per-link dynamic settings received over DHCP. See
|
||||
<citerefentry><refentrytitle>resolved.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
and
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details. To improve compatibility,
|
||||
<filename>/etc/resolv.conf</filename> is read in order to discover
|
||||
configured system DNS servers, but only if it is not a symlink
|
||||
to <filename>/run/systemd/resolve/resolv.conf</filename> (see above).</para>
|
||||
<listitem><para>The glibc
|
||||
<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</manvolnum></citerefentry> API (as defined
|
||||
by <ulink url="https://tools.ietf.org/html/rfc3493">RFC3493</ulink>) and its related resolver functions,
|
||||
including <citerefentry><refentrytitle>gethostbyname</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
|
||||
API is widely supported, including beyond the Linux platform. In its current form it does not expose DNSSEC
|
||||
validation status information however, and is synchronous only. This API is backed by the glibc Name Service
|
||||
Switch (<citerefentry><refentrytitle>nss</refentrytitle><manvolnum>5</manvolnum></citerefentry>). Usage of the
|
||||
glibc NSS module <citerefentry><refentrytitle>nss-resolve</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
is required in order to allow glibc's NSS resolver functions to resolve host names via
|
||||
<command>systemd-resolved</command>.</para></listitem>
|
||||
|
||||
<para><command>systemd-resolved</command> synthesizes DNS RRs for the following cases:</para>
|
||||
<listitem><para>Additionally, <command>systemd-resolved</command> provides a local DNS stub listener on IP
|
||||
address 127.0.0.53 on the local loopback interface. Programs issuing DNS requests directly, bypassing any local
|
||||
API may be directed to this stub, in order to connect them <command>systemd-resolved</command>. Note however that
|
||||
it is strongly recommended that local programs use the glibc NSS or bus APIs instead (as described above), as
|
||||
various network resolution concepts (such as link-local addressing, or LLMNR Unicode domains) cannot be mapped to
|
||||
the unicast DNS protocol.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The DNS servers contacted are determined from the global settings in
|
||||
<filename>/etc/systemd/resolved.conf</filename>, the per-link static settings in
|
||||
<filename>/etc/systemd/network/*.network</filename> files, the per-link dynamic settings received over DHCP and any
|
||||
DNS server information made available by other system services. See
|
||||
<citerefentry><refentrytitle>resolved.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> and
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details
|
||||
about systemd's own configuration files for DNS servers. To improve compatibility,
|
||||
<filename>/etc/resolv.conf</filename> is read in order to discover configured system DNS servers, but only if it is
|
||||
not a symlink to <filename>/run/systemd/resolve/resolv.conf</filename> (see below).</para>
|
||||
|
||||
<para><command>systemd-resolved</command> synthesizes DNS resource records (RRs) for the following cases:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>The local, configured hostname is resolved to
|
||||
@@ -137,14 +155,45 @@
|
||||
per-interface domains are exclusively routed to the matching
|
||||
interfaces.</para>
|
||||
|
||||
<para>Note that <filename>/run/systemd/resolve/resolv.conf</filename> should not be used directly by applications,
|
||||
but only through a symlink from <filename>/etc/resolv.conf</filename>.</para>
|
||||
|
||||
<para>See the <ulink url="http://www.freedesktop.org/wiki/Software/systemd/resolved"> resolved D-Bus API
|
||||
Documentation</ulink> for information about the APIs <filename>systemd-resolved</filename> provides.</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title><filename>/etc/resolv.conf</filename></title>
|
||||
|
||||
<para>Three modes of handling <filename>/etc/resolv.conf</filename> (see
|
||||
<citerefentry><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>) are
|
||||
supported:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>A static file <filename>/usr/lib/systemd/resolv.conf</filename> is provided that lists
|
||||
the 127.0.0.53 DNS stub (see above) as only DNS server. This file may be symlinked from
|
||||
<filename>/etc/resolv.conf</filename> in order to connect all local clients that bypass local DNS APIs to
|
||||
<command>systemd-resolved</command>. This mode of operation is recommended.</para></listitem>
|
||||
|
||||
<listitem><para><command>systemd-resolved</command> maintains the
|
||||
<filename>/run/systemd/resolve/resolv.conf</filename> file for compatibility with traditional Linux
|
||||
programs. This file may be symlinked from <filename>/etc/resolv.conf</filename> and is always kept up-to-date,
|
||||
containing information about all known DNS servers. Note the file format's limitations: it does not know a
|
||||
concept of per-interface DNS servers and hence only contains system-wide DNS server definitions. Note that
|
||||
<filename>/run/systemd/resolve/resolv.conf</filename> should not be used directly by applications, but only
|
||||
through a symlink from <filename>/etc/resolv.conf</filename>. If this mode of operation is used local clients
|
||||
that bypass any local DNS API will also bypass <command>systemd-resolved</command> and will talk directly to the
|
||||
known DNS servers.</para> </listitem>
|
||||
|
||||
<listitem><para>Alternatively, <filename>/etc/resolv.conf</filename> may be managed by other packages, in which
|
||||
case <command>systemd-resolved</command> will read it for DNS configuration data. In this mode of operation
|
||||
<command>systemd-resolved</command> is consumer rather than provider of this configuration
|
||||
file. </para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Note that the selected mode of operation for this file is detected fully automatically, depending on whether
|
||||
<filename>/etc/resolv.conf</filename> is a symlink to <filename>/run/systemd/resolve/resolv.conf</filename> or
|
||||
lists 127.0.0.53 as DNS server.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Signals</title>
|
||||
|
||||
|
||||
@@ -50,6 +50,23 @@ Bitmap *bitmap_new(void) {
|
||||
return new0(Bitmap, 1);
|
||||
}
|
||||
|
||||
Bitmap *bitmap_copy(Bitmap *b) {
|
||||
Bitmap *ret;
|
||||
|
||||
ret = bitmap_new();
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
ret->bitmaps = newdup(uint64_t, b->bitmaps, b->n_bitmaps);
|
||||
if (!ret->bitmaps) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->n_bitmaps = ret->bitmaps_allocated = b->n_bitmaps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bitmap_free(Bitmap *b) {
|
||||
if (!b)
|
||||
return;
|
||||
|
||||
@@ -27,10 +27,9 @@
|
||||
typedef struct Bitmap Bitmap;
|
||||
|
||||
Bitmap *bitmap_new(void);
|
||||
|
||||
void bitmap_free(Bitmap *b);
|
||||
|
||||
Bitmap *bitmap_copy(Bitmap *b);
|
||||
int bitmap_ensure_allocated(Bitmap **b);
|
||||
void bitmap_free(Bitmap *b);
|
||||
|
||||
int bitmap_set(Bitmap *b, unsigned n);
|
||||
void bitmap_unset(Bitmap *b, unsigned n);
|
||||
|
||||
@@ -1764,6 +1764,9 @@ void *ordered_hashmap_next(OrderedHashmap *h, const void *key) {
|
||||
int set_consume(Set *s, void *value) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(value);
|
||||
|
||||
r = set_put(s, value);
|
||||
if (r <= 0)
|
||||
free(value);
|
||||
@@ -1791,6 +1794,8 @@ int set_put_strdupv(Set *s, char **l) {
|
||||
int n = 0, r;
|
||||
char **i;
|
||||
|
||||
assert(s);
|
||||
|
||||
STRV_FOREACH(i, l) {
|
||||
r = set_put_strdup(s, *i);
|
||||
if (r < 0)
|
||||
@@ -1801,3 +1806,23 @@ int set_put_strdupv(Set *s, char **l) {
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags) {
|
||||
const char *p = v;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(v);
|
||||
|
||||
for (;;) {
|
||||
char *word;
|
||||
|
||||
r = extract_first_word(&p, &word, separators, flags);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = set_consume(s, word);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,7 +553,7 @@ int wait_for_terminate(pid_t pid, siginfo_t *status) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
return negative_errno();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "extract-word.h"
|
||||
#include "hashmap.h"
|
||||
#include "macro.h"
|
||||
|
||||
@@ -122,6 +123,7 @@ static inline char **set_get_strv(Set *s) {
|
||||
int set_consume(Set *s, void *value);
|
||||
int set_put_strdup(Set *s, const char *p);
|
||||
int set_put_strdupv(Set *s, char **l);
|
||||
int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags);
|
||||
|
||||
#define SET_FOREACH(e, s, i) \
|
||||
for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
|
||||
|
||||
@@ -48,6 +48,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
|
||||
#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \
|
||||
scope type name##_from_string(const char *s) { \
|
||||
int b; \
|
||||
if (!s) \
|
||||
return -1; \
|
||||
b = parse_boolean(s); \
|
||||
if (b == 0) \
|
||||
return (type) 0; \
|
||||
|
||||
@@ -481,7 +481,7 @@ static int mmap_try_harder(MMapCache *m, void *addr, int fd, int prot, int flags
|
||||
if (ptr != MAP_FAILED)
|
||||
break;
|
||||
if (errno != ENOMEM)
|
||||
return -errno;
|
||||
return negative_errno();
|
||||
|
||||
r = make_room(m);
|
||||
if (r < 0)
|
||||
@@ -571,7 +571,7 @@ static int add_mmap(
|
||||
return 1;
|
||||
|
||||
outofmem:
|
||||
munmap(d, wsize);
|
||||
(void) munmap(d, wsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ typedef struct SessionStatusInfo {
|
||||
char *seat;
|
||||
char *tty;
|
||||
char *display;
|
||||
bool remote;
|
||||
int remote;
|
||||
char *remote_host;
|
||||
char *remote_user;
|
||||
char *service;
|
||||
@@ -304,7 +304,7 @@ typedef struct SessionStatusInfo {
|
||||
|
||||
typedef struct UserStatusInfo {
|
||||
uid_t uid;
|
||||
bool linger;
|
||||
int linger;
|
||||
char *name;
|
||||
struct dual_timestamp timestamp;
|
||||
char *state;
|
||||
|
||||
@@ -58,7 +58,7 @@ static int append_vlan_info_data(Link *const link, sd_netlink_message *req, uint
|
||||
struct bridge_vlan_info br_vlan;
|
||||
int i, j, k, r, done, cnt;
|
||||
uint16_t begin, end;
|
||||
bool untagged;
|
||||
bool untagged = false;
|
||||
|
||||
assert(link);
|
||||
assert(req);
|
||||
|
||||
@@ -52,7 +52,7 @@ Network.DNS, config_parse_strv,
|
||||
Network.LLMNR, config_parse_resolve_support, 0, offsetof(Network, llmnr)
|
||||
Network.MulticastDNS, config_parse_resolve_support, 0, offsetof(Network, mdns)
|
||||
Network.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Network, dnssec_mode)
|
||||
Network.DNSSECNegativeTrustAnchors, config_parse_dnssec_negative_trust_anchors, 0, offsetof(Network, dnssec_negative_trust_anchors)
|
||||
Network.DNSSECNegativeTrustAnchors, config_parse_dnssec_negative_trust_anchors, 0, 0
|
||||
Network.NTP, config_parse_strv, 0, offsetof(Network, ntp)
|
||||
Network.IPForward, config_parse_address_family_boolean_with_kernel,0, offsetof(Network, ip_forward)
|
||||
Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade)
|
||||
|
||||
@@ -96,6 +96,15 @@ bool dns_type_is_valid_query(uint16_t type) {
|
||||
DNS_TYPE_RRSIG);
|
||||
}
|
||||
|
||||
bool dns_type_is_zone_transer(uint16_t type) {
|
||||
|
||||
/* Zone transfers, either normal or incremental */
|
||||
|
||||
return IN_SET(type,
|
||||
DNS_TYPE_AXFR,
|
||||
DNS_TYPE_IXFR);
|
||||
}
|
||||
|
||||
bool dns_type_is_valid_rr(uint16_t type) {
|
||||
|
||||
/* The types valid as RR in packets (but not necessarily
|
||||
|
||||
@@ -136,6 +136,7 @@ bool dns_type_is_obsolete(uint16_t type);
|
||||
bool dns_type_may_wildcard(uint16_t type);
|
||||
bool dns_type_apex_only(uint16_t type);
|
||||
bool dns_type_needs_authentication(uint16_t type);
|
||||
bool dns_type_is_zone_transer(uint16_t type);
|
||||
int dns_type_to_af(uint16_t type);
|
||||
|
||||
bool dns_class_is_pseudo(uint16_t class);
|
||||
|
||||
11
src/resolve/resolv.conf
Normal file
11
src/resolve/resolv.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
# This is a static resolv.conf file for connecting local clients to
|
||||
# systemd-resolved via its DNS stub listener on 127.0.0.53.
|
||||
#
|
||||
# Third party programs must not access this file directly, but only through the
|
||||
# symlink at /etc/resolv.conf. To manage resolv.conf(5) in a different way,
|
||||
# replace this symlink by a static file or a different symlink.
|
||||
#
|
||||
# See systemd-resolved.service(8) for details about the supported modes of
|
||||
# operation for /etc/resolv.conf.
|
||||
|
||||
nameserver 127.0.0.53
|
||||
File diff suppressed because it is too large
Load Diff
@@ -647,6 +647,8 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
|
||||
|
||||
if (!dns_type_is_valid_query(type))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified resource record type %" PRIu16 " may not be used in a query.", type);
|
||||
if (dns_type_is_zone_transer(type))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Zone transfers not permitted via this programming interface.");
|
||||
if (dns_type_is_obsolete(type))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type);
|
||||
|
||||
@@ -670,6 +672,10 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Let's request that the TTL is fixed up for locally cached entries, after all we return it in the wire format
|
||||
* blob */
|
||||
q->clamp_ttl = true;
|
||||
|
||||
q->request = sd_bus_message_ref(message);
|
||||
q->complete = bus_method_resolve_record_complete;
|
||||
|
||||
@@ -1414,6 +1420,36 @@ static int bus_property_get_dnssec_supported(
|
||||
return sd_bus_message_append(reply, "b", manager_dnssec_supported(m));
|
||||
}
|
||||
|
||||
static int bus_property_get_ntas(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = userdata;
|
||||
const char *domain;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(reply);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "s");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
SET_FOREACH(domain, m->trust_anchor.negative_by_name, i) {
|
||||
r = sd_bus_message_append(reply, "s", domain);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
DnsScope *s;
|
||||
@@ -1540,6 +1576,7 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||
SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0),
|
||||
SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
|
||||
SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
|
||||
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
|
||||
|
||||
SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
@@ -37,6 +37,10 @@ int manager_add_dns_server_by_string(Manager *m, DnsServerType type, const char
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Silently filter out 0.0.0.0 and 127.0.0.53 (our own stub DNS listener) */
|
||||
if (!dns_server_address_valid(family, &address))
|
||||
return 0;
|
||||
|
||||
/* Filter out duplicates */
|
||||
s = dns_server_find(manager_get_first_dns_server(m, type), family, &address, ifindex);
|
||||
if (s) {
|
||||
|
||||
@@ -87,6 +87,10 @@ static inline unsigned dns_answer_size(DnsAnswer *a) {
|
||||
return a ? a->n_rrs : 0;
|
||||
}
|
||||
|
||||
static inline bool dns_answer_isempty(DnsAnswer *a) {
|
||||
return dns_answer_size(a) <= 0;
|
||||
}
|
||||
|
||||
void dns_answer_dump(DnsAnswer *answer, FILE *f);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsAnswer*, dns_answer_unref);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user