systemd: update code from upstream (2019-09-24)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=a007d6fc2a2b9c19bafd6465fb4f00910b824c36 ( 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"
This commit is contained in:
@@ -78,7 +78,7 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
|
|||||||
* take possession of the extra space. This should be cheap, since libc doesn't have to move
|
* take possession of the extra space. This should be cheap, since libc doesn't have to move
|
||||||
* the memory for this. */
|
* the memory for this. */
|
||||||
|
|
||||||
qq = realloc(q, bn * size);
|
qq = reallocarray(q, bn, size);
|
||||||
if (_likely_(qq)) {
|
if (_likely_(qq)) {
|
||||||
*p = qq;
|
*p = qq;
|
||||||
*allocated = bn;
|
*allocated = bn;
|
||||||
|
@@ -485,6 +485,8 @@ static int merge_env_file_push(
|
|||||||
|
|
||||||
free_and_replace(value, expanded_value);
|
free_and_replace(value, expanded_value);
|
||||||
|
|
||||||
|
log_debug("%s:%u: setting %s=%s", filename, line, key, value);
|
||||||
|
|
||||||
return load_env_file_push(filename, line, key, value, env, n_pushed);
|
return load_env_file_push(filename, line, key, value, env, n_pushed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ static inline int negative_errno(void) {
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *strerror_safe(int error) {
|
static inline const char *strerror_safe(int error) {
|
||||||
/* 'safe' here does NOT mean thread safety. */
|
/* 'safe' here does NOT mean thread safety. */
|
||||||
return strerror(abs(error));
|
return strerror(abs(error));
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,6 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
|||||||
|
|
||||||
assert(p);
|
assert(p);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
/* Those two don't make sense together. */
|
|
||||||
assert(!FLAGS_SET(flags, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE));
|
|
||||||
|
|
||||||
/* Bail early if called after last value or with no input */
|
/* Bail early if called after last value or with no input */
|
||||||
if (!*p)
|
if (!*p)
|
||||||
|
@@ -930,10 +930,10 @@ int warn_file_is_world_accessible(const char *filename, struct stat *st, const c
|
|||||||
|
|
||||||
if (unit)
|
if (unit)
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
"%s has %04o mode that is too permissive, please adjust the access mode.",
|
"%s has %04o mode that is too permissive, please adjust the ownership and access mode.",
|
||||||
filename, st->st_mode & 07777);
|
filename, st->st_mode & 07777);
|
||||||
else
|
else
|
||||||
log_warning("%s has %04o mode that is too permissive, please adjust the access mode.",
|
log_warning("%s has %04o mode that is too permissive, please adjust the ownership and access mode.",
|
||||||
filename, st->st_mode & 07777);
|
filename, st->st_mode & 07777);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -732,7 +732,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||||||
* process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
|
* process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
|
||||||
* each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
|
* each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
|
||||||
* slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
|
* slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
|
||||||
* at a minimum.
|
* to a minimum.
|
||||||
*
|
*
|
||||||
* Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
|
* Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
|
||||||
* as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
|
* as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
|
||||||
@@ -742,9 +742,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||||||
* There are three ways to invoke this function:
|
* There are three ways to invoke this function:
|
||||||
*
|
*
|
||||||
* 1. Without CHASE_STEP or CHASE_OPEN: in this case the path is resolved and the normalized path is returned
|
* 1. Without CHASE_STEP or CHASE_OPEN: in this case the path is resolved and the normalized path is returned
|
||||||
* in `ret`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set 0 is returned if the file
|
* in `ret`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0 is returned if the file
|
||||||
* doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set >= 0 is returned if the destination was
|
* doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is returned if the destination was
|
||||||
* found, -ENOENT if it doesn't.
|
* found, -ENOENT if it wasn't.
|
||||||
*
|
*
|
||||||
* 2. With CHASE_OPEN: in this case the destination is opened after chasing it as O_PATH and this file
|
* 2. With CHASE_OPEN: in this case the destination is opened after chasing it as O_PATH and this file
|
||||||
* descriptor is returned as return value. This is useful to open files relative to some root
|
* descriptor is returned as return value. This is useful to open files relative to some root
|
||||||
@@ -760,13 +760,13 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||||||
*
|
*
|
||||||
* 4. With CHASE_SAFE: in this case the path must not contain unsafe transitions, i.e. transitions from
|
* 4. With CHASE_SAFE: in this case the path must not contain unsafe transitions, i.e. transitions from
|
||||||
* unprivileged to privileged files or directories. In such cases the return value is -ENOLINK. If
|
* unprivileged to privileged files or directories. In such cases the return value is -ENOLINK. If
|
||||||
* CHASE_WARN is also set a warning describing the unsafe transition is emitted.
|
* CHASE_WARN is also set, a warning describing the unsafe transition is emitted.
|
||||||
*
|
*
|
||||||
* 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, the path normalization is
|
* 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization
|
||||||
* aborted and -EREMOTE is returned. If CHASE_WARN is also set a warning showing the path of the mount point
|
* is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of
|
||||||
* is emitted.
|
* the mount point is emitted.
|
||||||
*
|
*
|
||||||
* */
|
*/
|
||||||
|
|
||||||
/* A root directory of "/" or "" is identical to none */
|
/* A root directory of "/" or "" is identical to none */
|
||||||
if (empty_or_root(original_root))
|
if (empty_or_root(original_root))
|
||||||
@@ -1298,6 +1298,17 @@ int fsync_directory_of_file(int fd) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fsync_full(int fd) {
|
||||||
|
int r, q;
|
||||||
|
|
||||||
|
/* Sync both the file and the directory */
|
||||||
|
|
||||||
|
r = fsync(fd) < 0 ? -errno : 0;
|
||||||
|
q = fsync_directory_of_file(fd);
|
||||||
|
|
||||||
|
return r < 0 ? r : q;
|
||||||
|
}
|
||||||
|
|
||||||
int fsync_path_at(int at_fd, const char *path) {
|
int fsync_path_at(int at_fd, const char *path) {
|
||||||
_cleanup_close_ int opened_fd = -1;
|
_cleanup_close_ int opened_fd = -1;
|
||||||
int fd;
|
int fd;
|
||||||
|
@@ -74,14 +74,16 @@ union inotify_event_buffer {
|
|||||||
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CHASE_PREFIX_ROOT = 1 << 0, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
|
CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */
|
||||||
CHASE_NONEXISTENT = 1 << 1, /* If set, it's OK if the path doesn't actually exist. */
|
CHASE_NONEXISTENT = 1 << 1, /* It's OK if the path doesn't actually exist. */
|
||||||
CHASE_NO_AUTOFS = 1 << 2, /* If set, return -EREMOTE if autofs mount point found */
|
CHASE_NO_AUTOFS = 1 << 2, /* Return -EREMOTE if autofs mount point found */
|
||||||
CHASE_SAFE = 1 << 3, /* If set, return EPERM if we ever traverse from unprivileged to privileged files or directories */
|
CHASE_SAFE = 1 << 3, /* Return EPERM if we ever traverse from unprivileged to privileged files or directories */
|
||||||
CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */
|
CHASE_OPEN = 1 << 4, /* Return an O_PATH object to the final component */
|
||||||
CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */
|
CHASE_TRAIL_SLASH = 1 << 5, /* Any trailing slash will be preserved */
|
||||||
CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */
|
CHASE_STEP = 1 << 6, /* Just execute a single step of the normalization */
|
||||||
CHASE_NOFOLLOW = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */
|
CHASE_NOFOLLOW = 1 << 7, /* Do not follow the path's right-most compontent. With CHASE_OPEN, when
|
||||||
|
* the path's right-most component refers to symlink, return O_PATH fd of
|
||||||
|
* the symlink. */
|
||||||
CHASE_WARN = 1 << 8, /* Emit an appropriate warning when an error is encountered */
|
CHASE_WARN = 1 << 8, /* Emit an appropriate warning when an error is encountered */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,6 +116,7 @@ void unlink_tempfilep(char (*p)[]);
|
|||||||
int unlinkat_deallocate(int fd, const char *name, int flags);
|
int unlinkat_deallocate(int fd, const char *name, int flags);
|
||||||
|
|
||||||
int fsync_directory_of_file(int fd);
|
int fsync_directory_of_file(int fd);
|
||||||
|
int fsync_full(int fd);
|
||||||
int fsync_path_at(int at_fd, const char *path);
|
int fsync_path_at(int at_fd, const char *path);
|
||||||
|
|
||||||
int syncfs_path(int atfd, const char *path);
|
int syncfs_path(int atfd, const char *path);
|
||||||
|
@@ -11,30 +11,38 @@
|
|||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
|
#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
|
||||||
|
#define PATH_SPLIT_BIN_SBIN(x) x "bin:" x "sbin"
|
||||||
#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
|
#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
|
||||||
|
|
||||||
#define PATH_NORMAL_SBIN_BIN(x) x "bin"
|
#define PATH_NORMAL_SBIN_BIN(x) x "bin"
|
||||||
|
#define PATH_NORMAL_BIN_SBIN(x) x "bin"
|
||||||
#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
|
#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
|
||||||
|
|
||||||
#if HAVE_SPLIT_BIN
|
#if HAVE_SPLIT_BIN
|
||||||
# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
|
# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
|
||||||
|
# define PATH_BIN_SBIN(x) PATH_SPLIT_BIN_SBIN(x)
|
||||||
# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
|
# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
|
||||||
#else
|
#else
|
||||||
# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
|
# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
|
||||||
|
# define PATH_BIN_SBIN(x) PATH_NORMAL_BIN_SBIN(x)
|
||||||
# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
|
# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
|
#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
|
||||||
|
#define DEFAULT_USER_PATH_NORMAL PATH_BIN_SBIN("/usr/local/") ":" PATH_BIN_SBIN("/usr/")
|
||||||
#define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
|
#define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
|
||||||
#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/")
|
#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/")
|
||||||
|
#define DEFAULT_USER_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_BIN_SBIN("/")
|
||||||
#define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/")
|
#define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/")
|
||||||
#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
|
#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
|
||||||
|
|
||||||
#if HAVE_SPLIT_USR
|
#if HAVE_SPLIT_USR
|
||||||
# define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
|
# define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
|
||||||
|
# define DEFAULT_USER_PATH DEFAULT_USER_PATH_SPLIT_USR
|
||||||
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR
|
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR
|
||||||
#else
|
#else
|
||||||
# define DEFAULT_PATH DEFAULT_PATH_NORMAL
|
# define DEFAULT_PATH DEFAULT_PATH_NORMAL
|
||||||
|
# define DEFAULT_USER_PATH DEFAULT_USER_PATH_NORMAL
|
||||||
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR
|
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -25,8 +25,10 @@
|
|||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
|
#include "fileio.h"
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
|
#include "parse-util.h"
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
@@ -389,3 +391,26 @@ void random_bytes(void *p, size_t n) {
|
|||||||
/* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */
|
/* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */
|
||||||
pseudo_random_bytes(p, n);
|
pseudo_random_bytes(p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t random_pool_size(void) {
|
||||||
|
_cleanup_free_ char *s = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Read pool size, if possible */
|
||||||
|
r = read_one_line_file("/proc/sys/kernel/random/poolsize", &s);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to read pool size from kernel: %m");
|
||||||
|
else {
|
||||||
|
unsigned sz;
|
||||||
|
|
||||||
|
r = safe_atou(s, &sz);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to parse pool size: %s", s);
|
||||||
|
else
|
||||||
|
/* poolsize is in bits on 2.6, but we want bytes */
|
||||||
|
return CLAMP(sz / 8, RANDOM_POOL_SIZE_MIN, RANDOM_POOL_SIZE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the minimum as default, if we can't retrieve the correct value */
|
||||||
|
return RANDOM_POOL_SIZE_MIN;
|
||||||
|
}
|
||||||
|
@@ -31,3 +31,9 @@ static inline uint32_t random_u32(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int rdrand(unsigned long *ret);
|
int rdrand(unsigned long *ret);
|
||||||
|
|
||||||
|
/* Some limits on the pool sizes when we deal with the kernel random pool */
|
||||||
|
#define RANDOM_POOL_SIZE_MIN 512U
|
||||||
|
#define RANDOM_POOL_SIZE_MAX (10U*1024U*1024U)
|
||||||
|
|
||||||
|
size_t random_pool_size(void);
|
||||||
|
@@ -157,6 +157,18 @@ void strv_print(char **l);
|
|||||||
_found; \
|
_found; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define ENDSWITH_SET(p, ...) \
|
||||||
|
({ \
|
||||||
|
const char *_p = (p); \
|
||||||
|
char *_found = NULL, **_i; \
|
||||||
|
STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \
|
||||||
|
_found = endswith(_p, *_i); \
|
||||||
|
if (_found) \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
_found; \
|
||||||
|
})
|
||||||
|
|
||||||
#define FOREACH_STRING(x, y, ...) \
|
#define FOREACH_STRING(x, y, ...) \
|
||||||
for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \
|
for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \
|
||||||
x; \
|
x; \
|
||||||
|
@@ -1191,7 +1191,10 @@ bool ntp_synced(void) {
|
|||||||
if (adjtimex(&txc) < 0)
|
if (adjtimex(&txc) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (txc.status & STA_UNSYNC)
|
/* Consider the system clock synchronized if the reported maximum error is smaller than the maximum
|
||||||
|
* value (16 seconds). Ignore the STA_UNSYNC flag as it may have been set to prevent the kernel from
|
||||||
|
* touching the RTC. */
|
||||||
|
if (txc.maxerror >= 16000000)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1414,8 +1417,8 @@ struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) {
|
|||||||
return utc ? gmtime_r(t, tm) : localtime_r(t, tm);
|
return utc ? gmtime_r(t, tm) : localtime_r(t, tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long usec_to_jiffies(usec_t u) {
|
static uint32_t sysconf_clock_ticks_cached(void) {
|
||||||
static thread_local unsigned long hz = 0;
|
static thread_local uint32_t hz = 0;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
if (hz == 0) {
|
if (hz == 0) {
|
||||||
@@ -1425,7 +1428,17 @@ unsigned long usec_to_jiffies(usec_t u) {
|
|||||||
hz = r;
|
hz = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
|
return hz;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usec_to_jiffies(usec_t u) {
|
||||||
|
uint32_t hz = sysconf_clock_ticks_cached();
|
||||||
|
return DIV_ROUND_UP(u, USEC_PER_SEC / hz);
|
||||||
|
}
|
||||||
|
|
||||||
|
usec_t jiffies_to_usec(uint32_t j) {
|
||||||
|
uint32_t hz = sysconf_clock_ticks_cached();
|
||||||
|
return DIV_ROUND_UP(j * USEC_PER_SEC, hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
|
usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
|
||||||
|
@@ -136,7 +136,8 @@ int get_timezone(char **timezone);
|
|||||||
time_t mktime_or_timegm(struct tm *tm, bool utc);
|
time_t mktime_or_timegm(struct tm *tm, bool utc);
|
||||||
struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
|
struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
|
||||||
|
|
||||||
unsigned long usec_to_jiffies(usec_t usec);
|
uint32_t usec_to_jiffies(usec_t usec);
|
||||||
|
usec_t jiffies_to_usec(uint32_t jiffies);
|
||||||
|
|
||||||
bool in_utc_timezone(void);
|
bool in_utc_timezone(void);
|
||||||
|
|
||||||
|
@@ -58,6 +58,9 @@ struct sd_dhcp_lease {
|
|||||||
struct in_addr *ntp;
|
struct in_addr *ntp;
|
||||||
size_t ntp_size;
|
size_t ntp_size;
|
||||||
|
|
||||||
|
struct in_addr *sip;
|
||||||
|
size_t sip_size;
|
||||||
|
|
||||||
struct sd_dhcp_route *static_route;
|
struct sd_dhcp_route *static_route;
|
||||||
size_t static_route_size, static_route_allocated;
|
size_t static_route_size, static_route_allocated;
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
|||||||
|
|
||||||
case SD_DHCP_OPTION_PAD:
|
case SD_DHCP_OPTION_PAD:
|
||||||
case SD_DHCP_OPTION_END:
|
case SD_DHCP_OPTION_END:
|
||||||
if (size < *offset + 1)
|
if (*offset + 1 > size)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
options[*offset] = code;
|
options[*offset] = code;
|
||||||
@@ -35,42 +35,57 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SD_DHCP_OPTION_USER_CLASS: {
|
case SD_DHCP_OPTION_USER_CLASS: {
|
||||||
size_t len = 0;
|
size_t total = 0;
|
||||||
char **s;
|
char **s;
|
||||||
|
|
||||||
STRV_FOREACH(s, (char **) optval)
|
|
||||||
len += strlen(*s) + 1;
|
|
||||||
|
|
||||||
if (size < *offset + len + 2)
|
|
||||||
return -ENOBUFS;
|
|
||||||
|
|
||||||
options[*offset] = code;
|
|
||||||
options[*offset + 1] = len;
|
|
||||||
*offset += 2;
|
|
||||||
|
|
||||||
STRV_FOREACH(s, (char **) optval) {
|
STRV_FOREACH(s, (char **) optval) {
|
||||||
len = strlen(*s);
|
size_t len = strlen(*s);
|
||||||
|
|
||||||
if (len > 255)
|
if (len > 255)
|
||||||
return -ENAMETOOLONG;
|
return -ENAMETOOLONG;
|
||||||
|
|
||||||
|
total += 1 + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*offset + 2 + total > size)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
options[*offset] = code;
|
||||||
|
options[*offset + 1] = total;
|
||||||
|
*offset += 2;
|
||||||
|
|
||||||
|
STRV_FOREACH(s, (char **) optval) {
|
||||||
|
size_t len = strlen(*s);
|
||||||
|
|
||||||
options[*offset] = len;
|
options[*offset] = len;
|
||||||
|
|
||||||
memcpy_safe(&options[*offset + 1], *s, len);
|
memcpy(&options[*offset + 1], *s, len);
|
||||||
*offset += len + 1;
|
*offset += 1 + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SD_DHCP_OPTION_SIP_SERVER:
|
||||||
|
if (*offset + 3 + optlen > size)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
options[*offset] = code;
|
||||||
|
options[*offset + 1] = optlen + 1;
|
||||||
|
options[*offset + 2] = 1;
|
||||||
|
|
||||||
|
memcpy_safe(&options[*offset + 3], optval, optlen);
|
||||||
|
*offset += 3 + optlen;
|
||||||
|
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (size < *offset + optlen + 2)
|
if (*offset + 2 + optlen > size)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
options[*offset] = code;
|
options[*offset] = code;
|
||||||
options[*offset + 1] = optlen;
|
options[*offset + 1] = optlen;
|
||||||
|
|
||||||
memcpy_safe(&options[*offset + 2], optval, optlen);
|
memcpy_safe(&options[*offset + 2], optval, optlen);
|
||||||
*offset += optlen + 2;
|
*offset += 2 + optlen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -81,22 +96,25 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
|||||||
int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
|
int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
|
||||||
uint8_t overload,
|
uint8_t overload,
|
||||||
uint8_t code, size_t optlen, const void *optval) {
|
uint8_t code, size_t optlen, const void *optval) {
|
||||||
size_t file_offset = 0, sname_offset =0;
|
const bool use_file = overload & DHCP_OVERLOAD_FILE;
|
||||||
bool file, sname;
|
const bool use_sname = overload & DHCP_OVERLOAD_SNAME;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
assert(offset);
|
assert(offset);
|
||||||
|
|
||||||
file = overload & DHCP_OVERLOAD_FILE;
|
/* If *offset is in range [0, size), we are writing to ->options,
|
||||||
sname = overload & DHCP_OVERLOAD_SNAME;
|
* if *offset is in range [size, size + sizeof(message->file)) and use_file, we are writing to ->file,
|
||||||
|
* if *offset is in range [size + use_file*sizeof(message->file), size + use_file*sizeof(message->file) + sizeof(message->sname))
|
||||||
|
* and use_sname, we are writing to ->sname.
|
||||||
|
*/
|
||||||
|
|
||||||
if (*offset < size) {
|
if (*offset < size) {
|
||||||
/* still space in the options array */
|
/* still space in the options array */
|
||||||
r = option_append(message->options, size, offset, code, optlen, optval);
|
r = option_append(message->options, size, offset, code, optlen, optval);
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
return 0;
|
return 0;
|
||||||
else if (r == -ENOBUFS && (file || sname)) {
|
else if (r == -ENOBUFS && (use_file || use_sname)) {
|
||||||
/* did not fit, but we have more buffers to try
|
/* did not fit, but we have more buffers to try
|
||||||
close the options array and move the offset to its end */
|
close the options array and move the offset to its end */
|
||||||
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
|
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
|
||||||
@@ -108,8 +126,8 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overload & DHCP_OVERLOAD_FILE) {
|
if (use_file) {
|
||||||
file_offset = *offset - size;
|
size_t file_offset = *offset - size;
|
||||||
|
|
||||||
if (file_offset < sizeof(message->file)) {
|
if (file_offset < sizeof(message->file)) {
|
||||||
/* still space in the 'file' array */
|
/* still space in the 'file' array */
|
||||||
@@ -117,7 +135,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
|
|||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
*offset = size + file_offset;
|
*offset = size + file_offset;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (r == -ENOBUFS && sname) {
|
} else if (r == -ENOBUFS && use_sname) {
|
||||||
/* did not fit, but we have more buffers to try
|
/* did not fit, but we have more buffers to try
|
||||||
close the file array and move the offset to its end */
|
close the file array and move the offset to its end */
|
||||||
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
|
r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL);
|
||||||
@@ -130,19 +148,18 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overload & DHCP_OVERLOAD_SNAME) {
|
if (use_sname) {
|
||||||
sname_offset = *offset - size - (file ? sizeof(message->file) : 0);
|
size_t sname_offset = *offset - size - use_file*sizeof(message->file);
|
||||||
|
|
||||||
if (sname_offset < sizeof(message->sname)) {
|
if (sname_offset < sizeof(message->sname)) {
|
||||||
/* still space in the 'sname' array */
|
/* still space in the 'sname' array */
|
||||||
r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval);
|
r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
*offset = size + (file ? sizeof(message->file) : 0) + sname_offset;
|
*offset = size + use_file*sizeof(message->file) + sname_offset;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else
|
||||||
/* no space, or other error, give up */
|
/* no space, or other error, give up */
|
||||||
return r;
|
return r;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -254,7 +254,7 @@ int config_parse_match_strv(
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
_cleanup_free_ char *word = NULL, *k = NULL;
|
_cleanup_free_ char *word = NULL, *k = NULL;
|
||||||
|
|
||||||
r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
|
r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
|
@@ -995,15 +995,14 @@ static int client_send_request(sd_dhcp_client *client) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (client->state == DHCP_STATE_RENEWING) {
|
if (client->state == DHCP_STATE_RENEWING)
|
||||||
r = dhcp_network_send_udp_socket(client->fd,
|
r = dhcp_network_send_udp_socket(client->fd,
|
||||||
client->lease->server_address,
|
client->lease->server_address,
|
||||||
DHCP_PORT_SERVER,
|
DHCP_PORT_SERVER,
|
||||||
&request->dhcp,
|
&request->dhcp,
|
||||||
sizeof(DHCPMessage) + optoffset);
|
sizeof(DHCPMessage) + optoffset);
|
||||||
} else {
|
else
|
||||||
r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
|
r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
|
||||||
}
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -1211,7 +1210,7 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
|
|||||||
assert(client);
|
assert(client);
|
||||||
assert(client->event);
|
assert(client->event);
|
||||||
|
|
||||||
if (client->start_delay) {
|
if (client->start_delay > 0) {
|
||||||
assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
|
assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
|
||||||
usec += client->start_delay;
|
usec += client->start_delay;
|
||||||
}
|
}
|
||||||
@@ -1882,6 +1881,17 @@ static int client_receive_message_raw(
|
|||||||
return client_handle_message(client, &packet->dhcp, len);
|
return client_handle_message(client, &packet->dhcp, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
|
||||||
|
assert_return(client, -EINVAL);
|
||||||
|
assert_return(client->fd >= 0, -EINVAL);
|
||||||
|
|
||||||
|
client->start_delay = 0;
|
||||||
|
client->attempt = 1;
|
||||||
|
client->state = DHCP_STATE_RENEWING;
|
||||||
|
|
||||||
|
return client_initialize_time_events(client);
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_start(sd_dhcp_client *client) {
|
int sd_dhcp_client_start(sd_dhcp_client *client) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@@ -120,6 +120,17 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
|||||||
return (int) lease->ntp_size;
|
return (int) lease->ntp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||||
|
assert_return(lease, -EINVAL);
|
||||||
|
assert_return(addr, -EINVAL);
|
||||||
|
|
||||||
|
if (lease->sip_size <= 0)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
*addr = lease->sip;
|
||||||
|
return (int) lease->sip_size;
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
|
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
|
||||||
assert_return(lease, -EINVAL);
|
assert_return(lease, -EINVAL);
|
||||||
assert_return(domainname, -EINVAL);
|
assert_return(domainname, -EINVAL);
|
||||||
@@ -269,6 +280,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
|
|||||||
free(lease->domainname);
|
free(lease->domainname);
|
||||||
free(lease->dns);
|
free(lease->dns);
|
||||||
free(lease->ntp);
|
free(lease->ntp);
|
||||||
|
free(lease->sip);
|
||||||
free(lease->static_route);
|
free(lease->static_route);
|
||||||
free(lease->client_id);
|
free(lease->client_id);
|
||||||
free(lease->vendor_specific);
|
free(lease->vendor_specific);
|
||||||
@@ -402,6 +414,36 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
|
||||||
|
assert(option);
|
||||||
|
assert(ret);
|
||||||
|
assert(n_ret);
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
*ret = mfree(*ret);
|
||||||
|
*n_ret = 0;
|
||||||
|
} else {
|
||||||
|
size_t n_addresses;
|
||||||
|
struct in_addr *addresses;
|
||||||
|
int l = len - 1;
|
||||||
|
|
||||||
|
if (l % 4 != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
n_addresses = l / 4;
|
||||||
|
|
||||||
|
addresses = newdup(struct in_addr, option + 1, n_addresses);
|
||||||
|
if (!addresses)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
free(*ret);
|
||||||
|
*ret = addresses;
|
||||||
|
*n_ret = n_addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int lease_parse_routes(
|
static int lease_parse_routes(
|
||||||
const uint8_t *option, size_t len,
|
const uint8_t *option, size_t len,
|
||||||
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
|
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
|
||||||
@@ -555,6 +597,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
|||||||
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
|
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SD_DHCP_OPTION_SIP_SERVER:
|
||||||
|
r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
|
||||||
|
break;
|
||||||
|
|
||||||
case SD_DHCP_OPTION_STATIC_ROUTE:
|
case SD_DHCP_OPTION_STATIC_ROUTE:
|
||||||
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
|
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -893,6 +941,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
|||||||
fputc('\n', f);
|
fputc('\n', f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = sd_dhcp_lease_get_sip(lease, &addresses);
|
||||||
|
if (r > 0) {
|
||||||
|
fputs("SIP=", f);
|
||||||
|
serialize_in_addrs(f, addresses, r, false, NULL);
|
||||||
|
fputc('\n', f);
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_dhcp_lease_get_domainname(lease, &string);
|
r = sd_dhcp_lease_get_domainname(lease, &string);
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
fprintf(f, "DOMAINNAME=%s\n", string);
|
fprintf(f, "DOMAINNAME=%s\n", string);
|
||||||
@@ -983,6 +1038,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||||||
*broadcast = NULL,
|
*broadcast = NULL,
|
||||||
*dns = NULL,
|
*dns = NULL,
|
||||||
*ntp = NULL,
|
*ntp = NULL,
|
||||||
|
*sip = NULL,
|
||||||
*mtu = NULL,
|
*mtu = NULL,
|
||||||
*routes = NULL,
|
*routes = NULL,
|
||||||
*domains = NULL,
|
*domains = NULL,
|
||||||
@@ -1011,6 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||||||
"BROADCAST", &broadcast,
|
"BROADCAST", &broadcast,
|
||||||
"DNS", &dns,
|
"DNS", &dns,
|
||||||
"NTP", &ntp,
|
"NTP", &ntp,
|
||||||
|
"SIP", &sip,
|
||||||
"MTU", &mtu,
|
"MTU", &mtu,
|
||||||
"DOMAINNAME", &lease->domainname,
|
"DOMAINNAME", &lease->domainname,
|
||||||
"HOSTNAME", &lease->hostname,
|
"HOSTNAME", &lease->hostname,
|
||||||
@@ -1115,6 +1172,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||||||
lease->ntp_size = r;
|
lease->ntp_size = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sip) {
|
||||||
|
r = deserialize_in_addrs(&lease->sip, sip);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
|
||||||
|
else
|
||||||
|
lease->ntp_size = r;
|
||||||
|
}
|
||||||
|
|
||||||
if (mtu) {
|
if (mtu) {
|
||||||
r = safe_atou16(mtu, &lease->mtu);
|
r = safe_atou16(mtu, &lease->mtu);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
|
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
|
||||||
|
|
||||||
|
#define IRT_DEFAULT (1 * USEC_PER_DAY)
|
||||||
|
#define IRT_MINIMUM (600 * USEC_PER_SEC)
|
||||||
|
|
||||||
/* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
|
/* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
|
||||||
enum {
|
enum {
|
||||||
DHCP6_REQUEST_IA_NA = 1,
|
DHCP6_REQUEST_IA_NA = 1,
|
||||||
@@ -71,6 +74,8 @@ struct sd_dhcp6_client {
|
|||||||
void *userdata;
|
void *userdata;
|
||||||
struct duid duid;
|
struct duid duid;
|
||||||
size_t duid_len;
|
size_t duid_len;
|
||||||
|
usec_t information_request_time_usec;
|
||||||
|
usec_t information_refresh_time_usec;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t default_req_opts[] = {
|
static const uint16_t default_req_opts[] = {
|
||||||
@@ -820,6 +825,7 @@ static int client_parse_message(
|
|||||||
uint32_t lt_t1 = ~0, lt_t2 = ~0;
|
uint32_t lt_t1 = ~0, lt_t2 = ~0;
|
||||||
bool clientid = false;
|
bool clientid = false;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
usec_t irt = IRT_DEFAULT;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(client);
|
assert(client);
|
||||||
@@ -994,6 +1000,13 @@ static int client_parse_message(
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
|
||||||
|
if (optlen != 4)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
irt = unaligned_read_be32((be32_t *) optval) * USEC_PER_SEC;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += offsetof(DHCP6Option, data) + optlen;
|
pos += offsetof(DHCP6Option, data) + optlen;
|
||||||
@@ -1025,6 +1038,8 @@ static int client_parse_message(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1425,8 +1440,15 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
|
|||||||
client->fd = r;
|
client->fd = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->information_request)
|
if (client->information_request) {
|
||||||
|
usec_t t = now(CLOCK_MONOTONIC);
|
||||||
|
|
||||||
|
if (t < usec_add(client->information_request_time_usec, client->information_refresh_time_usec))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
client->information_request_time_usec = t;
|
||||||
state = DHCP6_STATE_INFORMATION_REQUEST;
|
state = DHCP6_STATE_INFORMATION_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
log_dhcp6_client(client, "Started in %s mode",
|
log_dhcp6_client(client, "Started in %s mode",
|
||||||
client->information_request? "Information request":
|
client->information_request? "Information request":
|
||||||
|
@@ -87,6 +87,7 @@ enum {
|
|||||||
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
||||||
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
||||||
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
|
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
|
||||||
|
SD_DHCP_OPTION_SIP_SERVER = 120,
|
||||||
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
||||||
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
||||||
/* Windows 10 option to send when Anonymize=true */
|
/* Windows 10 option to send when Anonymize=true */
|
||||||
@@ -177,6 +178,7 @@ int sd_dhcp_client_get_lease(
|
|||||||
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
||||||
int sd_dhcp_client_start(sd_dhcp_client *client);
|
int sd_dhcp_client_start(sd_dhcp_client *client);
|
||||||
int sd_dhcp_client_send_release(sd_dhcp_client *client);
|
int sd_dhcp_client_send_release(sd_dhcp_client *client);
|
||||||
|
int sd_dhcp_client_send_renew(sd_dhcp_client *client);
|
||||||
|
|
||||||
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
|
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
|
||||||
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
|
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
|
||||||
|
@@ -44,6 +44,7 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
|
|||||||
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
|
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||||
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
|
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||||
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
|
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||||
|
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||||
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
|
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
|
||||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
|
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
|
||||||
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
|
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
|
||||||
|
@@ -66,6 +66,7 @@ enum {
|
|||||||
SD_DHCP6_OPTION_IA_PD_PREFIX = 26, /* RFC 3633, prefix delegation */
|
SD_DHCP6_OPTION_IA_PD_PREFIX = 26, /* RFC 3633, prefix delegation */
|
||||||
|
|
||||||
SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */
|
SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */
|
||||||
|
SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME = 32, /* RFC 8415, sec. 21.23 */
|
||||||
|
|
||||||
/* option code 35 is unassigned */
|
/* option code 35 is unassigned */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user