summaryrefslogtreecommitdiff
path: root/src/systemd
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-07-26 09:41:00 +0200
committerThomas Haller <thaller@redhat.com>2019-07-26 14:45:24 +0200
commit6a325673cf194accecb48722d810dad39fc266e1 (patch)
tree774dec9548f70726b738745e164fcc6ec2bf0dba /src/systemd
parent55c47d4efa5969db32499c769d89709ccef80887 (diff)
downloadNetworkManager-6a325673cf194accecb48722d810dad39fc266e1.tar.gz
systemd: update code from upstream (2019-07-26)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=608807c163921b0dfbaf646b3ec19fc9b71e6451 ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files -z :/src/systemd/src/ \ :/shared/systemd/src/ \ :/shared/nm-utils/unaligned.h | \ xargs -0 rm -f nm_copy_sd_shared() { mkdir -p "./shared/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1" } nm_copy_sd_core() { mkdir -p "./src/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/systemd/$1" } nm_copy_sd_nmutils() { mkdir -p "./shared/nm-utils/" cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}" } nm_copy_sd_core "src/libsystemd-network/arp-util.c" nm_copy_sd_core "src/libsystemd-network/arp-util.h" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h" nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c" nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h" nm_copy_sd_core "src/libsystemd-network/lldp-internal.h" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h" nm_copy_sd_core "src/libsystemd-network/lldp-network.c" nm_copy_sd_core "src/libsystemd-network/lldp-network.h" nm_copy_sd_core "src/libsystemd-network/network-internal.c" nm_copy_sd_core "src/libsystemd-network/network-internal.h" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c" nm_copy_sd_core "src/libsystemd-network/sd-lldp.c" nm_copy_sd_core "src/libsystemd/sd-event/event-source.h" nm_copy_sd_core "src/libsystemd/sd-event/event-util.c" nm_copy_sd_core "src/libsystemd/sd-event/event-util.h" nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h" nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c" nm_copy_sd_core "src/systemd/_sd-common.h" nm_copy_sd_core "src/systemd/sd-dhcp-client.h" nm_copy_sd_core "src/systemd/sd-dhcp-lease.h" nm_copy_sd_core "src/systemd/sd-dhcp6-client.h" nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h" nm_copy_sd_core "src/systemd/sd-event.h" nm_copy_sd_core "src/systemd/sd-id128.h" nm_copy_sd_core "src/systemd/sd-ipv4acd.h" nm_copy_sd_core "src/systemd/sd-ipv4ll.h" nm_copy_sd_core "src/systemd/sd-lldp.h" nm_copy_sd_core "src/systemd/sd-ndisc.h" nm_copy_sd_nmutils "src/basic/unaligned.h" nm_copy_sd_shared "src/basic/alloc-util.c" nm_copy_sd_shared "src/basic/alloc-util.h" nm_copy_sd_shared "src/basic/async.h" nm_copy_sd_shared "src/basic/env-file.c" nm_copy_sd_shared "src/basic/env-file.h" nm_copy_sd_shared "src/basic/env-util.c" nm_copy_sd_shared "src/basic/env-util.h" nm_copy_sd_shared "src/basic/errno-util.h" nm_copy_sd_shared "src/basic/escape.c" nm_copy_sd_shared "src/basic/escape.h" nm_copy_sd_shared "src/basic/ether-addr-util.c" nm_copy_sd_shared "src/basic/ether-addr-util.h" nm_copy_sd_shared "src/basic/extract-word.c" nm_copy_sd_shared "src/basic/extract-word.h" nm_copy_sd_shared "src/basic/fd-util.c" nm_copy_sd_shared "src/basic/fd-util.h" nm_copy_sd_shared "src/basic/fileio.c" nm_copy_sd_shared "src/basic/fileio.h" nm_copy_sd_shared "src/basic/format-util.c" nm_copy_sd_shared "src/basic/format-util.h" nm_copy_sd_shared "src/basic/fs-util.c" nm_copy_sd_shared "src/basic/fs-util.h" nm_copy_sd_shared "src/basic/hash-funcs.c" nm_copy_sd_shared "src/basic/hash-funcs.h" nm_copy_sd_shared "src/basic/hashmap.c" nm_copy_sd_shared "src/basic/hashmap.h" nm_copy_sd_shared "src/basic/hexdecoct.c" nm_copy_sd_shared "src/basic/hexdecoct.h" nm_copy_sd_shared "src/basic/hostname-util.c" nm_copy_sd_shared "src/basic/hostname-util.h" nm_copy_sd_shared "src/basic/in-addr-util.c" nm_copy_sd_shared "src/basic/in-addr-util.h" nm_copy_sd_shared "src/basic/io-util.c" nm_copy_sd_shared "src/basic/io-util.h" nm_copy_sd_shared "src/basic/list.h" nm_copy_sd_shared "src/basic/log.h" nm_copy_sd_shared "src/basic/macro.h" nm_copy_sd_shared "src/basic/memory-util.c" nm_copy_sd_shared "src/basic/memory-util.h" nm_copy_sd_shared "src/basic/mempool.c" nm_copy_sd_shared "src/basic/mempool.h" nm_copy_sd_shared "src/basic/missing_fcntl.h" nm_copy_sd_shared "src/basic/missing_socket.h" nm_copy_sd_shared "src/basic/missing_stat.h" nm_copy_sd_shared "src/basic/missing_type.h" nm_copy_sd_shared "src/basic/parse-util.c" nm_copy_sd_shared "src/basic/parse-util.h" nm_copy_sd_shared "src/basic/path-util.c" nm_copy_sd_shared "src/basic/path-util.h" nm_copy_sd_shared "src/basic/prioq.c" nm_copy_sd_shared "src/basic/prioq.h" nm_copy_sd_shared "src/basic/process-util.c" nm_copy_sd_shared "src/basic/process-util.h" nm_copy_sd_shared "src/basic/random-util.c" nm_copy_sd_shared "src/basic/random-util.h" nm_copy_sd_shared "src/basic/set.h" nm_copy_sd_shared "src/basic/signal-util.h" nm_copy_sd_shared "src/basic/siphash24.h" nm_copy_sd_shared "src/basic/socket-util.c" nm_copy_sd_shared "src/basic/socket-util.h" nm_copy_sd_shared "src/basic/sort-util.h" nm_copy_sd_shared "src/basic/sparse-endian.h" nm_copy_sd_shared "src/basic/stat-util.c" nm_copy_sd_shared "src/basic/stat-util.h" nm_copy_sd_shared "src/basic/stdio-util.h" nm_copy_sd_shared "src/basic/string-table.c" nm_copy_sd_shared "src/basic/string-table.h" nm_copy_sd_shared "src/basic/string-util.c" nm_copy_sd_shared "src/basic/string-util.h" nm_copy_sd_shared "src/basic/strv.c" nm_copy_sd_shared "src/basic/strv.h" nm_copy_sd_shared "src/basic/strxcpyx.c" nm_copy_sd_shared "src/basic/strxcpyx.h" nm_copy_sd_shared "src/basic/time-util.c" nm_copy_sd_shared "src/basic/time-util.h" nm_copy_sd_shared "src/basic/tmpfile-util.c" nm_copy_sd_shared "src/basic/tmpfile-util.h" nm_copy_sd_shared "src/basic/umask-util.h" nm_copy_sd_shared "src/basic/utf8.c" nm_copy_sd_shared "src/basic/utf8.h" nm_copy_sd_shared "src/basic/util.c" nm_copy_sd_shared "src/basic/util.h" nm_copy_sd_shared "src/shared/dns-domain.c" nm_copy_sd_shared "src/shared/dns-domain.h"
Diffstat (limited to 'src/systemd')
-rw-r--r--src/systemd/src/libsystemd-network/arp-util.c3
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-internal.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-internal.h2
-rw-r--r--src/systemd/src/libsystemd-network/lldp-internal.h2
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c1
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-lease.c16
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4acd.c3
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4ll.c2
-rw-r--r--src/systemd/src/libsystemd/sd-event/sd-event.c14
-rw-r--r--src/systemd/src/shared/dns-domain.c1375
-rw-r--r--src/systemd/src/shared/dns-domain.h112
-rw-r--r--src/systemd/src/systemd/sd-id128.h1
14 files changed, 23 insertions, 1514 deletions
diff --git a/src/systemd/src/libsystemd-network/arp-util.c b/src/systemd/src/libsystemd-network/arp-util.c
index 3a86f3f077..ac601a4efa 100644
--- a/src/systemd/src/libsystemd-network/arp-util.c
+++ b/src/systemd/src/libsystemd-network/arp-util.c
@@ -3,8 +3,9 @@
Copyright © 2014 Axis Communications AB. All rights reserved.
***/
-#include <linux/filter.h>
#include <arpa/inet.h>
+#include <linux/filter.h>
+#include <netinet/if_ether.h>
#include "arp-util.h"
#include "fd-util.h"
diff --git a/src/systemd/src/libsystemd-network/dhcp-internal.h b/src/systemd/src/libsystemd-network/dhcp-internal.h
index a0f9c2299f..e0269b5456 100644
--- a/src/systemd/src/libsystemd-network/dhcp-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp-internal.h
@@ -51,5 +51,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui
#define DHCP_CLIENT_DONT_DESTROY(client) \
_cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
-#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
+#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__)
diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h
index 157fc0aadd..f28ba68dd1 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h
@@ -79,7 +79,7 @@ struct DHCP6IA {
typedef struct DHCP6IA DHCP6IA;
-#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__)
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
diff --git a/src/systemd/src/libsystemd-network/lldp-internal.h b/src/systemd/src/libsystemd-network/lldp-internal.h
index 88b54933c3..9598438dba 100644
--- a/src/systemd/src/libsystemd-network/lldp-internal.h
+++ b/src/systemd/src/libsystemd-network/lldp-internal.h
@@ -32,7 +32,7 @@ struct sd_lldp {
struct ether_addr filter_address;
};
-#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
+#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__)
const char* lldp_event_to_string(sd_lldp_event e) _const_;
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index 1f2e5c7e65..f18ec88300 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -254,7 +254,7 @@ int config_parse_match_strv(
for (;;) {
_cleanup_free_ char *word = NULL, *k = NULL;
- r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
+ r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
if (r == 0)
return 0;
if (r == -ENOMEM)
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index b0f0f84937..85238c21d1 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -576,7 +576,7 @@ static void client_stop(sd_dhcp_client *client, int error) {
assert(client);
if (error < 0)
- log_dhcp_client(client, "STOPPED: %s", strerror(-error));
+ log_dhcp_client_errno(client, error, "STOPPED: %m");
else if (error == SD_DHCP_CLIENT_EVENT_STOP)
log_dhcp_client(client, "STOPPED");
else
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 68b41dfb6c..d7a5349c70 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -6,6 +6,7 @@
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
+#include <linux/if_arp.h>
#include <linux/if_infiniband.h>
#include "sd-dhcp6-client.h"
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
index 8b424811ad..8aebb53c87 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
@@ -205,12 +205,8 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->dns,
lease->dns_count,
&lease->dns_allocated);
- if (r < 0) {
- log_dhcp6_client(client, "Invalid DNS server option: %s",
- strerror(-r));
-
- return r;
- }
+ if (r < 0)
+ return log_dhcp6_client_errno(client, r, "Invalid DNS server option: %m");
lease->dns_count = r;
@@ -336,12 +332,8 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen)
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp,
lease->ntp_count,
&lease->ntp_allocated);
- if (r < 0) {
- log_dhcp6_client(client, "Invalid SNTP server option: %s",
- strerror(-r));
-
- return r;
- }
+ if (r < 0)
+ return log_dhcp6_client_errno(client, r, "Invalid SNTP server option: %m");
lease->ntp_count = r;
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
index c8e34497fd..5a24f38ae9 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
@@ -5,6 +5,7 @@
#include <arpa/inet.h>
#include <errno.h>
+#include <netinet/if_ether.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -72,7 +73,7 @@ struct sd_ipv4acd {
void* userdata;
};
-#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__)
+#define log_ipv4acd_errno(acd, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4ACD: " fmt, ##__VA_ARGS__)
#define log_ipv4acd(acd, fmt, ...) log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__)
static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_counter) {
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c
index a59a952326..3104d8c5a8 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c
@@ -50,7 +50,7 @@ struct sd_ipv4ll {
void* userdata;
};
-#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
+#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
#define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__)
static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata);
diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c
index 09285c19d8..5adbceeb02 100644
--- a/src/systemd/src/libsystemd/sd-event/sd-event.c
+++ b/src/systemd/src/libsystemd/sd-event/sd-event.c
@@ -23,6 +23,7 @@
#include "signal-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strxcpyx.h"
#include "time-util.h"
#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
@@ -3248,15 +3249,16 @@ _public_ int sd_event_dispatch(sd_event *e) {
}
static void event_log_delays(sd_event *e) {
- char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1];
- unsigned i;
- int o;
+ char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1], *p;
+ size_t l, i;
- for (i = o = 0; i < ELEMENTSOF(e->delays); i++) {
- o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]);
+ p = b;
+ l = sizeof(b);
+ for (i = 0; i < ELEMENTSOF(e->delays); i++) {
+ l = strpcpyf(&p, l, "%u ", e->delays[i]);
e->delays[i] = 0;
}
- log_debug("Event loop iterations: %.*s", o, b);
+ log_debug("Event loop iterations: %s", b);
}
_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
diff --git a/src/systemd/src/shared/dns-domain.c b/src/systemd/src/shared/dns-domain.c
deleted file mode 100644
index f62ad0a0f5..0000000000
--- a/src/systemd/src/shared/dns-domain.c
+++ /dev/null
@@ -1,1375 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#if HAVE_LIBIDN2
-# include <idn2.h>
-#elif HAVE_LIBIDN
-# include <idna.h>
-# include <stringprep.h>
-#endif
-
-#include <endian.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include "alloc-util.h"
-#include "dns-domain.h"
-#include "hashmap.h"
-#include "hexdecoct.h"
-#include "hostname-util.h"
-#include "in-addr-util.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "utf8.h"
-
-int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags) {
- const char *n;
- char *d, last_char = 0;
- int r = 0;
-
- assert(name);
- assert(*name);
-
- n = *name;
- d = dest;
-
- for (;;) {
- if (IN_SET(*n, 0, '.')) {
- if (FLAGS_SET(flags, DNS_LABEL_LDH) && last_char == '-')
- /* Trailing dash */
- return -EINVAL;
-
- if (*n == '.')
- n++;
- break;
- }
-
- if (r >= DNS_LABEL_MAX)
- return -EINVAL;
-
- if (sz <= 0)
- return -ENOBUFS;
-
- if (*n == '\\') {
- /* Escaped character */
- if (FLAGS_SET(flags, DNS_LABEL_NO_ESCAPES))
- return -EINVAL;
-
- n++;
-
- if (*n == 0)
- /* Ending NUL */
- return -EINVAL;
-
- else if (IN_SET(*n, '\\', '.')) {
- /* Escaped backslash or dot */
-
- if (FLAGS_SET(flags, DNS_LABEL_LDH))
- return -EINVAL;
-
- last_char = *n;
- if (d)
- *(d++) = *n;
- sz--;
- r++;
- n++;
-
- } else if (n[0] >= '0' && n[0] <= '9') {
- unsigned k;
-
- /* Escaped literal ASCII character */
-
- if (!(n[1] >= '0' && n[1] <= '9') ||
- !(n[2] >= '0' && n[2] <= '9'))
- return -EINVAL;
-
- k = ((unsigned) (n[0] - '0') * 100) +
- ((unsigned) (n[1] - '0') * 10) +
- ((unsigned) (n[2] - '0'));
-
- /* Don't allow anything that doesn't
- * fit in 8bit. Note that we do allow
- * control characters, as some servers
- * (e.g. cloudflare) are happy to
- * generate labels with them
- * inside. */
- if (k > 255)
- return -EINVAL;
-
- if (FLAGS_SET(flags, DNS_LABEL_LDH) &&
- !valid_ldh_char((char) k))
- return -EINVAL;
-
- last_char = (char) k;
- if (d)
- *(d++) = (char) k;
- sz--;
- r++;
-
- n += 3;
- } else
- return -EINVAL;
-
- } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) {
-
- /* Normal character */
-
- if (FLAGS_SET(flags, DNS_LABEL_LDH)) {
- if (!valid_ldh_char(*n))
- return -EINVAL;
- if (r == 0 && *n == '-')
- /* Leading dash */
- return -EINVAL;
- }
-
- last_char = *n;
- if (d)
- *(d++) = *n;
- sz--;
- r++;
- n++;
- } else
- return -EINVAL;
- }
-
- /* Empty label that is not at the end? */
- if (r == 0 && *n)
- return -EINVAL;
-
- /* More than one trailing dot? */
- if (*n == '.')
- return -EINVAL;
-
- if (sz >= 1 && d)
- *d = 0;
-
- *name = n;
- return r;
-}
-
-/* @label_terminal: terminal character of a label, updated to point to the terminal character of
- * the previous label (always skipping one dot) or to NULL if there are no more
- * labels. */
-int dns_label_unescape_suffix(const char *name, const char **label_terminal, char *dest, size_t sz) {
- const char *terminal;
- int r;
-
- assert(name);
- assert(label_terminal);
- assert(dest);
-
- /* no more labels */
- if (!*label_terminal) {
- if (sz >= 1)
- *dest = 0;
-
- return 0;
- }
-
- terminal = *label_terminal;
- assert(IN_SET(*terminal, 0, '.'));
-
- /* Skip current terminal character (and accept domain names ending it ".") */
- if (*terminal == 0)
- terminal--;
- if (terminal >= name && *terminal == '.')
- terminal--;
-
- /* Point name to the last label, and terminal to the preceding terminal symbol (or make it a NULL pointer) */
- for (;;) {
- if (terminal < name) {
- /* Reached the first label, so indicate that there are no more */
- terminal = NULL;
- break;
- }
-
- /* Find the start of the last label */
- if (*terminal == '.') {
- const char *y;
- unsigned slashes = 0;
-
- for (y = terminal - 1; y >= name && *y == '\\'; y--)
- slashes++;
-
- if (slashes % 2 == 0) {
- /* The '.' was not escaped */
- name = terminal + 1;
- break;
- } else {
- terminal = y;
- continue;
- }
- }
-
- terminal--;
- }
-
- r = dns_label_unescape(&name, dest, sz, 0);
- if (r < 0)
- return r;
-
- *label_terminal = terminal;
-
- return r;
-}
-
-int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
- char *q;
-
- /* DNS labels must be between 1 and 63 characters long. A
- * zero-length label does not exist. See RFC 2182, Section
- * 11. */
-
- if (l <= 0 || l > DNS_LABEL_MAX)
- return -EINVAL;
- if (sz < 1)
- return -ENOBUFS;
-
- assert(p);
- assert(dest);
-
- q = dest;
- while (l > 0) {
-
- if (IN_SET(*p, '.', '\\')) {
-
- /* Dot or backslash */
-
- if (sz < 3)
- return -ENOBUFS;
-
- *(q++) = '\\';
- *(q++) = *p;
-
- sz -= 2;
-
- } else if (IN_SET(*p, '_', '-') ||
- (*p >= '0' && *p <= '9') ||
- (*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z')) {
-
- /* Proper character */
-
- if (sz < 2)
- return -ENOBUFS;
-
- *(q++) = *p;
- sz -= 1;
-
- } else {
-
- /* Everything else */
-
- if (sz < 5)
- return -ENOBUFS;
-
- *(q++) = '\\';
- *(q++) = '0' + (char) ((uint8_t) *p / 100);
- *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10);
- *(q++) = '0' + (char) ((uint8_t) *p % 10);
-
- sz -= 4;
- }
-
- p++;
- l--;
- }
-
- *q = 0;
- return (int) (q - dest);
-}
-
-int dns_label_escape_new(const char *p, size_t l, char **ret) {
- _cleanup_free_ char *s = NULL;
- int r;
-
- assert(p);
- assert(ret);
-
- if (l <= 0 || l > DNS_LABEL_MAX)
- return -EINVAL;
-
- s = new(char, DNS_LABEL_ESCAPED_MAX);
- if (!s)
- return -ENOMEM;
-
- r = dns_label_escape(p, l, s, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- return r;
-
- *ret = TAKE_PTR(s);
-
- return r;
-}
-
-#if HAVE_LIBIDN
-int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
- _cleanup_free_ uint32_t *input = NULL;
- size_t input_size, l;
- const char *p;
- bool contains_8bit = false;
- char buffer[DNS_LABEL_MAX+1];
-
- assert(encoded);
- assert(decoded);
-
- /* Converts an U-label into an A-label */
-
- if (encoded_size <= 0)
- return -EINVAL;
-
- for (p = encoded; p < encoded + encoded_size; p++)
- if ((uint8_t) *p > 127)
- contains_8bit = true;
-
- if (!contains_8bit) {
- if (encoded_size > DNS_LABEL_MAX)
- return -EINVAL;
-
- return 0;
- }
-
- input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
- if (!input)
- return -ENOMEM;
-
- if (idna_to_ascii_4i(input, input_size, buffer, 0) != 0)
- return -EINVAL;
-
- l = strlen(buffer);
-
- /* Verify that the result is not longer than one DNS label. */
- if (l <= 0 || l > DNS_LABEL_MAX)
- return -EINVAL;
- if (l > decoded_max)
- return -ENOBUFS;
-
- memcpy(decoded, buffer, l);
-
- /* If there's room, append a trailing NUL byte, but only then */
- if (decoded_max > l)
- decoded[l] = 0;
-
- return (int) l;
-}
-
-int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
- size_t input_size, output_size;
- _cleanup_free_ uint32_t *input = NULL;
- _cleanup_free_ char *result = NULL;
- uint32_t *output = NULL;
- size_t w;
-
- /* To be invoked after unescaping. Converts an A-label into an U-label. */
-
- assert(encoded);
- assert(decoded);
-
- if (encoded_size <= 0 || encoded_size > DNS_LABEL_MAX)
- return -EINVAL;
-
- if (!memory_startswith(encoded, encoded_size, IDNA_ACE_PREFIX))
- return 0;
-
- input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
- if (!input)
- return -ENOMEM;
-
- output_size = input_size;
- output = newa(uint32_t, output_size);
-
- idna_to_unicode_44i(input, input_size, output, &output_size, 0);
-
- result = stringprep_ucs4_to_utf8(output, output_size, NULL, &w);
- if (!result)
- return -ENOMEM;
- if (w <= 0)
- return -EINVAL;
- if (w > decoded_max)
- return -ENOBUFS;
-
- memcpy(decoded, result, w);
-
- /* Append trailing NUL byte if there's space, but only then. */
- if (decoded_max > w)
- decoded[w] = 0;
-
- return w;
-}
-#endif
-
-int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_ret) {
- _cleanup_free_ char *ret = NULL;
- size_t n = 0, allocated = 0;
- const char *p;
- bool first = true;
- int r;
-
- if (a)
- p = a;
- else if (b)
- p = TAKE_PTR(b);
- else
- goto finish;
-
- for (;;) {
- char label[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&p, label, sizeof label, flags);
- if (r < 0)
- return r;
- if (r == 0) {
- if (*p != 0)
- return -EINVAL;
-
- if (b) {
- /* Now continue with the second string, if there is one */
- p = TAKE_PTR(b);
- continue;
- }
-
- break;
- }
-
- if (_ret) {
- if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
- return -ENOMEM;
-
- r = dns_label_escape(label, r, ret + n + !first, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- return r;
-
- if (!first)
- ret[n] = '.';
- } else {
- char escaped[DNS_LABEL_ESCAPED_MAX];
-
- r = dns_label_escape(label, r, escaped, sizeof(escaped));
- if (r < 0)
- return r;
- }
-
- if (!first)
- n++;
- else
- first = false;
-
- n += r;
- }
-
-finish:
- if (n > DNS_HOSTNAME_MAX)
- return -EINVAL;
-
- if (_ret) {
- if (n == 0) {
- /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */
- if (!GREEDY_REALLOC(ret, allocated, 2))
- return -ENOMEM;
-
- ret[n++] = '.';
- } else {
- if (!GREEDY_REALLOC(ret, allocated, n + 1))
- return -ENOMEM;
- }
-
- ret[n] = 0;
- *_ret = TAKE_PTR(ret);
- }
-
- return 0;
-}
-
-void dns_name_hash_func(const char *p, struct siphash *state) {
- int r;
-
- assert(p);
-
- for (;;) {
- char label[DNS_LABEL_MAX+1];
-
- r = dns_label_unescape(&p, label, sizeof label, 0);
- if (r < 0)
- break;
- if (r == 0)
- break;
-
- ascii_strlower_n(label, r);
- siphash24_compress(label, r, state);
- siphash24_compress_byte(0, state); /* make sure foobar and foo.bar result in different hashes */
- }
-
- /* enforce that all names are terminated by the empty label */
- string_hash_func("", state);
-}
-
-int dns_name_compare_func(const char *a, const char *b) {
- const char *x, *y;
- int r, q;
-
- assert(a);
- assert(b);
-
- x = a + strlen(a);
- y = b + strlen(b);
-
- for (;;) {
- char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
-
- if (x == NULL && y == NULL)
- return 0;
-
- r = dns_label_unescape_suffix(a, &x, la, sizeof(la));
- q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb));
- if (r < 0 || q < 0)
- return CMP(r, q);
-
- r = ascii_strcasecmp_nn(la, r, lb, q);
- if (r != 0)
- return r;
- }
-}
-
-DEFINE_HASH_OPS(dns_name_hash_ops, char, dns_name_hash_func, dns_name_compare_func);
-
-int dns_name_equal(const char *x, const char *y) {
- int r, q;
-
- assert(x);
- assert(y);
-
- for (;;) {
- char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&x, la, sizeof la, 0);
- if (r < 0)
- return r;
-
- q = dns_label_unescape(&y, lb, sizeof lb, 0);
- if (q < 0)
- return q;
-
- if (r != q)
- return false;
- if (r == 0)
- return true;
-
- if (ascii_strcasecmp_n(la, lb, r) != 0)
- return false;
- }
-}
-
-int dns_name_endswith(const char *name, const char *suffix) {
- const char *n, *s, *saved_n = NULL;
- int r, q;
-
- assert(name);
- assert(suffix);
-
- n = name;
- s = suffix;
-
- for (;;) {
- char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&n, ln, sizeof ln, 0);
- if (r < 0)
- return r;
-
- if (!saved_n)
- saved_n = n;
-
- q = dns_label_unescape(&s, ls, sizeof ls, 0);
- if (q < 0)
- return q;
-
- if (r == 0 && q == 0)
- return true;
- if (r == 0 && saved_n == n)
- return false;
-
- if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
-
- /* Not the same, let's jump back, and try with the next label again */
- s = suffix;
- n = TAKE_PTR(saved_n);
- }
- }
-}
-
-int dns_name_startswith(const char *name, const char *prefix) {
- const char *n, *p;
- int r, q;
-
- assert(name);
- assert(prefix);
-
- n = name;
- p = prefix;
-
- for (;;) {
- char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&p, lp, sizeof lp, 0);
- if (r < 0)
- return r;
- if (r == 0)
- return true;
-
- q = dns_label_unescape(&n, ln, sizeof ln, 0);
- if (q < 0)
- return q;
-
- if (r != q)
- return false;
- if (ascii_strcasecmp_n(ln, lp, r) != 0)
- return false;
- }
-}
-
-int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
- const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
- int r, q;
-
- assert(name);
- assert(old_suffix);
- assert(new_suffix);
- assert(ret);
-
- n = name;
- s = old_suffix;
-
- for (;;) {
- char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
-
- if (!saved_before)
- saved_before = n;
-
- r = dns_label_unescape(&n, ln, sizeof ln, 0);
- if (r < 0)
- return r;
-
- if (!saved_after)
- saved_after = n;
-
- q = dns_label_unescape(&s, ls, sizeof ls, 0);
- if (q < 0)
- return q;
-
- if (r == 0 && q == 0)
- break;
- if (r == 0 && saved_after == n) {
- *ret = NULL; /* doesn't match */
- return 0;
- }
-
- if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
-
- /* Not the same, let's jump back, and try with the next label again */
- s = old_suffix;
- n = TAKE_PTR(saved_after);
- saved_before = NULL;
- }
- }
-
- /* Found it! Now generate the new name */
- prefix = strndupa(name, saved_before - name);
-
- r = dns_name_concat(prefix, new_suffix, 0, ret);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-int dns_name_between(const char *a, const char *b, const char *c) {
- /* Determine if b is strictly greater than a and strictly smaller than c.
- We consider the order of names to be circular, so that if a is
- strictly greater than c, we consider b to be between them if it is
- either greater than a or smaller than c. This is how the canonical
- DNS name order used in NSEC records work. */
-
- if (dns_name_compare_func(a, c) < 0)
- /*
- a and c are properly ordered:
- a<---b--->c
- */
- return dns_name_compare_func(a, b) < 0 &&
- dns_name_compare_func(b, c) < 0;
- else
- /*
- a and c are equal or 'reversed':
- <--b--c a----->
- or:
- <-----c a--b-->
- */
- return dns_name_compare_func(b, c) < 0 ||
- dns_name_compare_func(a, b) < 0;
-}
-
-int dns_name_reverse(int family, const union in_addr_union *a, char **ret) {
- const uint8_t *p;
- int r;
-
- assert(a);
- assert(ret);
-
- p = (const uint8_t*) a;
-
- if (family == AF_INET)
- r = asprintf(ret, "%u.%u.%u.%u.in-addr.arpa", p[3], p[2], p[1], p[0]);
- else if (family == AF_INET6)
- r = asprintf(ret, "%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.ip6.arpa",
- hexchar(p[15] & 0xF), hexchar(p[15] >> 4), hexchar(p[14] & 0xF), hexchar(p[14] >> 4),
- hexchar(p[13] & 0xF), hexchar(p[13] >> 4), hexchar(p[12] & 0xF), hexchar(p[12] >> 4),
- hexchar(p[11] & 0xF), hexchar(p[11] >> 4), hexchar(p[10] & 0xF), hexchar(p[10] >> 4),
- hexchar(p[ 9] & 0xF), hexchar(p[ 9] >> 4), hexchar(p[ 8] & 0xF), hexchar(p[ 8] >> 4),
- hexchar(p[ 7] & 0xF), hexchar(p[ 7] >> 4), hexchar(p[ 6] & 0xF), hexchar(p[ 6] >> 4),
- hexchar(p[ 5] & 0xF), hexchar(p[ 5] >> 4), hexchar(p[ 4] & 0xF), hexchar(p[ 4] >> 4),
- hexchar(p[ 3] & 0xF), hexchar(p[ 3] >> 4), hexchar(p[ 2] & 0xF), hexchar(p[ 2] >> 4),
- hexchar(p[ 1] & 0xF), hexchar(p[ 1] >> 4), hexchar(p[ 0] & 0xF), hexchar(p[ 0] >> 4));
- else
- return -EAFNOSUPPORT;
- if (r < 0)
- return -ENOMEM;
-
- return 0;
-}
-
-int dns_name_address(const char *p, int *family, union in_addr_union *address) {
- int r;
-
- assert(p);
- assert(family);
- assert(address);
-
- r = dns_name_endswith(p, "in-addr.arpa");
- if (r < 0)
- return r;
- if (r > 0) {
- uint8_t a[4];
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(a); i++) {
- char label[DNS_LABEL_MAX+1];
-
- r = dns_label_unescape(&p, label, sizeof label, 0);
- if (r < 0)
- return r;
- if (r == 0)
- return -EINVAL;
- if (r > 3)
- return -EINVAL;
-
- r = safe_atou8(label, &a[i]);
- if (r < 0)
- return r;
- }
-
- r = dns_name_equal(p, "in-addr.arpa");
- if (r <= 0)
- return r;
-
- *family = AF_INET;
- address->in.s_addr = htobe32(((uint32_t) a[3] << 24) |
- ((uint32_t) a[2] << 16) |
- ((uint32_t) a[1] << 8) |
- (uint32_t) a[0]);
-
- return 1;
- }
-
- r = dns_name_endswith(p, "ip6.arpa");
- if (r < 0)
- return r;
- if (r > 0) {
- struct in6_addr a;
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(a.s6_addr); i++) {
- char label[DNS_LABEL_MAX+1];
- int x, y;
-
- r = dns_label_unescape(&p, label, sizeof label, 0);
- if (r <= 0)
- return r;
- if (r != 1)
- return -EINVAL;
- x = unhexchar(label[0]);
- if (x < 0)
- return -EINVAL;
-
- r = dns_label_unescape(&p, label, sizeof label, 0);
- if (r <= 0)
- return r;
- if (r != 1)
- return -EINVAL;
- y = unhexchar(label[0]);
- if (y < 0)
- return -EINVAL;
-
- a.s6_addr[ELEMENTSOF(a.s6_addr) - i - 1] = (uint8_t) y << 4 | (uint8_t) x;
- }
-
- r = dns_name_equal(p, "ip6.arpa");
- if (r <= 0)
- return r;
-
- *family = AF_INET6;
- address->in6 = a;
- return 1;
- }
-
- return 0;
-}
-
-bool dns_name_is_root(const char *name) {
-
- assert(name);
-
- /* There are exactly two ways to encode the root domain name:
- * as empty string, or with a single dot. */
-
- return STR_IN_SET(name, "", ".");
-}
-
-bool dns_name_is_single_label(const char *name) {
- int r;
-
- assert(name);
-
- r = dns_name_parent(&name);
- if (r <= 0)
- return false;
-
- return dns_name_is_root(name);
-}
-
-/* Encode a domain name according to RFC 1035 Section 3.1, without compression */
-int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical) {
- uint8_t *label_length, *out;
- int r;
-
- assert(domain);
- assert(buffer);
-
- out = buffer;
-
- do {
- /* Reserve a byte for label length */
- if (len <= 0)
- return -ENOBUFS;
- len--;
- label_length = out;
- out++;
-
- /* Convert and copy a single label. Note that
- * dns_label_unescape() returns 0 when it hits the end
- * of the domain name, which we rely on here to encode
- * the trailing NUL byte. */
- r = dns_label_unescape(&domain, (char *) out, len, 0);
- if (r < 0)
- return r;
-
- /* Optionally, output the name in DNSSEC canonical
- * format, as described in RFC 4034, section 6.2. Or
- * in other words: in lower-case. */
- if (canonical)
- ascii_strlower_n((char*) out, (size_t) r);
-
- /* Fill label length, move forward */
- *label_length = r;
- out += r;
- len -= r;
-
- } while (r != 0);
-
- /* Verify the maximum size of the encoded name. The trailing
- * dot + NUL byte account are included this time, hence
- * compare against DNS_HOSTNAME_MAX + 2 (which is 255) this
- * time. */
- if (out - buffer > DNS_HOSTNAME_MAX + 2)
- return -EINVAL;
-
- return out - buffer;
-}
-
-static bool srv_type_label_is_valid(const char *label, size_t n) {
- size_t k;
-
- assert(label);
-
- if (n < 2) /* Label needs to be at least 2 chars long */
- return false;
-
- if (label[0] != '_') /* First label char needs to be underscore */
- return false;
-
- /* Second char must be a letter */
- if (!(label[1] >= 'A' && label[1] <= 'Z') &&
- !(label[1] >= 'a' && label[1] <= 'z'))
- return false;
-
- /* Third and further chars must be alphanumeric or a hyphen */
- for (k = 2; k < n; k++) {
- if (!(label[k] >= 'A' && label[k] <= 'Z') &&
- !(label[k] >= 'a' && label[k] <= 'z') &&
- !(label[k] >= '0' && label[k] <= '9') &&
- label[k] != '-')
- return false;
- }
-
- return true;
-}
-
-bool dns_srv_type_is_valid(const char *name) {
- unsigned c = 0;
- int r;
-
- if (!name)
- return false;
-
- for (;;) {
- char label[DNS_LABEL_MAX];
-
- /* This more or less implements RFC 6335, Section 5.1 */
-
- r = dns_label_unescape(&name, label, sizeof label, 0);
- if (r < 0)
- return false;
- if (r == 0)
- break;
-
- if (c >= 2)
- return false;
-
- if (!srv_type_label_is_valid(label, r))
- return false;
-
- c++;
- }
-
- return c == 2; /* exactly two labels */
-}
-
-bool dnssd_srv_type_is_valid(const char *name) {
- return dns_srv_type_is_valid(name) &&
- ((dns_name_endswith(name, "_tcp") > 0) ||
- (dns_name_endswith(name, "_udp") > 0)); /* Specific to DNS-SD. RFC 6763, Section 7 */
-}
-
-bool dns_service_name_is_valid(const char *name) {
- size_t l;
-
- /* This more or less implements RFC 6763, Section 4.1.1 */
-
- if (!name)
- return false;
-
- if (!utf8_is_valid(name))
- return false;
-
- if (string_has_cc(name, NULL))
- return false;
-
- l = strlen(name);
- if (l <= 0)
- return false;
- if (l > 63)
- return false;
-
- return true;
-}
-
-int dns_service_join(const char *name, const char *type, const char *domain, char **ret) {
- char escaped[DNS_LABEL_ESCAPED_MAX];
- _cleanup_free_ char *n = NULL;
- int r;
-
- assert(type);
- assert(domain);
- assert(ret);
-
- if (!dns_srv_type_is_valid(type))
- return -EINVAL;
-
- if (!name)
- return dns_name_concat(type, domain, 0, ret);
-
- if (!dns_service_name_is_valid(name))
- return -EINVAL;
-
- r = dns_label_escape(name, strlen(name), escaped, sizeof(escaped));
- if (r < 0)
- return r;
-
- r = dns_name_concat(type, domain, 0, &n);
- if (r < 0)
- return r;
-
- return dns_name_concat(escaped, n, 0, ret);
-}
-
-static bool dns_service_name_label_is_valid(const char *label, size_t n) {
- char *s;
-
- assert(label);
-
- if (memchr(label, 0, n))
- return false;
-
- s = strndupa(label, n);
- return dns_service_name_is_valid(s);
-}
-
-int dns_service_split(const char *joined, char **_name, char **_type, char **_domain) {
- _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
- const char *p = joined, *q = NULL, *d = NULL;
- char a[DNS_LABEL_MAX], b[DNS_LABEL_MAX], c[DNS_LABEL_MAX];
- int an, bn, cn, r;
- unsigned x = 0;
-
- assert(joined);
-
- /* Get first label from the full name */
- an = dns_label_unescape(&p, a, sizeof(a), 0);
- if (an < 0)
- return an;
-
- if (an > 0) {
- x++;
-
- /* If there was a first label, try to get the second one */
- bn = dns_label_unescape(&p, b, sizeof(b), 0);
- if (bn < 0)
- return bn;
-
- if (bn > 0) {
- x++;
-
- /* If there was a second label, try to get the third one */
- q = p;
- cn = dns_label_unescape(&p, c, sizeof(c), 0);
- if (cn < 0)
- return cn;
-
- if (cn > 0)
- x++;
- } else
- cn = 0;
- } else
- an = 0;
-
- if (x >= 2 && srv_type_label_is_valid(b, bn)) {
-
- if (x >= 3 && srv_type_label_is_valid(c, cn)) {
-
- if (dns_service_name_label_is_valid(a, an)) {
- /* OK, got <name> . <type> . <type2> . <domain> */
-
- name = strndup(a, an);
- if (!name)
- return -ENOMEM;
-
- type = strjoin(b, ".", c);
- if (!type)
- return -ENOMEM;
-
- d = p;
- goto finish;
- }
-
- } else if (srv_type_label_is_valid(a, an)) {
-
- /* OK, got <type> . <type2> . <domain> */
-
- name = NULL;
-
- type = strjoin(a, ".", b);
- if (!type)
- return -ENOMEM;
-
- d = q;
- goto finish;
- }
- }
-
- name = NULL;
- type = NULL;
- d = joined;
-
-finish:
- r = dns_name_normalize(d, 0, &domain);
- if (r < 0)
- return r;
-
- if (_domain)
- *_domain = TAKE_PTR(domain);
-
- if (_type)
- *_type = TAKE_PTR(type);
-
- if (_name)
- *_name = TAKE_PTR(name);
-
- return 0;
-}
-
-static int dns_name_build_suffix_table(const char *name, const char *table[]) {
- const char *p;
- unsigned n = 0;
- int r;
-
- assert(name);
- assert(table);
-
- p = name;
- for (;;) {
- if (n > DNS_N_LABELS_MAX)
- return -EINVAL;
-
- table[n] = p;
- r = dns_name_parent(&p);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- n++;
- }
-
- return (int) n;
-}
-
-int dns_name_suffix(const char *name, unsigned n_labels, const char **ret) {
- const char* labels[DNS_N_LABELS_MAX+1];
- int n;
-
- assert(name);
- assert(ret);
-
- n = dns_name_build_suffix_table(name, labels);
- if (n < 0)
- return n;
-
- if ((unsigned) n < n_labels)
- return -EINVAL;
-
- *ret = labels[n - n_labels];
- return (int) (n - n_labels);
-}
-
-int dns_name_skip(const char *a, unsigned n_labels, const char **ret) {
- int r;
-
- assert(a);
- assert(ret);
-
- for (; n_labels > 0; n_labels--) {
- r = dns_name_parent(&a);
- if (r < 0)
- return r;
- if (r == 0) {
- *ret = "";
- return 0;
- }
- }
-
- *ret = a;
- return 1;
-}
-
-int dns_name_count_labels(const char *name) {
- unsigned n = 0;
- const char *p;
- int r;
-
- assert(name);
-
- p = name;
- for (;;) {
- r = dns_name_parent(&p);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- if (n >= DNS_N_LABELS_MAX)
- return -EINVAL;
-
- n++;
- }
-
- return (int) n;
-}
-
-int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b) {
- int r;
-
- assert(a);
- assert(b);
-
- r = dns_name_skip(a, n_labels, &a);
- if (r <= 0)
- return r;
-
- return dns_name_equal(a, b);
-}
-
-int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
- const char *a_labels[DNS_N_LABELS_MAX+1], *b_labels[DNS_N_LABELS_MAX+1];
- int n = 0, m = 0, k = 0, r, q;
-
- assert(a);
- assert(b);
- assert(ret);
-
- /* Determines the common suffix of domain names a and b */
-
- n = dns_name_build_suffix_table(a, a_labels);
- if (n < 0)
- return n;
-
- m = dns_name_build_suffix_table(b, b_labels);
- if (m < 0)
- return m;
-
- for (;;) {
- char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
- const char *x, *y;
-
- if (k >= n || k >= m) {
- *ret = a_labels[n - k];
- return 0;
- }
-
- x = a_labels[n - 1 - k];
- r = dns_label_unescape(&x, la, sizeof la, 0);
- if (r < 0)
- return r;
-
- y = b_labels[m - 1 - k];
- q = dns_label_unescape(&y, lb, sizeof lb, 0);
- if (q < 0)
- return q;
-
- if (r != q || ascii_strcasecmp_n(la, lb, r) != 0) {
- *ret = a_labels[n - k];
- return 0;
- }
-
- k++;
- }
-}
-
-int dns_name_apply_idna(const char *name, char **ret) {
- /* Return negative on error, 0 if not implemented, positive on success. */
-
-#if HAVE_LIBIDN2
- int r;
- _cleanup_free_ char *t = NULL;
-
- assert(name);
- assert(ret);
-
- r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t,
- IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
- log_debug("idn2_lookup_u8: %s → %s", name, t);
- if (r == IDN2_OK) {
- if (!startswith(name, "xn--")) {
- _cleanup_free_ char *s = NULL;
-
- r = idn2_to_unicode_8z8z(t, &s, 0);
- if (r != IDN2_OK) {
- log_debug("idn2_to_unicode_8z8z(\"%s\") failed: %d/%s",
- t, r, idn2_strerror(r));
- return 0;
- }
-
- if (!streq_ptr(name, s)) {
- log_debug("idn2 roundtrip failed: \"%s\" → \"%s\" → \"%s\", ignoring.",
- name, t, s);
- return 0;
- }
- }
-
- *ret = TAKE_PTR(t);
-
- return 1; /* *ret has been written */
- }
-
- log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r));
- if (r == IDN2_2HYPHEN)
- /* The name has two hyphens — forbidden by IDNA2008 in some cases */
- return 0;
- if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
- return -ENOSPC;
- return -EINVAL;
-#elif HAVE_LIBIDN
- _cleanup_free_ char *buf = NULL;
- size_t n = 0, allocated = 0;
- bool first = true;
- int r, q;
-
- assert(name);
- assert(ret);
-
- for (;;) {
- char label[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&name, label, sizeof label, 0);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- q = dns_label_apply_idna(label, r, label, sizeof label);
- if (q < 0)
- return q;
- if (q > 0)
- r = q;
-
- if (!GREEDY_REALLOC(buf, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
- return -ENOMEM;
-
- r = dns_label_escape(label, r, buf + n + !first, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- return r;
-
- if (first)
- first = false;
- else
- buf[n++] = '.';
-
- n += r;
- }
-
- if (n > DNS_HOSTNAME_MAX)
- return -EINVAL;
-
- if (!GREEDY_REALLOC(buf, allocated, n + 1))
- return -ENOMEM;
-
- buf[n] = 0;
- *ret = TAKE_PTR(buf);
-
- return 1;
-#else
- return 0;
-#endif
-}
-
-int dns_name_is_valid_or_address(const char *name) {
- /* Returns > 0 if the specified name is either a valid IP address formatted as string or a valid DNS name */
-
- if (isempty(name))
- return 0;
-
- if (in_addr_from_string_auto(name, NULL, NULL) >= 0)
- return 1;
-
- return dns_name_is_valid(name);
-}
diff --git a/src/systemd/src/shared/dns-domain.h b/src/systemd/src/shared/dns-domain.h
deleted file mode 100644
index 6ed512c6b1..0000000000
--- a/src/systemd/src/shared/dns-domain.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "hashmap.h"
-#include "in-addr-util.h"
-
-/* Length of a single label, with all escaping removed, excluding any trailing dot or NUL byte */
-#define DNS_LABEL_MAX 63
-
-/* Worst case length of a single label, with all escaping applied and room for a trailing NUL byte. */
-#define DNS_LABEL_ESCAPED_MAX (DNS_LABEL_MAX*4+1)
-
-/* Maximum length of a full hostname, consisting of a series of unescaped labels, and no trailing dot or NUL byte */
-#define DNS_HOSTNAME_MAX 253
-
-/* Maximum length of a full hostname, on the wire, including the final NUL byte */
-#define DNS_WIRE_FORMAT_HOSTNAME_MAX 255
-
-/* Maximum number of labels per valid hostname */
-#define DNS_N_LABELS_MAX 127
-
-typedef enum DNSLabelFlags {
- DNS_LABEL_LDH = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
- DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */
-} DNSLabelFlags;
-
-int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags);
-int dns_label_unescape_suffix(const char *name, const char **label_end, char *dest, size_t sz);
-int dns_label_escape(const char *p, size_t l, char *dest, size_t sz);
-int dns_label_escape_new(const char *p, size_t l, char **ret);
-
-static inline int dns_name_parent(const char **name) {
- return dns_label_unescape(name, NULL, DNS_LABEL_MAX, 0);
-}
-
-#if HAVE_LIBIDN
-int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
-int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
-#endif
-
-int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret);
-
-static inline int dns_name_normalize(const char *s, DNSLabelFlags flags, char **ret) {
- /* dns_name_concat() normalizes as a side-effect */
- return dns_name_concat(s, NULL, flags, ret);
-}
-
-static inline int dns_name_is_valid(const char *s) {
- int r;
-
- /* dns_name_normalize() verifies as a side effect */
- r = dns_name_normalize(s, 0, NULL);
- if (r == -EINVAL)
- return 0;
- if (r < 0)
- return r;
- return 1;
-}
-
-static inline int dns_name_is_valid_ldh(const char *s) {
- int r;
-
- r = dns_name_concat(s, NULL, DNS_LABEL_LDH|DNS_LABEL_NO_ESCAPES, NULL);
- if (r == -EINVAL)
- return 0;
- if (r < 0)
- return r;
- return 1;
-}
-
-void dns_name_hash_func(const char *s, struct siphash *state);
-int dns_name_compare_func(const char *a, const char *b);
-extern const struct hash_ops dns_name_hash_ops;
-
-int dns_name_between(const char *a, const char *b, const char *c);
-int dns_name_equal(const char *x, const char *y);
-int dns_name_endswith(const char *name, const char *suffix);
-int dns_name_startswith(const char *name, const char *prefix);
-
-int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret);
-
-int dns_name_reverse(int family, const union in_addr_union *a, char **ret);
-int dns_name_address(const char *p, int *family, union in_addr_union *a);
-
-bool dns_name_is_root(const char *name);
-bool dns_name_is_single_label(const char *name);
-
-int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical);
-
-bool dns_srv_type_is_valid(const char *name);
-bool dnssd_srv_type_is_valid(const char *name);
-bool dns_service_name_is_valid(const char *name);
-
-int dns_service_join(const char *name, const char *type, const char *domain, char **ret);
-int dns_service_split(const char *joined, char **name, char **type, char **domain);
-
-int dns_name_suffix(const char *name, unsigned n_labels, const char **ret);
-int dns_name_count_labels(const char *name);
-
-int dns_name_skip(const char *a, unsigned n_labels, const char **ret);
-int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b);
-
-int dns_name_common_suffix(const char *a, const char *b, const char **ret);
-
-int dns_name_apply_idna(const char *name, char **ret);
-
-int dns_name_is_valid_or_address(const char *name);
diff --git a/src/systemd/src/systemd/sd-id128.h b/src/systemd/src/systemd/sd-id128.h
index c5fbe0a4f1..9b00b76ea6 100644
--- a/src/systemd/src/systemd/sd-id128.h
+++ b/src/systemd/src/systemd/sd-id128.h
@@ -54,7 +54,6 @@ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret);
#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
((const sd_id128_t) SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15))
-
/* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16
* times. It is hence not a good idea to call this macro with an
* expensive function as parameter or an expression with side