diff options
author | Thomas Haller <thaller@redhat.com> | 2018-10-04 00:19:48 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-10-05 00:20:48 +0200 |
commit | 56cc16cdf7013468e6ee2371712d3c34e6e52dcd (patch) | |
tree | f3956e86397cf9d498d7afd31db3b55fde554e1c | |
parent | f699fc644d8aa7f8f05cb7253e1e519f76cacf53 (diff) |
systemd: update code from upstream (2018-10-04)
This is a direct dump from systemd git.
======
SYSTEMD_DIR=../systemd
COMMIT=b62f9008668a5330c61b4de7e0d48147bcd1edf7
(
cd "$SYSTEMD_DIR"
git checkout "$COMMIT"
git reset --hard
git clean -fdx
)
git ls-files :/src/systemd/src/ \
:/shared/nm-utils/unaligned.h | \
xargs -d '\n' rm -f
nm_copy_sd() {
mkdir -p "./src/systemd/$(dirname "$1")"
cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}
nm_copy_sd_shared() {
mkdir -p "./shared/nm-utils/"
cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}
nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/env-util.c"
nm_copy_sd "src/basic/env-util.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stat-util.c"
nm_copy_sd "src/basic/stat-util.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
44 files changed, 645 insertions, 460 deletions
diff --git a/src/systemd/src/basic/env-util.c b/src/systemd/src/basic/env-util.c index a784a30e1..3b8130b03 100644 --- a/src/systemd/src/basic/env-util.c +++ b/src/systemd/src/basic/env-util.c @@ -114,7 +114,7 @@ bool strv_env_is_valid(char **e) { if (!env_assignment_is_valid(*p)) return false; - /* Check if there are duplicate assginments */ + /* Check if there are duplicate assignments */ k = strcspn(*p, "="); STRV_FOREACH(q, p + 1) if (strneq(*p, *q, k) && (*q)[k] == '=') @@ -388,7 +388,7 @@ int strv_env_replace(char ***l, char *p) { assert(p); /* Replace first occurrence of the env var or add a new one in the - * string list. Drop other occurences. Edits in-place. Does not copy p. + * string list. Drop other occurrences. Edits in-place. Does not copy p. * p must be a valid key=value assignment. */ diff --git a/src/systemd/src/basic/fd-util.c b/src/systemd/src/basic/fd-util.c index e085dc23b..b97bd191a 100644 --- a/src/systemd/src/basic/fd-util.c +++ b/src/systemd/src/basic/fd-util.c @@ -277,7 +277,7 @@ int same_fd(int a, int b) { return true; if (r > 0) return false; - if (errno != ENOSYS) + if (!IN_SET(errno, ENOSYS, EACCES, EPERM)) return -errno; /* We don't have kcmp(), use fstat() instead. */ diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c index ea607f8cf..d2fd4c47b 100644 --- a/src/systemd/src/basic/fileio.c +++ b/src/systemd/src/basic/fileio.c @@ -1492,6 +1492,7 @@ int open_serialization_fd(const char *ident) { } int link_tmpfile(int fd, const char *path, const char *target) { + int r; assert(fd >= 0); assert(target); @@ -1504,8 +1505,9 @@ int link_tmpfile(int fd, const char *path, const char *target) { * operation currently (renameat2() does), and there is no nice way to emulate this. */ if (path) { - if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0) - return -errno; + r = rename_noreplace(AT_FDCWD, path, AT_FDCWD, target); + if (r < 0) + return r; } else { char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1]; diff --git a/src/systemd/src/basic/fs-util.c b/src/systemd/src/basic/fs-util.c index 09fcc32e0..3d83fc9b1 100644 --- a/src/systemd/src/basic/fs-util.c +++ b/src/systemd/src/basic/fs-util.c @@ -89,41 +89,44 @@ int rmdir_parents(const char *path, const char *stop) { } int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { - struct stat buf; - int ret; + int r; - ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE); - if (ret >= 0) + /* Try the ideal approach first */ + if (renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE) >= 0) return 0; - /* renameat2() exists since Linux 3.15, btrfs added support for it later. - * If it is not implemented, fallback to another method. */ - if (!IN_SET(errno, EINVAL, ENOSYS)) + /* renameat2() exists since Linux 3.15, btrfs and FAT added support for it later. If it is not implemented, + * fall back to a different method. */ + if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY)) return -errno; - /* The link()/unlink() fallback does not work on directories. But - * renameat() without RENAME_NOREPLACE gives the same semantics on - * directories, except when newpath is an *empty* directory. This is - * good enough. */ - ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW); - if (ret >= 0 && S_ISDIR(buf.st_mode)) { - ret = renameat(olddirfd, oldpath, newdirfd, newpath); - return ret >= 0 ? 0 : -errno; + /* Let's try to use linkat()+unlinkat() as fallback. This doesn't work on directories and on some file systems + * that do not support hard links (such as FAT, most prominently), but for files it's pretty close to what we + * want — though not atomic (i.e. for a short period both the new and the old filename will exist). */ + if (linkat(olddirfd, oldpath, newdirfd, newpath, 0) >= 0) { + + if (unlinkat(olddirfd, oldpath, 0) < 0) { + r = -errno; /* Backup errno before the following unlinkat() alters it */ + (void) unlinkat(newdirfd, newpath, 0); + return r; + } + + return 0; } - /* If it is not a directory, use the link()/unlink() fallback. */ - ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0); - if (ret < 0) + if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM)) /* FAT returns EPERM on link()… */ return -errno; - ret = unlinkat(olddirfd, oldpath, 0); - if (ret < 0) { - /* backup errno before the following unlinkat() alters it */ - ret = errno; - (void) unlinkat(newdirfd, newpath, 0); - errno = ret; + /* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fallback to the racy TOCTOU + * vulnerable accessat(F_OK) check followed by classic, replacing renameat(), we have nothing better. */ + + if (faccessat(newdirfd, newpath, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) + return -EEXIST; + if (errno != ENOENT) + return -errno; + + if (renameat(olddirfd, oldpath, newdirfd, newpath) < 0) return -errno; - } return 0; } @@ -346,12 +349,27 @@ int touch(const char *path) { return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); } -int symlink_idempotent(const char *from, const char *to) { +int symlink_idempotent(const char *from, const char *to, bool make_relative) { + _cleanup_free_ char *relpath = NULL; int r; assert(from); assert(to); + if (make_relative) { + _cleanup_free_ char *parent = NULL; + + parent = dirname_malloc(to); + if (!parent) + return -ENOMEM; + + r = path_make_relative(parent, from, &relpath); + if (r < 0) + return r; + + from = relpath; + } + if (symlink(from, to) < 0) { _cleanup_free_ char *p = NULL; diff --git a/src/systemd/src/basic/fs-util.h b/src/systemd/src/basic/fs-util.h index 4b6562586..bc753d592 100644 --- a/src/systemd/src/basic/fs-util.h +++ b/src/systemd/src/basic/fs-util.h @@ -37,7 +37,7 @@ int fd_warn_permissions(const char *path, int fd); int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode); int touch(const char *path); -int symlink_idempotent(const char *from, const char *to); +int symlink_idempotent(const char *from, const char *to, bool make_relative); int symlink_atomic(const char *from, const char *to); int mknod_atomic(const char *path, mode_t mode, dev_t dev); diff --git a/src/systemd/src/basic/hashmap.h b/src/systemd/src/basic/hashmap.h index 274afb395..b771ceccd 100644 --- a/src/systemd/src/basic/hashmap.h +++ b/src/systemd/src/basic/hashmap.h @@ -15,7 +15,7 @@ * necessary to instantiate an object for each Hashmap use. * * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap), - * the implemention will: + * the implementation will: * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py) * - perform extra checks for invalid use of iterators */ diff --git a/src/systemd/src/basic/hexdecoct.c b/src/systemd/src/basic/hexdecoct.c index 7748e8352..c0f96409f 100644 --- a/src/systemd/src/basic/hexdecoct.c +++ b/src/systemd/src/basic/hexdecoct.c @@ -79,7 +79,7 @@ static int unhex_next(const char **p, size_t *l) { assert(l); /* Find the next non-whitespace character, and decode it. We - * greedily skip all preceeding and all following whitespace. */ + * greedily skip all preceding and all following whitespace. */ for (;;) { if (*l == 0) @@ -592,8 +592,7 @@ static int base64_append_width( _cleanup_free_ char *x = NULL; char *t, *s; - ssize_t slen, len, avail; - int line, lines; + ssize_t len, slen, avail, line, lines; len = base64mem(p, l, &x); if (len <= 0) @@ -602,6 +601,9 @@ static int base64_append_width( lines = DIV_ROUND_UP(len, width); slen = strlen_ptr(sep); + if (lines > (SSIZE_MAX - plen - 1 - slen) / (indent + width + 1)) + return -ENOMEM; + t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines); if (!t) return -ENOMEM; @@ -647,7 +649,7 @@ static int unbase64_next(const char **p, size_t *l) { assert(l); /* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We - * greedily skip all preceeding and all following whitespace. */ + * greedily skip all preceding and all following whitespace. */ for (;;) { if (*l == 0) diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h index 24fcdc840..9972b6f99 100644 --- a/src/systemd/src/basic/macro.h +++ b/src/systemd/src/basic/macro.h @@ -464,4 +464,53 @@ static inline int __coverity_check__(int condition) { func(*p); \ } +#define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \ + scope type *name##_ref(type *p) { \ + if (!p) \ + return NULL; \ + \ + assert(p->n_ref > 0); \ + p->n_ref++; \ + return p; \ + } + +#define _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, scope) \ + scope type *name##_unref(type *p) { \ + if (!p) \ + return NULL; \ + \ + assert(p->n_ref > 0); \ + p->n_ref--; \ + if (p->n_ref > 0) \ + return NULL; \ + \ + return free_func(p); \ + } + +#define DEFINE_TRIVIAL_REF_FUNC(type, name) \ + _DEFINE_TRIVIAL_REF_FUNC(type, name,) +#define DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name) \ + _DEFINE_TRIVIAL_REF_FUNC(type, name, static) +#define DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name) \ + _DEFINE_TRIVIAL_REF_FUNC(type, name, _public_) + +#define DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func) \ + _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func,) +#define DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func) \ + _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, static) +#define DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func) \ + _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, _public_) + +#define DEFINE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_TRIVIAL_REF_FUNC(type, name); \ + DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func); + +#define DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name); \ + DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func); + +#define DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name); \ + DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func); + #include "log.h" diff --git a/src/systemd/src/basic/parse-util.c b/src/systemd/src/basic/parse-util.c index db38f91c8..a9085348b 100644 --- a/src/systemd/src/basic/parse-util.c +++ b/src/systemd/src/basic/parse-util.c @@ -570,7 +570,7 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { s = *p; - /* accept any number of digits, strtoull is limted to 19 */ + /* accept any number of digits, strtoull is limited to 19 */ for (i=0; i < digits; i++,s++) { if (*s < '0' || *s > '9') { if (i == 0) diff --git a/src/systemd/src/basic/path-util.c b/src/systemd/src/basic/path-util.c index b62786f27..f3c6c16aa 100644 --- a/src/systemd/src/basic/path-util.c +++ b/src/systemd/src/basic/path-util.c @@ -425,7 +425,7 @@ int path_compare(const char *a, const char *b) { assert(a); assert(b); - /* A relative path and an abolute path must not compare as equal. + /* A relative path and an absolute path must not compare as equal. * Which one is sorted before the other does not really matter. * Here a relative path is ordered before an absolute path. */ d = (a[0] == '/') - (b[0] == '/'); diff --git a/src/systemd/src/basic/process-util.c b/src/systemd/src/basic/process-util.c index d6ee8b62b..1098cf453 100644 --- a/src/systemd/src/basic/process-util.c +++ b/src/systemd/src/basic/process-util.c @@ -425,7 +425,7 @@ int is_kernel_thread(pid_t pid) { q += l; } - /* Skip preceeding whitespace */ + /* Skip preceding whitespace */ l = strspn(q, WHITESPACE); if (l < 1) return -EINVAL; @@ -1104,11 +1104,9 @@ void valgrind_summary_hack(void) { #endif } -int pid_compare_func(const void *a, const void *b) { - const pid_t *p = a, *q = b; - +int pid_compare_func(const pid_t *a, const pid_t *b) { /* Suitable for usage in qsort() */ - return CMP(*p, *q); + return CMP(*a, *b); } int ioprio_parse_priority(const char *s, int *ret) { diff --git a/src/systemd/src/basic/process-util.h b/src/systemd/src/basic/process-util.h index a5bb072b2..7ef45dc92 100644 --- a/src/systemd/src/basic/process-util.h +++ b/src/systemd/src/basic/process-util.h @@ -108,7 +108,7 @@ static inline void* PID_TO_PTR(pid_t pid) { void valgrind_summary_hack(void); -int pid_compare_func(const void *a, const void *b); +int pid_compare_func(const pid_t *a, const pid_t *b); static inline bool nice_is_valid(int n) { return n >= PRIO_MIN && n < PRIO_MAX; diff --git a/src/systemd/src/basic/refcnt.h b/src/systemd/src/basic/refcnt.h index d2be6086d..40f9a84a2 100644 --- a/src/systemd/src/basic/refcnt.h +++ b/src/systemd/src/basic/refcnt.h @@ -14,3 +14,41 @@ typedef struct { #define REFCNT_DEC(r) (__sync_sub_and_fetch(&(r)._value, 1)) #define REFCNT_INIT ((RefCount) { ._value = 1 }) + +#define _DEFINE_ATOMIC_REF_FUNC(type, name, scope) \ + scope type *name##_ref(type *p) { \ + if (!p) \ + return NULL; \ + \ + assert_se(REFCNT_INC(p->n_ref) >= 2); \ + return p; \ + } + +#define _DEFINE_ATOMIC_UNREF_FUNC(type, name, free_func, scope) \ + scope type *name##_unref(type *p) { \ + if (!p) \ + return NULL; \ + \ + if (REFCNT_DEC(p->n_ref) > 0) \ + return NULL; \ + \ + return free_func(p); \ + } + +#define DEFINE_ATOMIC_REF_FUNC(type, name) \ + _DEFINE_ATOMIC_REF_FUNC(type, name,) +#define DEFINE_PUBLIC_ATOMIC_REF_FUNC(type, name) \ + _DEFINE_ATOMIC_REF_FUNC(type, name, _public_) + +#define DEFINE_ATOMIC_UNREF_FUNC(type, name, free_func) \ + _DEFINE_ATOMIC_UNREF_FUNC(type, name, free_func,) +#define DEFINE_PUBLIC_ATOMIC_UNREF_FUNC(type, name, free_func) \ + _DEFINE_ATOMIC_UNREF_FUNC(type, name, free_func, _public_) + +#define DEFINE_ATOMIC_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_ATOMIC_REF_FUNC(type, name); \ + DEFINE_ATOMIC_UNREF_FUNC(type, name, free_func); + +#define DEFINE_PUBLIC_ATOMIC_REF_UNREF_FUNC(type, name, free_func) \ + DEFINE_PUBLIC_ATOMIC_REF_FUNC(type, name); \ + DEFINE_PUBLIC_ATOMIC_UNREF_FUNC(type, name, free_func); diff --git a/src/systemd/src/basic/socket-util.c b/src/systemd/src/basic/socket-util.c index 986bc6e67..4e8b2baf8 100644 --- a/src/systemd/src/basic/socket-util.c +++ b/src/systemd/src/basic/socket-util.c @@ -835,8 +835,8 @@ int fd_inc_sndbuf(int fd, size_t n) { /* If we have the privileges we will ignore the kernel limit. */ value = (int) n; - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) return -errno; return 1; @@ -853,8 +853,8 @@ int fd_inc_rcvbuf(int fd, size_t n) { /* If we have the privileges we will ignore the kernel limit. */ value = (int) n; - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) return -errno; return 1; } diff --git a/src/systemd/src/basic/sparse-endian.h b/src/systemd/src/basic/sparse-endian.h index 5e59de543..8540ccd0b 100644 --- a/src/systemd/src/basic/sparse-endian.h +++ b/src/systemd/src/basic/sparse-endian.h @@ -20,8 +20,7 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ -#ifndef SPARSE_ENDIAN_H -#define SPARSE_ENDIAN_H +#pragma once #include <byteswap.h> #include <endian.h> @@ -89,5 +88,3 @@ static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t _ #undef __sd_bitwise #undef __sd_force - -#endif /* SPARSE_ENDIAN_H */ diff --git a/src/systemd/src/basic/string-table.h b/src/systemd/src/basic/string-table.h index 9bd787935..228c12ad0 100644 --- a/src/systemd/src/basic/string-table.h +++ b/src/systemd/src/basic/string-table.h @@ -58,7 +58,7 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k } #define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \ - type name##_from_string(const char *s) { \ + scope type name##_from_string(const char *s) { \ type i; \ unsigned u = 0; \ if (!s) \ diff --git a/src/systemd/src/basic/string-util.c b/src/systemd/src/basic/string-util.c index 0a4068349..dfa739996 100644 --- a/src/systemd/src/basic/string-util.c +++ b/src/systemd/src/basic/string-util.c @@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) { assert(p); - /* Replaces a string pointer with an strdup()ed new string, + /* Replaces a string pointer with a strdup()ed new string, * possibly freeing the old one. */ if (streq_ptr(*p, s)) @@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) { return 1; } +int free_and_strndup(char **p, const char *s, size_t l) { + char *t; + + assert(p); + assert(s || l == 0); + + /* Replaces a string pointer with a strndup()ed new string, + * freeing the old one. */ + + if (!*p && !s) + return 0; + + if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0')) + return 0; + + if (s) { + t = strndup(s, l); + if (!t) + return -ENOMEM; + } else + t = NULL; + + free_and_replace(*p, t); + return 1; +} + #if !HAVE_EXPLICIT_BZERO /* * Pointer to memset is volatile so that compiler must de-reference diff --git a/src/systemd/src/basic/string-util.h b/src/systemd/src/basic/string-util.h index c0cc4e78d..72c075aa3 100644 --- a/src/systemd/src/basic/string-util.h +++ b/src/systemd/src/basic/string-util.h @@ -176,6 +176,7 @@ char *strrep(const char *s, unsigned n); int split_pair(const char *s, const char *sep, char **l, char **r); int free_and_strdup(char **p, const char *s); +int free_and_strndup(char **p, const char *s, size_t l); /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { @@ -228,3 +229,25 @@ static inline void *memory_startswith(const void *p, size_t sz, const char *toke return (uint8_t*) p + n; } + +/* Like startswith_no_case(), but operates on arbitrary memory blocks. + * It works only for ASCII strings. + */ +static inline void *memory_startswith_no_case(const void *p, size_t sz, const char *token) { + size_t n, i; + + assert(token); + + n = strlen(token); + if (sz < n) + return NULL; + + assert(p); + + for (i = 0; i < n; i++) { + if (ascii_tolower(((char *)p)[i]) != ascii_tolower(token[i])) + return NULL; + } + + return (uint8_t*) p + n; +} diff --git a/src/systemd/src/basic/strv.c b/src/systemd/src/basic/strv.c index abf3fc4c7..dc72f036a 100644 --- a/src/systemd/src/basic/strv.c +++ b/src/systemd/src/basic/strv.c @@ -339,21 +339,22 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract return (int) n; } -char *strv_join(char **l, const char *separator) { +char *strv_join_prefix(char **l, const char *separator, const char *prefix) { char *r, *e; char **s; - size_t n, k; + size_t n, k, m; if (!separator) separator = " "; k = strlen(separator); + m = strlen_ptr(prefix); n = 0; STRV_FOREACH(s, l) { if (s != l) n += k; - n += strlen(*s); + n += m + strlen(*s); } r = new(char, n+1); @@ -365,6 +366,9 @@ char *strv_join(char **l, const char *separator) { if (s != l) e = stpcpy(e, separator); + if (prefix) + e = stpcpy(e, prefix); + e = stpcpy(e, *s); } @@ -711,14 +715,12 @@ bool strv_overlap(char **a, char **b) { return false; } -static int str_compare(const void *_a, const void *_b) { - const char **a = (const char**) _a, **b = (const char**) _b; - +static int str_compare(char * const *a, char * const *b) { return strcmp(*a, *b); } char **strv_sort(char **l) { - qsort_safe(l, strv_length(l), sizeof(char*), str_compare); + typesafe_qsort(l, strv_length(l), str_compare); return l; } diff --git a/src/systemd/src/basic/strv.h b/src/systemd/src/basic/strv.h index 51d03db94..34a660cb9 100644 --- a/src/systemd/src/basic/strv.h +++ b/src/systemd/src/basic/strv.h @@ -71,7 +71,10 @@ char **strv_split_newlines(const char *s); int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags); -char *strv_join(char **l, const char *separator); +char *strv_join_prefix(char **l, const char *separator, const char *prefix); +static inline char *strv_join(char **l, const char *separator) { + return strv_join_prefix(l, separator, NULL); +} char **strv_parse_nulstr(const char *s, size_t l); char **strv_split_nulstr(const char *s); diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c index 81d3f3f38..9ac739b42 100644 --- a/src/systemd/src/basic/time-util.c +++ b/src/systemd/src/basic/time-util.c @@ -905,7 +905,7 @@ int parse_timestamp(const char *t, usec_t *usec) { * Otherwise just cut it off. */ with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]); - /* Cut off the timezone if we dont need it. */ + /* Cut off the timezone if we don't need it. */ if (with_tz) t = strndupa(t, last_space - t); diff --git a/src/systemd/src/basic/utf8.c b/src/systemd/src/basic/utf8.c index a5ce1a294..e0d1949dc 100644 --- a/src/systemd/src/basic/utf8.c +++ b/src/systemd/src/basic/utf8.c @@ -61,12 +61,12 @@ static bool unichar_is_control(char32_t ch) { } /* count of characters used to encode one unicode char */ -static int utf8_encoded_expected_len(const char *str) { - unsigned char c; +static size_t utf8_encoded_expected_len(const char *str) { + uint8_t c; assert(str); - c = (unsigned char) str[0]; + c = (uint8_t) str[0]; if (c < 0x80) return 1; if ((c & 0xe0) == 0xc0) @@ -86,7 +86,7 @@ static int utf8_encoded_expected_len(const char *str) { /* decode one unicode char */ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) { char32_t unichar; - int len, i; + size_t len, i; assert(str); @@ -118,6 +118,7 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) { for (i = 1; i < len; i++) { if (((char32_t)str[i] & 0xc0) != 0x80) return -EINVAL; + unichar <<= 6; unichar |= (char32_t)str[i] & 0x3f; } @@ -154,22 +155,23 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) { return true; } -const char *utf8_is_valid(const char *str) { - const uint8_t *p; +char *utf8_is_valid(const char *str) { + const char *p; assert(str); - for (p = (const uint8_t*) str; *p; ) { + p = str; + while (*p) { int len; - len = utf8_encoded_valid_unichar((const char *)p); + len = utf8_encoded_valid_unichar(p); if (len < 0) return NULL; p += len; } - return str; + return (char*) str; } char *utf8_escape_invalid(const char *str) { @@ -312,18 +314,25 @@ size_t utf8_encode_unichar(char *out_utf8, char32_t g) { return 0; } -char *utf16_to_utf8(const void *s, size_t length) { +char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */) { const uint8_t *f; char *r, *t; - r = new(char, (length * 4 + 1) / 2 + 1); + assert(s); + + /* Input length is in bytes, i.e. the shortest possible character takes 2 bytes. Each unicode character may + * take up to 4 bytes in UTF-8. Let's also account for a trailing NUL byte. */ + if (length * 2 < length) + return NULL; /* overflow */ + + r = new(char, length * 2 + 1); if (!r) return NULL; - f = s; + f = (const uint8_t*) s; t = r; - while (f < (const uint8_t*) s + length) { + while (f + 1 < (const uint8_t*) s + length) { char16_t w1, w2; /* see RFC 2781 section 2.2 */ @@ -333,13 +342,13 @@ char *utf16_to_utf8(const void *s, size_t length) { if (!utf16_is_surrogate(w1)) { t += utf8_encode_unichar(t, w1); - continue; } if (utf16_is_trailing_surrogate(w1)) - continue; - else if (f >= (const uint8_t*) s + length) + continue; /* spurious trailing surrogate, ignore */ + + if (f + 1 >= (const uint8_t*) s + length) break; w2 = f[1] << 8 | f[0]; @@ -347,7 +356,7 @@ char *utf16_to_utf8(const void *s, size_t length) { if (!utf16_is_trailing_surrogate(w2)) { f -= 2; - continue; + continue; /* surrogate missing its trailing surrogate, ignore */ } t += utf8_encode_unichar(t, utf16_surrogate_pair_to_unichar(w1, w2)); @@ -357,6 +366,79 @@ char *utf16_to_utf8(const void *s, size_t length) { return r; } +size_t utf16_encode_unichar(char16_t *out, char32_t c) { + + /* Note that this encodes as little-endian. */ + + switch (c) { + + case 0 ... 0xd7ffU: + case 0xe000U ... 0xffffU: + out[0] = htole16(c); + return 1; + + case 0x10000U ... 0x10ffffU: + c -= 0x10000U; + out[0] = htole16((c >> 10) + 0xd800U); + out[1] = htole16((c & 0x3ffU) + 0xdc00U); + return 2; + + default: /* A surrogate (invalid) */ + return 0; + } +} + +char16_t *utf8_to_utf16(const char *s, size_t length) { + char16_t *n, *p; + size_t i; + int r; + + assert(s); + + n = new(char16_t, length + 1); + if (!n) + return NULL; + + p = n; + + for (i = 0; i < length;) { + char32_t unichar; + size_t e; + + e = utf8_encoded_expected_len(s + i); + if (e <= 1) /* Invalid and single byte characters are copied as they are */ + goto copy; + + if (i + e > length) /* sequence longer than input buffer, then copy as-is */ + goto copy; + + r = utf8_encoded_to_unichar(s + i, &unichar); + if (r < 0) /* sequence invalid, then copy as-is */ + goto copy; + + p += utf16_encode_unichar(p, unichar); + i += e; + continue; + + copy: + *(p++) = htole16(s[i++]); + } + + *p = 0; + return n; +} + +size_t char16_strlen(const char16_t *s) { + size_t n = 0; + + assert(s); + + while (*s != 0) + n++, s++; + + return n; +} + /* expected size used to encode one unicode char */ static int utf8_unichar_to_encoded_len(char32_t unichar) { @@ -376,8 +458,9 @@ static int utf8_unichar_to_encoded_len(char32_t unichar) { /* validate one encoded unicode char and return its length */ int utf8_encoded_valid_unichar(const char *str) { - int len, i, r; char32_t unichar; + size_t len, i; + int r; assert(str); @@ -399,14 +482,14 @@ int utf8_encoded_valid_unichar(const char *str) { return r; /* check if encoded length matches encoded value */ - if (utf8_unichar_to_encoded_len(unichar) != len) + if (utf8_unichar_to_encoded_len(unichar) != (int) len) return -EINVAL; /* check if value has valid range */ if (!unichar_is_valid(unichar)) return -EINVAL; - return len; + return (int) len; } size_t utf8_n_codepoints(const char *str) { diff --git a/src/systemd/src/basic/utf8.h b/src/systemd/src/basic/utf8.h index e8af7a576..3de798050 100644 --- a/src/systemd/src/basic/utf8.h +++ b/src/systemd/src/basic/utf8.h @@ -14,7 +14,7 @@ bool unichar_is_valid(char32_t c); -const char *utf8_is_valid(const char *s) _pure_; +char *utf8_is_valid(const char *s) _pure_; char *ascii_is_valid(const char *s) _pure_; char *ascii_is_valid_n(const char *str, size_t len); @@ -25,21 +25,26 @@ char *utf8_escape_invalid(const char *s); char *utf8_escape_non_printable(const char *str); size_t utf8_encode_unichar(char *out_utf8, char32_t g); -char *utf16_to_utf8(const void *s, size_t length); +size_t utf16_encode_unichar(char16_t *out, char32_t c); + +char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */); +char16_t *utf8_to_utf16(const char *s, size_t length); + +size_t char16_strlen(const char16_t *s); /* returns the number of 16bit words in the string (not bytes!) */ int utf8_encoded_valid_unichar(const char *str); int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar); static inline bool utf16_is_surrogate(char16_t c) { - return (0xd800 <= c && c <= 0xdfff); + return c >= 0xd800U && c <= 0xdfffU; } static inline bool utf16_is_trailing_surrogate(char16_t c) { - return (0xdc00 <= c && c <= 0xdfff); + return c >= 0xdc00U && c <= 0xdfffU; } static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) { - return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000; + return ((((char32_t) lead - 0xd800U) << 10) + ((char32_t) trail - 0xdc00U) + 0x10000U); } size_t utf8_n_codepoints(const char *str); diff --git a/src/systemd/src/basic/util.c b/src/systemd/src/basic/util.c index f951d641d..081c63c89 100644 --- a/src/systemd/src/basic/util.c +++ b/src/systemd/src/basic/util.c @@ -133,7 +133,7 @@ void in_initrd_force(bool value) { /* hey glibc, APIs with callbacks without a user pointer are so useless */ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar) (const void *, const void *, void *), void *arg) { + __compar_d_fn_t compar, void *arg) { size_t l, u, idx; const void *p; int comparison; diff --git a/src/systemd/src/basic/util.h b/src/systemd/src/basic/util.h index 308933ac9..5f3f98219 100644 --- a/src/systemd/src/basic/util.h +++ b/src/systemd/src/basic/util.h @@ -68,15 +68,21 @@ bool in_initrd(void); void in_initrd_force(bool value); void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar) (const void *, const void *, void *), - void *arg); + __compar_d_fn_t compar, void *arg); + +#define typesafe_bsearch_r(k, b, n, func, userdata) \ + ({ \ + const typeof(b[0]) *_k = k; \ + int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \ + xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_d_fn_t) _func_, userdata); \ + }) /** * Normal bsearch requires base to be nonnull. Here were require * that only if nmemb > 0. */ static inline void* bsearch_safe(const void *key, const void *base, - size_t nmemb, size_t size, comparison_fn_t compar) { + size_t nmemb, size_t size, __compar_fn_t compar) { if (nmemb <= 0) return NULL; @@ -84,11 +90,18 @@ static inline void* bsearch_safe(const void *key, const void *base, return bsearch(key, base, nmemb, size, compar); } +#define typesafe_bsearch(k, b, n, func) \ + ({ \ + const typeof(b[0]) *_k = k; \ + int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \ + bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_fn_t) _func_); \ + }) + /** * Normal qsort requires base to be nonnull. Here were require * that only if nmemb > 0. */ -static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) { +static inline void qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) { if (nmemb <= 1) return; @@ -104,7 +117,7 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_ qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \ }) -static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void *userdata) { +static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) { if (nmemb <= 1) return; @@ -112,6 +125,12 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*com qsort_r(base, nmemb, size, compar, userdata); } +#define typesafe_qsort_r(p, n, func, userdata) \ + ({ \ + int (*_func_)(const typeof(p[0])*, const typeof(p[0])*, typeof(userdata)) = func; \ + qsort_r_safe((p), (n), sizeof((p)[0]), (__compar_d_fn_t) _func_, userdata); \ + }) + /* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */ static inline void memcpy_safe(void *dst, const void *src, size_t n) { if (n == 0) diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c index 531cf6783..77c584ee6 100644 --- a/src/systemd/src/libsystemd-network/dhcp-identifier.c +++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c @@ -108,8 +108,13 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { assert(len); r = sd_id128_get_machine(&machine_id); - if (r < 0) + if (r < 0) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + machine_id = SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10); +#else return r; +#endif + } unaligned_write_be16(&duid->type, DUID_TYPE_EN); unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN); diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c index 77638338f..cf59f1495 100644 --- a/src/systemd/src/libsystemd-network/dhcp-network.c +++ b/src/systemd/src/libsystemd-network/dhcp-network.c @@ -126,8 +126,6 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, const uint8_t *bcast_addr = NULL; uint8_t dhcp_hlen = 0; - assert_return(mac_addr_len > 0, -EINVAL); - if (arp_type == ARPHRD_ETHER) { assert_return(mac_addr_len == ETH_ALEN, -EINVAL); memcpy(ð_mac, mac_addr, ETH_ALEN); diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h index f1cbd6a4f..63d8fe35f 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h @@ -73,8 +73,6 @@ struct DHCP6IA { struct ia_pd ia_pd; struct ia_ta ia_ta; }; - sd_event_source *timeout_t1; - sd_event_source *timeout_t2; LIST_HEAD(DHCP6Address, addresses); }; @@ -91,7 +89,7 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd); int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn); int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen, uint8_t **optvalue); -int dhcp6_option_parse_status(DHCP6Option *option); +int dhcp6_option_parse_status(DHCP6Option *option, size_t len); int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia); int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen, struct in6_addr **addrs, size_t count, diff --git a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h index ff0b0f00c..e004f48b4 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h @@ -37,7 +37,6 @@ struct sd_dhcp6_lease { size_t ntp_fqdn_count; }; -int dhcp6_lease_clear_timers(DHCP6IA *ia); int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire); DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia); @@ -50,6 +49,7 @@ int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease); int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit); int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid); +int dhcp6_lease_get_pd_iaid(sd_dhcp6_lease *lease, be32_t *iaid); int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen); int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval, diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c index 18196b125..cf19d366d 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-option.c +++ b/src/systemd/src/libsystemd-network/dhcp6-option.c @@ -247,10 +247,11 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, return 0; } -int dhcp6_option_parse_status(DHCP6Option *option) { +int dhcp6_option_parse_status(DHCP6Option *option, size_t len) { DHCP6StatusOption *statusopt = (DHCP6StatusOption *)option; - if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*statusopt)) + if (len < sizeof(DHCP6StatusOption) || + be16toh(option->len) + sizeof(DHCP6Option) < sizeof(DHCP6StatusOption)) return -ENOBUFS; return be16toh(statusopt->status); @@ -277,7 +278,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, } if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*addr_option)) { - r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options); + r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*addr_option)); if (r != 0) return r < 0 ? r: 0; } @@ -317,7 +318,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, } if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*pdprefix_option)) { - r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options); + r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*pdprefix_option)); if (r != 0) return r < 0 ? r: 0; } @@ -462,7 +463,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) { case SD_DHCP6_OPTION_STATUS_CODE: - status = dhcp6_option_parse_status(option); + status = dhcp6_option_parse_status(option, optlen); if (status) { log_dhcp6_client(client, "IA status %d", status); @@ -563,7 +564,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char * /* Literal label */ label = (const char *)&optval[pos]; pos += c; - if (pos > optlen) + if (pos >= optlen) return -EMSGSIZE; if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) { diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.c b/src/systemd/src/libsystemd-network/lldp-neighbor.c index 8295d4d40..f3c4e0ac8 100644 --- a/src/systemd/src/libsystemd-network/lldp-neighbor.c +++ b/src/systemd/src/libsystemd-network/lldp-neighbor.c @@ -18,8 +18,7 @@ static void lldp_neighbor_id_hash_func(const void *p, struct siphash *state) { siphash24_compress(&id->port_id_size, sizeof(id->port_id_size), state); } -static int lldp_neighbor_id_compare_func(const void *a, const void *b) { - const LLDPNeighborID *x = a, *y = b; +int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y) { int r; r = memcmp(x->chassis_id, y->chassis_id, MIN(x->chassis_id_size, y->chassis_id_size)); @@ -39,7 +38,7 @@ static int lldp_neighbor_id_compare_func(const void *a, const void *b) { const struct hash_ops lldp_neighbor_id_hash_ops = { .hash = lldp_neighbor_id_hash_func, - .compare = lldp_neighbor_id_compare_func + .compare = (__compar_fn_t) lldp_neighbor_id_compare_func, }; int lldp_neighbor_prioq_compare_func(const void *a, const void *b) { diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.h b/src/systemd/src/libsystemd-network/lldp-neighbor.h index 494bc5176..2241c3bd9 100644 --- a/src/systemd/src/libsystemd-network/lldp-neighbor.h +++ b/src/systemd/src/libsystemd-network/lldp-neighbor.h @@ -81,6 +81,7 @@ static inline void* LLDP_NEIGHBOR_TLV_DATA(const sd_lldp_neighbor *n) { } extern const struct hash_ops lldp_neighbor_id_hash_ops; +int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y); int lldp_neighbor_prioq_compare_func(const void *a, const void *b); sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n); diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index de86028a5..3e8d985aa 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -385,7 +385,7 @@ static int dhcp_client_set_iaid_duid_internal( } else switch (duid_type) { case DUID_TYPE_LLT: - if (!client->mac_addr || client->mac_addr_len == 0) + if (client->mac_addr_len == 0) return -EOPNOTSUPP; r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len); @@ -398,7 +398,7 @@ static int dhcp_client_set_iaid_duid_internal( return r; break; case DUID_TYPE_LL: - if (!client->mac_addr || client->mac_addr_len == 0) + if (client->mac_addr_len == 0) return -EOPNOTSUPP; r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len); @@ -698,7 +698,7 @@ static int client_message_init( let the server know how large the server may make its DHCP messages. Note (from ConnMan): Some DHCP servers will send bigger DHCP packets - than the defined default size unless the Maximum Messge Size option + than the defined default size unless the Maximum Message Size option is explicitly set RFC3442 "Requirements to Avoid Sizing Constraints": @@ -1951,27 +1951,8 @@ sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) { return client->event; } -sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) { - - if (!client) - return NULL; - - assert(client->n_ref >= 1); - client->n_ref++; - - return client; -} - -sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { - - if (!client) - return NULL; - - assert(client->n_ref >= 1); - client->n_ref--; - - if (client->n_ref > 0) - return NULL; +static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) { + assert(client); log_dhcp_client(client, "FREE"); @@ -1990,6 +1971,8 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { return mfree(client); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free); + int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) { _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL; diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c index 8b6f5ad34..863818d6d 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c @@ -246,27 +246,8 @@ int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, s return 0; } -sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) { - - if (!lease) - return NULL; - - assert(lease->n_ref >= 1); - lease->n_ref++; - - return lease; -} - -sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { - - if (!lease) - return NULL; - - assert(lease->n_ref >= 1); - lease->n_ref--; - - if (lease->n_ref > 0) - return NULL; +static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { + assert(lease); while (lease->private_options) { struct sd_dhcp_raw_option *option = lease->private_options; @@ -277,6 +258,8 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { free(option); } + free(lease->root_path); + free(lease->timezone); free(lease->hostname); free(lease->domainname); free(lease->dns); @@ -288,6 +271,8 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { return mfree(lease); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_lease, sd_dhcp_lease, dhcp_lease_free); + static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) { assert(option); assert(ret); @@ -347,8 +332,7 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) { if (!string) return -ENOMEM; - free(*ret); - *ret = string; + free_and_replace(*ret, string); } return 0; diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index 84c58af34..c07d831f7 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -27,6 +27,13 @@ #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN +/* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */ +enum { + DHCP6_REQUEST_IA_NA = 1, + DHCP6_REQUEST_IA_TA = 2, /* currently not used */ + DHCP6_REQUEST_IA_PD = 4, +}; + struct sd_dhcp6_client { unsigned n_ref; @@ -40,7 +47,9 @@ struct sd_dhcp6_client { uint16_t arp_type; DHCP6IA ia_na; DHCP6IA ia_pd; - bool prefix_delegation; + sd_event_source *timeout_t1; + sd_event_source *timeout_t2; + unsigned request; be32_t transaction_id; usec_t transaction_start; struct sd_dhcp6_lease *lease; @@ -205,10 +214,10 @@ static int dhcp6_client_set_duid_internal( } else switch (duid_type) { case DUID_TYPE_LLT: - if (!client->mac_addr || client->mac_addr_len == 0) + if (client->mac_addr_len == 0) return -EOPNOTSUPP; - r = dhcp_identifier_set_duid_llt(&client->duid, 0, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len); + r = dhcp_identifier_set_duid_llt(&client->duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len); if (r < 0) return r; break; @@ -218,7 +227,7 @@ static int dhcp6_client_set_duid_internal( return r; break; case DUID_TYPE_LL: - if (!client->mac_addr || client->mac_addr_len == 0) + if (client->mac_addr_len == 0) return -EOPNOTSUPP; r = dhcp_identifier_set_duid_ll(&client->duid, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len); @@ -325,10 +334,44 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) return 0; } -int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, bool delegation) { +int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) { + assert_return(client, -EINVAL); + assert_return(delegation, -EINVAL); + + *delegation = FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD); + + return 0; +} + +int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, int delegation) { + assert_return(client, -EINVAL); + + SET_FLAG(client->request, DHCP6_REQUEST_IA_PD, delegation); + + return 0; +} + +int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client, int *request) { + assert_return(client, -EINVAL); + assert_return(request, -EINVAL); + + *request = FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA); + + return 0; +} + +int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) { assert_return(client, -EINVAL); - client->prefix_delegation = delegation; + SET_FLAG(client->request, DHCP6_REQUEST_IA_NA, request); + + return 0; +} + +int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id) { + assert_return(client, -EINVAL); + + client->transaction_id = transaction_id; return 0; } @@ -352,21 +395,10 @@ static void client_notify(sd_dhcp6_client *client, int event) { client->callback(client, event, client->userdata); } -static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) { - assert(client); - - if (client->lease) { - dhcp6_lease_clear_timers(&client->lease->ia); - sd_dhcp6_lease_unref(client->lease); - } - - client->lease = lease; -} - static int client_reset(sd_dhcp6_client *client) { assert(client); - client_set_lease(client, NULL); + client->lease = sd_dhcp6_lease_unref(client->lease); client->receive_message = sd_event_source_unref(client->receive_message); @@ -374,17 +406,15 @@ static int client_reset(sd_dhcp6_client *client) { client->transaction_id = 0; client->transaction_start = 0; - client->ia_na.timeout_t1 = - sd_event_source_unref(client->ia_na.timeout_t1); - client->ia_na.timeout_t2 = - sd_event_source_unref(client->ia_na.timeout_t2); - client->retransmit_time = 0; client->retransmit_count = 0; client->timeout_resend = sd_event_source_unref(client->timeout_resend); client->timeout_resend_expire = sd_event_source_unref(client->timeout_resend_expire); + client->timeout_t1 = sd_event_source_unref(client->timeout_t1); + client->timeout_t2 = sd_event_source_unref(client->timeout_t2); + client->state = DHCP6_STATE_STOPPED; return 0; @@ -436,9 +466,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { if (r < 0) return r; - r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na); - if (r < 0) - return r; + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) { + r = dhcp6_option_append_ia(&opt, &optlen, + &client->ia_na); + if (r < 0) + return r; + } if (client->fqdn) { r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn); @@ -446,7 +479,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } - if (client->prefix_delegation) { + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd); if (r < 0) return r; @@ -471,9 +504,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { if (r < 0) return r; - r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia); - if (r < 0) - return r; + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) { + r = dhcp6_option_append_ia(&opt, &optlen, + &client->lease->ia); + if (r < 0) + return r; + } if (client->fqdn) { r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn); @@ -481,7 +517,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } - if (client->prefix_delegation) { + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd); if (r < 0) return r; @@ -495,9 +531,11 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { case DHCP6_STATE_REBIND: message->type = DHCP6_REBIND; - r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia); - if (r < 0) - return r; + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) { + r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia); + if (r < 0) + return r; + } if (client->fqdn) { r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn); @@ -505,7 +543,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } - if (client->prefix_delegation) { + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd); if (r < 0) return r; @@ -562,8 +600,8 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) assert(client); assert(client->lease); - client->lease->ia.timeout_t2 = - sd_event_source_unref(client->lease->ia.timeout_t2); + client->timeout_t2 = + sd_event_source_unref(client->timeout_t2); log_dhcp6_client(client, "Timeout T2"); @@ -579,8 +617,8 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) assert(client); assert(client->lease); - client->lease->ia.timeout_t1 = - sd_event_source_unref(client->lease->ia.timeout_t1); + client->timeout_t1 = + sd_event_source_unref(client->timeout_t1); log_dhcp6_client(client, "Timeout T1"); @@ -810,8 +848,8 @@ static int client_parse_message( uint8_t *optval; be32_t iaid_lease; - if (len < offsetof(DHCP6Option, data) || - len < offsetof(DHCP6Option, data) + be16toh(option->len)) + if (len < pos + offsetof(DHCP6Option, data) || + len < pos + offsetof(DHCP6Option, data) + be16toh(option->len)) return -ENOBUFS; optcode = be16toh(option->code); @@ -862,7 +900,7 @@ static int client_parse_message( break; case SD_DHCP6_OPTION_STATUS_CODE: - status = dhcp6_option_parse_status(option); + status = dhcp6_option_parse_status(option, optlen); if (status) { log_dhcp6_client(client, "%s Status %s", dhcp6_message_type_to_string(message->type), @@ -914,7 +952,7 @@ static int client_parse_message( if (r < 0 && r != -ENOMSG) return r; - r = dhcp6_lease_get_iaid(lease, &iaid_lease); + r = dhcp6_lease_get_pd_iaid(lease, &iaid_lease); if (r < 0) return r; @@ -967,7 +1005,7 @@ static int client_parse_message( break; } - pos += sizeof(*option) + optlen; + pos += offsetof(DHCP6Option, data) + optlen; } if (!clientid) { @@ -1027,8 +1065,8 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si return 0; } - client_set_lease(client, lease); - lease = NULL; + sd_dhcp6_lease_unref(client->lease); + client->lease = TAKE_PTR(lease); return DHCP6_STATE_BOUND; } @@ -1056,8 +1094,8 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver r = dhcp6_lease_get_preference(client->lease, &pref_lease); if (r < 0 || pref_advertise > pref_lease) { - client_set_lease(client, lease); - lease = NULL; + sd_dhcp6_lease_unref(client->lease); + client->lease = TAKE_PTR(lease); r = 0; } @@ -1188,10 +1226,33 @@ static int client_receive_message( return 0; } +static int client_get_lifetime(sd_dhcp6_client *client, uint32_t *lifetime_t1, + uint32_t *lifetime_t2) { + assert_return(client, -EINVAL); + assert_return(client->lease, -EINVAL); + + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA) && client->lease->ia.addresses) { + *lifetime_t1 = be32toh(client->lease->ia.ia_na.lifetime_t1); + *lifetime_t2 = be32toh(client->lease->ia.ia_na.lifetime_t2); + + return 0; + } + + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) { + *lifetime_t1 = be32toh(client->lease->pd.ia_pd.lifetime_t1); + *lifetime_t2 = be32toh(client->lease->pd.ia_pd.lifetime_t2); + + return 0; + } + + return -ENOMSG; +} + static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { int r; usec_t timeout, time_now; char time_string[FORMAT_TIMESPAN_MAX]; + uint32_t lifetime_t1, lifetime_t2; assert_return(client, -EINVAL); assert_return(client->event, -EINVAL); @@ -1251,57 +1312,58 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { case DHCP6_STATE_BOUND: - if (client->lease->ia.ia_na.lifetime_t1 == 0xffffffff || - client->lease->ia.ia_na.lifetime_t2 == 0xffffffff) { + r = client_get_lifetime(client, &lifetime_t1, &lifetime_t2); + if (r < 0) + goto error; + if (lifetime_t1 == 0xffffffff || lifetime_t2 == 0xffffffff) { log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x", - be32toh(client->lease->ia.ia_na.lifetime_t1), - be32toh(client->lease->ia.ia_na.lifetime_t2)); + lifetime_t1, lifetime_t2); return 0; } - timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t1) * USEC_PER_SEC); + timeout = client_timeout_compute_random(lifetime_t1 * USEC_PER_SEC); log_dhcp6_client(client, "T1 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); r = sd_event_add_time(client->event, - &client->lease->ia.timeout_t1, + &client->timeout_t1, clock_boottime_or_monotonic(), time_now + timeout, 10 * USEC_PER_SEC, client_timeout_t1, client); if (r < 0) goto error; - r = sd_event_source_set_priority(client->lease->ia.timeout_t1, + r = sd_event_source_set_priority(client->timeout_t1, client->event_priority); if (r < 0) goto error; - r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout"); + r = sd_event_source_set_description(client->timeout_t1, "dhcp6-t1-timeout"); if (r < 0) goto error; - timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t2) * USEC_PER_SEC); + timeout = client_timeout_compute_random(lifetime_t2 * USEC_PER_SEC); log_dhcp6_client(client, "T2 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); r = sd_event_add_time(client->event, - &client->lease->ia.timeout_t2, + &client->timeout_t2, clock_boottime_or_monotonic(), time_now + timeout, 10 * USEC_PER_SEC, client_timeout_t2, client); if (r < 0) goto error; - r = sd_event_source_set_priority(client->lease->ia.timeout_t2, + r = sd_event_source_set_priority(client->timeout_t2, client->event_priority); if (r < 0) goto error; - r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout"); + r = sd_event_source_set_description(client->timeout_t2, "dhcp6-t2-timeout"); if (r < 0) goto error; @@ -1363,6 +1425,9 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { if (!IN_SET(client->state, DHCP6_STATE_STOPPED)) return -EBUSY; + if (!client->information_request && !client->request) + return -EINVAL; + r = client_reset(client); if (r < 0) return r; @@ -1431,27 +1496,8 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) { return client->event; } -sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) { - - if (!client) - return NULL; - - assert(client->n_ref >= 1); - client->n_ref++; - - return client; -} - -sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { - - if (!client) - return NULL; - - assert(client->n_ref >= 1); - client->n_ref--; - - if (client->n_ref > 0) - return NULL; +static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) { + assert(client); client_reset(client); @@ -1464,6 +1510,8 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { return mfree(client); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_client, sd_dhcp6_client, dhcp6_client_free); + int sd_dhcp6_client_new(sd_dhcp6_client **ret) { _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL; size_t t; @@ -1478,6 +1526,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) { client->ia_na.type = SD_DHCP6_OPTION_IA_NA; client->ia_pd.type = SD_DHCP6_OPTION_IA_PD; client->ifindex = -1; + client->request = DHCP6_REQUEST_IA_NA; client->fd = -1; client->req_opts_len = ELEMENTSOF(default_req_opts); diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c index 779ad54b4..15fec2d85 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c @@ -11,15 +11,6 @@ #include "strv.h" #include "util.h" -int dhcp6_lease_clear_timers(DHCP6IA *ia) { - assert_return(ia, -EINVAL); - - ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1); - ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2); - - return 0; -} - int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) { DHCP6Address *addr; uint32_t valid = 0, t; @@ -48,8 +39,6 @@ DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) { if (!ia) return NULL; - dhcp6_lease_clear_timers(ia); - while (ia->addresses) { address = ia->addresses; @@ -136,6 +125,15 @@ int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) { return 0; } +int dhcp6_lease_get_pd_iaid(sd_dhcp6_lease *lease, be32_t *iaid) { + assert_return(lease, -EINVAL); + assert_return(iaid, -EINVAL); + + *iaid = lease->pd.ia_pd.id; + + return 0; +} + int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr, uint32_t *lifetime_preferred, uint32_t *lifetime_valid) { @@ -374,27 +372,8 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) { return -ENOENT; } -sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) { - - if (!lease) - return NULL; - - assert(lease->n_ref >= 1); - lease->n_ref++; - - return lease; -} - -sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) { - - if (!lease) - return NULL; - - assert(lease->n_ref >= 1); - lease->n_ref--; - - if (lease->n_ref > 0) - return NULL; +static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) { + assert(lease); free(lease->serverid); dhcp6_lease_free_ia(&lease->ia); @@ -410,6 +389,8 @@ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) { return mfree(lease); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_lease, sd_dhcp6_lease, dhcp6_lease_free); + int dhcp6_lease_new(sd_dhcp6_lease **ret) { sd_dhcp6_lease *lease; diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c index a40d40db9..6c12b5144 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c @@ -97,25 +97,8 @@ static void ipv4acd_reset(sd_ipv4acd *acd) { ipv4acd_set_state(acd, IPV4ACD_STATE_INIT, true); } -sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd) { - if (!acd) - return NULL; - - assert_se(acd->n_ref >= 1); - acd->n_ref++; - - return acd; -} - -sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) { - if (!acd) - return NULL; - - assert_se(acd->n_ref >= 1); - acd->n_ref--; - - if (acd->n_ref > 0) - return NULL; +static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) { + assert(acd); ipv4acd_reset(acd); sd_ipv4acd_detach_event(acd); @@ -123,6 +106,8 @@ sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) { return mfree(acd); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_ipv4acd, sd_ipv4acd, ipv4acd_free); + int sd_ipv4acd_new(sd_ipv4acd **ret) { _cleanup_(sd_ipv4acd_unrefp) sd_ipv4acd *acd = NULL; diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c index 7307e1668..e451dff74 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c @@ -55,30 +55,15 @@ struct sd_ipv4ll { static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata); -sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) { - if (!ll) - return NULL; - - assert(ll->n_ref >= 1); - ll->n_ref++; - - return ll; -} - -sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) { - if (!ll) - return NULL; - - assert(ll->n_ref >= 1); - ll->n_ref--; - - if (ll->n_ref > 0) - return NULL; +static sd_ipv4ll *ipv4ll_free(sd_ipv4ll *ll) { + assert(ll); sd_ipv4acd_unref(ll->acd); return mfree(ll); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_ipv4ll, sd_ipv4ll, ipv4ll_free); + int sd_ipv4ll_new(sd_ipv4ll **ret) { _cleanup_(sd_ipv4ll_unrefp) sd_ipv4ll *ll = NULL; int r; diff --git a/src/systemd/src/libsystemd-network/sd-lldp.c b/src/systemd/src/libsystemd-network/sd-lldp.c index c75d6079e..f72ef204b 100644 --- a/src/systemd/src/libsystemd-network/sd-lldp.c +++ b/src/systemd/src/libsystemd-network/sd-lldp.c @@ -119,7 +119,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) { } if (lldp_neighbor_equal(n, old)) { - /* Is this equal, then restart the TTL counter, but don't do anyting else. */ + /* Is this equal, then restart the TTL counter, but don't do anything else. */ old->timestamp = n->timestamp; lldp_start_timer(lldp, old); lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old); @@ -329,27 +329,8 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) { return 0; } -_public_ sd_lldp* sd_lldp_ref(sd_lldp *lldp) { - - if (!lldp) - return NULL; - - assert(lldp->n_ref > 0); - lldp->n_ref++; - - return lldp; -} - -_public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) { - - if (!lldp) - return NULL; - - assert(lldp->n_ref > 0); - lldp->n_ref --; - - if (lldp->n_ref > 0) - return NULL; +static sd_lldp* lldp_free(sd_lldp *lldp) { + assert(lldp); lldp_reset(lldp); sd_lldp_detach_event(lldp); @@ -360,6 +341,8 @@ _public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) { return mfree(lldp); } +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_lldp, sd_lldp, lldp_free); + _public_ int sd_lldp_new(sd_lldp **ret) { _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL; int r; @@ -388,10 +371,8 @@ _public_ int sd_lldp_new(sd_lldp **ret) { return 0; } -static int neighbor_compare_func(const void *a, const void *b) { - const sd_lldp_neighbor * const*x = a, * const *y = b; - - return lldp_neighbor_id_hash_ops.compare(&(*x)->id, &(*y)->id); +static int neighbor_compare_func(sd_lldp_neighbor * const *a, sd_lldp_neighbor * const *b) { + return lldp_neighbor_id_compare_func(&(*a)->id, &(*b)->id); } static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) { @@ -479,7 +460,7 @@ _public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) { assert((size_t) k == hashmap_size(lldp->neighbor_by_id)); /* Return things in a stable order */ - qsort(l, k, sizeof(sd_lldp_neighbor*), neighbor_compare_func); + typesafe_qsort(l, k, neighbor_compare_func); *ret = l; return k; diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c index 6e50fcc4c..880e12768 100644 --- a/src/systemd/src/libsystemd/sd-event/sd-event.c +++ b/src/systemd/src/libsystemd/sd-event/sd-event.c @@ -456,7 +456,7 @@ static void free_clock_data(struct clock_data *d) { prioq_free(d->latest); } -static void event_free(sd_event *e) { +static sd_event *event_free(sd_event *e) { sd_event_source *s; assert(e); @@ -492,7 +492,8 @@ static void event_free(sd_event *e) { hashmap_free(e->child_sources); set_free(e->post_sources); - free(e); + + return mfree(e); } _public_ int sd_event_new(sd_event** ret) { @@ -553,30 +554,7 @@ fail: return r; } -_public_ sd_event* sd_event_ref(sd_event *e) { - - if (!e) - return NULL; - - assert(e->n_ref >= 1); - e->n_ref++; - - return e; -} - -_public_ sd_event* sd_event_unref(sd_event *e) { - - if (!e) - return NULL; - - assert(e->n_ref >= 1); - e->n_ref--; - - if (e->n_ref <= 0) - event_free(e); - - return NULL; -} +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_event, sd_event, event_free); static bool event_pid_changed(sd_event *e) { assert(e); @@ -972,7 +950,7 @@ static void source_disconnect(sd_event_source *s) { * continued to being watched. That's because inotify doesn't really have an API for that: we * can only change watch masks with access to the original inode either by fd or by path. But * paths aren't stable, and keeping an O_PATH fd open all the time would mean wasting an fd - * continously and keeping the mount busy which we can't really do. We could reconstruct the + * continuously and keeping the mount busy which we can't really do. We could reconstruct the * original inode from /proc/self/fdinfo/$INOTIFY_FD (as all watch descriptors are listed * there), but given the need for open_by_handle_at() which is privileged and not universally * available this would be quite an incomplete solution. Hence we go the other way, leave the @@ -1021,6 +999,7 @@ static void source_free(sd_event_source *s) { free(s->description); free(s); } +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free); static int source_set_pending(sd_event_source *s, bool b) { int r; @@ -1114,7 +1093,7 @@ _public_ int sd_event_add_io( sd_event_io_handler_t callback, void *userdata) { - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; int r; assert_return(e, -EINVAL); @@ -1137,13 +1116,12 @@ _public_ int sd_event_add_io( s->enabled = SD_EVENT_ON; r = source_io_register(s, s->enabled, events); - if (r < 0) { - source_free(s); + if (r < 0) return r; - } if (ret) *ret = s; + TAKE_PTR(s); return 0; } @@ -1152,7 +1130,7 @@ static void initialize_perturb(sd_event *e) { sd_id128_t bootid = {}; /* When we sleep for longer, we try to realign the wakeup to - the same time wihtin each minute/second/250ms, so that + the same time within each minute/second/250ms, so that events all across the system can be coalesced into a single CPU wakeup. However, let's take some system-specific randomness for this value, so that in a network of systems @@ -1218,7 +1196,7 @@ _public_ int sd_event_add_time( void *userdata) { EventSourceType type; - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; struct clock_data *d; int r; @@ -1270,20 +1248,17 @@ _public_ int sd_event_add_time( r = prioq_put(d->earliest, s, &s->time.earliest_index); if (r < 0) - goto fail; + return r; r = prioq_put(d->latest, s, &s->time.latest_index); if (r < 0) - goto fail; + return r; if (ret) *ret = s; + TAKE_PTR(s); return 0; - -fail: - source_free(s); - return r; } static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { @@ -1299,7 +1274,7 @@ _public_ int sd_event_add_signal( sd_event_signal_handler_t callback, void *userdata) { - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; struct signal_data *d; sigset_t ss; int r; @@ -1339,16 +1314,15 @@ _public_ int sd_event_add_signal( e->signal_sources[sig] = s; r = event_make_signal_data(e, sig, &d); - if (r < 0) { - source_free(s); + if (r < 0) return r; - } /* Use the signal name as description for the event source by default */ (void) sd_event_source_set_description(s, signal_to_string(sig)); if (ret) *ret = s; + TAKE_PTR(s); return 0; } @@ -1361,7 +1335,7 @@ _public_ int sd_event_add_child( sd_event_child_handler_t callback, void *userdata) { - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; int r; assert_return(e, -EINVAL); @@ -1391,17 +1365,14 @@ _public_ int sd_event_add_child( s->enabled = SD_EVENT_ONESHOT; r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s); - if (r < 0) { - source_free(s); + if (r < 0) return r; - } e->n_enabled_child_sources++; r = event_make_signal_data(e, SIGCHLD, NULL); if (r < 0) { e->n_enabled_child_sources--; - source_free(s); return r; } @@ -1409,6 +1380,7 @@ _public_ int sd_event_add_child( if (ret) *ret = s; + TAKE_PTR(s); return 0; } @@ -1419,7 +1391,7 @@ _public_ int sd_event_add_defer( sd_event_handler_t callback, void *userdata) { - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; int r; assert_return(e, -EINVAL); @@ -1437,13 +1409,12 @@ _public_ int sd_event_add_defer( s->enabled = SD_EVENT_ONESHOT; r = source_set_pending(s, true); - if (r < 0) { - source_free(s); + if (r < 0) return r; - } if (ret) *ret = s; + TAKE_PTR(s); return 0; } @@ -1454,7 +1425,7 @@ _public_ int sd_event_add_post( sd_event_handler_t callback, void *userdata) { - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; int r; assert_return(e, -EINVAL); @@ -1476,13 +1447,12 @@ _public_ int sd_event_add_post( s->enabled = SD_EVENT_ON; r = set_put(e->post_sources, s); - if (r < 0) { - source_free(s); + if (r < 0) return r; - } if (ret) *ret = s; + TAKE_PTR(s); return 0; } @@ -1493,7 +1463,7 @@ _public_ int sd_event_add_exit( sd_event_handler_t callback, void *userdata) { - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; int r; assert_return(e, -EINVAL); @@ -1516,13 +1486,12 @@ _public_ int sd_event_add_exit( s->enabled = SD_EVENT_ONESHOT; r = prioq_put(s->event->exit, s, &s->exit.prioq_index); - if (r < 0) { - source_free(s); + if (r < 0) return r; - } if (ret) *ret = s; + TAKE_PTR(s); return 0; } @@ -1777,7 +1746,7 @@ static uint32_t inode_data_determine_mask(struct inode_data *d) { * * Note that we add all sources to the mask here, regardless whether enabled, disabled or oneshot. That's * because we cannot change the mask anymore after the event source was created once, since the kernel has no - * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and supress + * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and suppress * events we don't care for client-side. */ LIST_FOREACH(inotify.by_inode_data, s, d->event_sources) { @@ -1839,11 +1808,10 @@ _public_ int sd_event_add_inotify( sd_event_inotify_handler_t callback, void *userdata) { - bool rm_inotify = false, rm_inode = false; struct inotify_data *inotify_data = NULL; struct inode_data *inode_data = NULL; _cleanup_close_ int fd = -1; - sd_event_source *s; + _cleanup_(source_freep) sd_event_source *s = NULL; struct stat st; int r; @@ -1881,13 +1849,13 @@ _public_ int sd_event_add_inotify( /* Allocate an inotify object for this priority, and an inode object within it */ r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data); if (r < 0) - goto fail; - rm_inotify = r > 0; + return r; r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); - if (r < 0) - goto fail; - rm_inode = r > 0; + if (r < 0) { + event_free_inotify_data(e, inotify_data); + return r; + } /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of * the event source, until then, for which we need the original inode. */ @@ -1900,72 +1868,45 @@ _public_ int sd_event_add_inotify( LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s); s->inotify.inode_data = inode_data; - rm_inode = rm_inotify = false; - /* Actually realize the watch now */ r = inode_data_realize_watch(e, inode_data); if (r < 0) - goto fail; + return r; (void) sd_event_source_set_description(s, path); if (ret) *ret = s; + TAKE_PTR(s); return 0; - -fail: - source_free(s); - - if (rm_inode) - event_free_inode_data(e, inode_data); - - if (rm_inotify) - event_free_inotify_data(e, inotify_data); - - return r; } -_public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { - +static sd_event_source* event_source_free(sd_event_source *s) { if (!s) return NULL; - assert(s->n_ref >= 1); - s->n_ref++; - - return s; -} - -_public_ sd_event_source* sd_event_source_unref(sd_event_source *s) { + /* Here's a special hack: when we are called from a + * dispatch handler we won't free the event source + * immediately, but we will detach the fd from the + * epoll. This way it is safe for the caller to unref + * the event source and immediately close the fd, but + * we still retain a valid event source object after + * the callback. */ - if (!s) - return NULL; - - assert(s->n_ref >= 1); - s->n_ref--; - - if (s->n_ref <= 0) { - /* Here's a special hack: when we are called from a - * dispatch handler we won't free the event source - * immediately, but we will detach the fd from the - * epoll. This way it is safe for the caller to unref - * the event source and immediately close the fd, but - * we still retain a valid event source object after - * the callback. */ - - if (s->dispatching) { - if (s->type == SOURCE_IO) - source_io_unregister(s); + if (s->dispatching) { + if (s->type == SOURCE_IO) + source_io_unregister(s); - source_disconnect(s); - } else - source_free(s); - } + source_disconnect(s); + } else + source_free(s); return NULL; } +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_event_source, sd_event_source, event_source_free); + _public_ int sd_event_source_set_description(sd_event_source *s, const char *description) { assert_return(s, -EINVAL); assert_return(!event_pid_changed(s->event), -ECHILD); diff --git a/src/systemd/src/libsystemd/sd-id128/sd-id128.c b/src/systemd/src/libsystemd/sd-id128/sd-id128.c index 9d93732d7..b7cca832d 100644 --- a/src/systemd/src/libsystemd/sd-id128/sd-id128.c +++ b/src/systemd/src/libsystemd/sd-id128/sd-id128.c @@ -284,19 +284,15 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) { return 0; } -_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) { +static int get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret) { _cleanup_(khash_unrefp) khash *h = NULL; - sd_id128_t m, result; + sd_id128_t result; const void *p; int r; - assert_return(ret, -EINVAL); - - r = sd_id128_get_machine(&m); - if (r < 0) - return r; + assert(ret); - r = khash_new_with_key(&h, "hmac(sha256)", &m, sizeof(m)); + r = khash_new_with_key(&h, "hmac(sha256)", &base, sizeof(base)); if (r < 0) return r; @@ -314,3 +310,29 @@ _public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *re *ret = make_v4_uuid(result); return 0; } + +_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) { + sd_id128_t id; + int r; + + assert_return(ret, -EINVAL); + + r = sd_id128_get_machine(&id); + if (r < 0) + return r; + + return get_app_specific(id, app_id, ret); +} + +_public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret) { + sd_id128_t id; + int r; + + assert_return(ret, -EINVAL); + + r = sd_id128_get_boot(&id); + if (r < 0) + return r; + + return get_app_specific(id, app_id, ret); +} diff --git a/src/systemd/src/shared/dns-domain.c b/src/systemd/src/shared/dns-domain.c index 1ecfb77de..f24edf579 100644 --- a/src/systemd/src/shared/dns-domain.c +++ b/src/systemd/src/shared/dns-domain.c @@ -1284,7 +1284,7 @@ int dns_name_apply_idna(const char *name, char **ret) { log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r)); if (r == IDN2_2HYPHEN) - /* The name has two hypens — forbidden by IDNA2008 in some cases */ + /* 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; diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h index fa36dca90..43d38f5c7 100644 --- a/src/systemd/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/src/systemd/sd-dhcp6-client.h @@ -21,7 +21,6 @@ #include <inttypes.h> #include <net/ethernet.h> -#include <stdbool.h> #include <sys/types.h> #include "sd-dhcp6-lease.h" @@ -120,8 +119,15 @@ int sd_dhcp6_client_get_information_request( int sd_dhcp6_client_set_request_option( sd_dhcp6_client *client, uint16_t option); +int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, + int *delegation); int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, - bool delegation); + int delegation); +int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client, + int *request); +int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, + int request); +int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id); int sd_dhcp6_client_get_lease( sd_dhcp6_client *client, diff --git a/src/systemd/src/systemd/sd-id128.h b/src/systemd/src/systemd/sd-id128.h index 143a0ffb5..78cf9462b 100644 --- a/src/systemd/src/systemd/sd-id128.h +++ b/src/systemd/src/systemd/sd-id128.h @@ -42,6 +42,7 @@ int sd_id128_randomize(sd_id128_t *ret); int sd_id128_get_machine(sd_id128_t *ret); int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret); +int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); int sd_id128_get_boot(sd_id128_t *ret); int sd_id128_get_invocation(sd_id128_t *ret); |