diff options
author | Thomas Haller <thaller@redhat.com> | 2019-07-26 09:41:00 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-07-26 14:45:24 +0200 |
commit | 6a325673cf194accecb48722d810dad39fc266e1 (patch) | |
tree | 774dec9548f70726b738745e164fcc6ec2bf0dba /src/systemd | |
parent | 55c47d4efa5969db32499c769d89709ccef80887 (diff) | |
download | NetworkManager-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.c | 3 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/dhcp-internal.h | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/dhcp6-internal.h | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/lldp-internal.h | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/network-internal.c | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-dhcp-client.c | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-dhcp6-client.c | 1 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-dhcp6-lease.c | 16 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-ipv4acd.c | 3 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-ipv4ll.c | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd/sd-event/sd-event.c | 14 | ||||
-rw-r--r-- | src/systemd/src/shared/dns-domain.c | 1375 | ||||
-rw-r--r-- | src/systemd/src/shared/dns-domain.h | 112 | ||||
-rw-r--r-- | src/systemd/src/systemd/sd-id128.h | 1 |
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 |