mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-06 09:40:17 +01:00
systemd: update code from upstream (2017-09-21)
This is a direct dump from systemd git on 2017-09-21, git commit
f679ed61163468f4fb2d4a17fa0984c8c1f0ba36.
======
SYSTEMD_DIR=../systemd
COMMIT=f679ed61163468f4fb2d4a17fa0984c8c1f0ba36
(
cd "$SYSTEMD_DIR"
git checkout "$COMMIT"
git reset --hard
git clean -fdx
)
git ls-files :/src/systemd/src/ | xargs -d '\n' rm -f
nm_copy_sd() {
mkdir -p "./src/systemd/$(dirname "$1")"
cp "$SYSTEMD_DIR/$1" "./src/systemd/$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/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.c"
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/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 "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"
This commit is contained in:
parent
770ad94cba
commit
eba874f859
9 changed files with 375 additions and 83 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/magic.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
@ -721,6 +722,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
|
||||
if (fstat(child, &st) < 0)
|
||||
return -errno;
|
||||
if ((flags & CHASE_NO_AUTOFS) &&
|
||||
fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
|
||||
return -EREMOTE;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
char *joined;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
|||
enum {
|
||||
CHASE_PREFIX_ROOT = 1, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
|
||||
CHASE_NONEXISTENT = 2, /* If set, it's OK if the path doesn't actually exist. */
|
||||
CHASE_NO_AUTOFS = 4, /* If set, return -EREMOTE if autofs mount point found */
|
||||
};
|
||||
|
||||
int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
|
||||
|
|
|
|||
|
|
@ -904,6 +904,28 @@ const char* personality_to_string(unsigned long p) {
|
|||
return architecture_to_string(architecture);
|
||||
}
|
||||
|
||||
int safe_personality(unsigned long p) {
|
||||
int ret;
|
||||
|
||||
/* So here's the deal, personality() is weirdly defined by glibc. In some cases it returns a failure via errno,
|
||||
* and in others as negative return value containing an errno-like value. Let's work around this: this is a
|
||||
* wrapper that uses errno if it is set, and uses the return value otherwise. And then it sets both errno and
|
||||
* the return value indicating the same issue, so that we are definitely on the safe side.
|
||||
*
|
||||
* See https://github.com/systemd/systemd/issues/6737 */
|
||||
|
||||
errno = 0;
|
||||
ret = personality(p);
|
||||
if (ret < 0) {
|
||||
if (errno != 0)
|
||||
return -errno;
|
||||
|
||||
errno = -ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int opinionated_personality(unsigned long *ret) {
|
||||
int current;
|
||||
|
||||
|
|
@ -911,9 +933,9 @@ int opinionated_personality(unsigned long *ret) {
|
|||
* opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the
|
||||
* two most relevant personalities: PER_LINUX and PER_LINUX32. */
|
||||
|
||||
current = personality(PERSONALITY_INVALID);
|
||||
current = safe_personality(PERSONALITY_INVALID);
|
||||
if (current < 0)
|
||||
return -errno;
|
||||
return current;
|
||||
|
||||
if (((unsigned long) current & 0xffff) == PER_LINUX32)
|
||||
*ret = PER_LINUX32;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ bool oom_score_adjust_is_valid(int oa);
|
|||
unsigned long personality_from_string(const char *p);
|
||||
const char *personality_to_string(unsigned long);
|
||||
|
||||
int safe_personality(unsigned long p);
|
||||
int opinionated_personality(unsigned long *ret);
|
||||
|
||||
int ioprio_class_to_string_alloc(int i, char **s);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
|
@ -596,7 +597,7 @@ int timestamp_deserialize(const char *value, usec_t *timestamp) {
|
|||
return r;
|
||||
}
|
||||
|
||||
int parse_timestamp(const char *t, usec_t *usec) {
|
||||
static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
|
||||
static const struct {
|
||||
const char *name;
|
||||
const int nr;
|
||||
|
|
@ -617,7 +618,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
|||
{ "Sat", 6 },
|
||||
};
|
||||
|
||||
const char *k, *utc, *tzn = NULL;
|
||||
const char *k, *utc = NULL, *tzn = NULL;
|
||||
struct tm tm, copy;
|
||||
time_t x;
|
||||
usec_t x_usec, plus = 0, minus = 0, ret;
|
||||
|
|
@ -645,84 +646,86 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
|||
assert(t);
|
||||
assert(usec);
|
||||
|
||||
if (t[0] == '@')
|
||||
if (t[0] == '@' && !with_tz)
|
||||
return parse_sec(t + 1, usec);
|
||||
|
||||
ret = now(CLOCK_REALTIME);
|
||||
|
||||
if (streq(t, "now"))
|
||||
goto finish;
|
||||
if (!with_tz) {
|
||||
if (streq(t, "now"))
|
||||
goto finish;
|
||||
|
||||
else if (t[0] == '+') {
|
||||
r = parse_sec(t+1, &plus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
else if (t[0] == '+') {
|
||||
r = parse_sec(t+1, &plus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
goto finish;
|
||||
goto finish;
|
||||
|
||||
} else if (t[0] == '-') {
|
||||
r = parse_sec(t+1, &minus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (t[0] == '-') {
|
||||
r = parse_sec(t+1, &minus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
goto finish;
|
||||
goto finish;
|
||||
|
||||
} else if ((k = endswith(t, " ago"))) {
|
||||
t = strndupa(t, k - t);
|
||||
} else if ((k = endswith(t, " ago"))) {
|
||||
t = strndupa(t, k - t);
|
||||
|
||||
r = parse_sec(t, &minus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = parse_sec(t, &minus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
goto finish;
|
||||
goto finish;
|
||||
|
||||
} else if ((k = endswith(t, " left"))) {
|
||||
t = strndupa(t, k - t);
|
||||
} else if ((k = endswith(t, " left"))) {
|
||||
t = strndupa(t, k - t);
|
||||
|
||||
r = parse_sec(t, &plus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = parse_sec(t, &plus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* See if the timestamp is suffixed with UTC */
|
||||
utc = endswith_no_case(t, " UTC");
|
||||
if (utc)
|
||||
t = strndupa(t, utc - t);
|
||||
else {
|
||||
const char *e = NULL;
|
||||
int j;
|
||||
|
||||
tzset();
|
||||
|
||||
/* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note that we only
|
||||
* support the local timezones here, nothing else. Not because we wouldn't want to, but simply because
|
||||
* there are no nice APIs available to cover this. By accepting the local time zone strings, we make
|
||||
* sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't
|
||||
* support arbitrary timezone specifications. */
|
||||
|
||||
for (j = 0; j <= 1; j++) {
|
||||
|
||||
if (isempty(tzname[j]))
|
||||
continue;
|
||||
|
||||
e = endswith_no_case(t, tzname[j]);
|
||||
if (!e)
|
||||
continue;
|
||||
if (e == t)
|
||||
continue;
|
||||
if (e[-1] != ' ')
|
||||
continue;
|
||||
|
||||
break;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (IN_SET(j, 0, 1)) {
|
||||
/* Found one of the two timezones specified. */
|
||||
t = strndupa(t, e - t - 1);
|
||||
dst = j;
|
||||
tzn = tzname[j];
|
||||
/* See if the timestamp is suffixed with UTC */
|
||||
utc = endswith_no_case(t, " UTC");
|
||||
if (utc)
|
||||
t = strndupa(t, utc - t);
|
||||
else {
|
||||
const char *e = NULL;
|
||||
int j;
|
||||
|
||||
tzset();
|
||||
|
||||
/* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note that we only
|
||||
* support the local timezones here, nothing else. Not because we wouldn't want to, but simply because
|
||||
* there are no nice APIs available to cover this. By accepting the local time zone strings, we make
|
||||
* sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't
|
||||
* support arbitrary timezone specifications. */
|
||||
|
||||
for (j = 0; j <= 1; j++) {
|
||||
|
||||
if (isempty(tzname[j]))
|
||||
continue;
|
||||
|
||||
e = endswith_no_case(t, tzname[j]);
|
||||
if (!e)
|
||||
continue;
|
||||
if (e == t)
|
||||
continue;
|
||||
if (e[-1] != ' ')
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (IN_SET(j, 0, 1)) {
|
||||
/* Found one of the two timezones specified. */
|
||||
t = strndupa(t, e - t - 1);
|
||||
dst = j;
|
||||
tzn = tzname[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -733,7 +736,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
|||
return -EINVAL;
|
||||
|
||||
tm.tm_isdst = dst;
|
||||
if (tzn)
|
||||
if (!with_tz && tzn)
|
||||
tm.tm_zone = tzn;
|
||||
|
||||
if (streq(t, "today")) {
|
||||
|
|
@ -874,6 +877,67 @@ finish:
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef struct ParseTimestampResult {
|
||||
usec_t usec;
|
||||
int return_value;
|
||||
} ParseTimestampResult;
|
||||
|
||||
int parse_timestamp(const char *t, usec_t *usec) {
|
||||
char *last_space, *timezone = NULL;
|
||||
ParseTimestampResult *shared, tmp;
|
||||
int r;
|
||||
pid_t pid;
|
||||
|
||||
last_space = strrchr(t, ' ');
|
||||
if (last_space != NULL && timezone_is_valid(last_space + 1))
|
||||
timezone = last_space + 1;
|
||||
|
||||
if (timezone == NULL || endswith_no_case(t, " UTC"))
|
||||
return parse_timestamp_impl(t, usec, false);
|
||||
|
||||
t = strndupa(t, last_space - t);
|
||||
|
||||
shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||
if (shared == MAP_FAILED)
|
||||
return negative_errno();
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
int fork_errno = errno;
|
||||
(void) munmap(shared, sizeof *shared);
|
||||
return -fork_errno;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
if (setenv("TZ", timezone, 1) != 0) {
|
||||
shared->return_value = negative_errno();
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
tzset();
|
||||
|
||||
shared->return_value = parse_timestamp_impl(t, &shared->usec, true);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
r = wait_for_terminate(pid, NULL);
|
||||
if (r < 0) {
|
||||
(void) munmap(shared, sizeof *shared);
|
||||
return r;
|
||||
}
|
||||
|
||||
tmp = *shared;
|
||||
if (munmap(shared, sizeof *shared) != 0)
|
||||
return negative_errno();
|
||||
|
||||
if (tmp.return_value == 0)
|
||||
*usec = tmp.usec;
|
||||
|
||||
return tmp.return_value;
|
||||
}
|
||||
|
||||
static char* extract_multiplier(char *p, usec_t *multiplier) {
|
||||
static const struct {
|
||||
const char *suffix;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "btrfs-util.h"
|
||||
#include "build.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "def.h"
|
||||
|
|
@ -719,3 +720,133 @@ int version(void) {
|
|||
SYSTEMD_FEATURES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_block_device(const char *path, dev_t *dev) {
|
||||
struct stat st;
|
||||
struct statfs sfs;
|
||||
|
||||
assert(path);
|
||||
assert(dev);
|
||||
|
||||
/* Get's the block device directly backing a file system. If
|
||||
* the block device is encrypted, returns the device mapper
|
||||
* block device. */
|
||||
|
||||
if (lstat(path, &st))
|
||||
return -errno;
|
||||
|
||||
if (major(st.st_dev) != 0) {
|
||||
*dev = st.st_dev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (statfs(path, &sfs) < 0)
|
||||
return -errno;
|
||||
|
||||
if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
|
||||
return btrfs_get_block_device(path, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_block_device_harder(const char *path, dev_t *dev) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
_cleanup_free_ char *p = NULL, *t = NULL;
|
||||
struct dirent *de, *found = NULL;
|
||||
const char *q;
|
||||
unsigned maj, min;
|
||||
dev_t dt;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(dev);
|
||||
|
||||
/* Gets the backing block device for a file system, and
|
||||
* handles LUKS encrypted file systems, looking for its
|
||||
* immediate parent, if there is one. */
|
||||
|
||||
r = get_block_device(path, &dt);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
d = opendir(p);
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
goto fallback;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
FOREACH_DIRENT_ALL(de, d, return -errno) {
|
||||
|
||||
if (dot_or_dot_dot(de->d_name))
|
||||
continue;
|
||||
|
||||
if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
|
||||
continue;
|
||||
|
||||
if (found) {
|
||||
_cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL;
|
||||
|
||||
/* We found a device backed by multiple other devices. We don't really support automatic
|
||||
* discovery on such setups, with the exception of dm-verity partitions. In this case there are
|
||||
* two backing devices: the data partition and the hash partition. We are fine with such
|
||||
* setups, however, only if both partitions are on the same physical device. Hence, let's
|
||||
* verify this. */
|
||||
|
||||
u = strjoin(p, "/", de->d_name, "/../dev");
|
||||
if (!u)
|
||||
return -ENOMEM;
|
||||
|
||||
v = strjoin(p, "/", found->d_name, "/../dev");
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
r = read_one_line_file(u, &a);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to read %s: %m", u);
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
r = read_one_line_file(v, &b);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to read %s: %m", v);
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
/* Check if the parent device is the same. If not, then the two backing devices are on
|
||||
* different physical devices, and we don't support that. */
|
||||
if (!streq(a, b))
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
found = de;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
goto fallback;
|
||||
|
||||
q = strjoina(p, "/", found->d_name, "/dev");
|
||||
|
||||
r = read_one_line_file(q, &t);
|
||||
if (r == -ENOENT)
|
||||
goto fallback;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (sscanf(t, "%u:%u", &maj, &min) != 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (maj == 0)
|
||||
goto fallback;
|
||||
|
||||
*dev = makedev(maj, min);
|
||||
return 1;
|
||||
|
||||
fallback:
|
||||
*dev = dt;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,3 +192,6 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
|
|||
int update_reboot_parameter_and_warn(const char *param);
|
||||
|
||||
int version(void);
|
||||
|
||||
int get_block_device(const char *path, dev_t *dev);
|
||||
int get_block_device_harder(const char *path, dev_t *dev);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ struct sd_dhcp_client {
|
|||
uint8_t *req_opts;
|
||||
size_t req_opts_allocated;
|
||||
size_t req_opts_size;
|
||||
bool anonymize;
|
||||
be32_t last_addr;
|
||||
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
|
||||
size_t mac_addr_len;
|
||||
|
|
@ -116,6 +117,32 @@ static const uint8_t default_req_opts[] = {
|
|||
SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
|
||||
};
|
||||
|
||||
/* RFC7844 section 3:
|
||||
MAY contain the Parameter Request List option.
|
||||
RFC7844 section 3.6:
|
||||
The client intending to protect its privacy SHOULD only request a
|
||||
minimal number of options in the PRL and SHOULD also randomly shuffle
|
||||
the ordering of option codes in the PRL. If this random ordering
|
||||
cannot be implemented, the client MAY order the option codes in the
|
||||
PRL by option code number (lowest to highest).
|
||||
*/
|
||||
/* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
|
||||
static const uint8_t default_req_opts_anonymize[] = {
|
||||
SD_DHCP_OPTION_SUBNET_MASK, /* 1 */
|
||||
SD_DHCP_OPTION_ROUTER, /* 3 */
|
||||
SD_DHCP_OPTION_DOMAIN_NAME_SERVER, /* 6 */
|
||||
SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */
|
||||
SD_DHCP_OPTION_ROUTER_DISCOVER, /* 31 */
|
||||
SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */
|
||||
SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */
|
||||
SD_DHCP_OPTION_NETBIOS_NAMESERVER, /* 44 */
|
||||
SD_DHCP_OPTION_NETBIOS_NODETYPE, /* 46 */
|
||||
SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */
|
||||
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, /* 121 */
|
||||
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, /* 249 */
|
||||
SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, /* 252 */
|
||||
};
|
||||
|
||||
static int client_receive_message_raw(
|
||||
sd_event_source *s,
|
||||
int fd,
|
||||
|
|
@ -588,11 +615,18 @@ static int client_message_init(
|
|||
it MUST include that list in any subsequent DHCPREQUEST
|
||||
messages.
|
||||
*/
|
||||
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
|
||||
client->req_opts_size, client->req_opts);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* RFC7844 section 3:
|
||||
MAY contain the Parameter Request List option. */
|
||||
/* NOTE: in case that there would be an option to do not send
|
||||
* any PRL at all, the size should be checked before sending */
|
||||
if (client->req_opts_size > 0) {
|
||||
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
|
||||
client->req_opts_size, client->req_opts);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* RFC2131 section 3.5:
|
||||
The client SHOULD include the ’maximum DHCP message size’ option to
|
||||
|
|
@ -616,12 +650,16 @@ static int client_message_init(
|
|||
Maximum DHCP Message Size option is the total maximum packet size,
|
||||
including IP and UDP headers.)
|
||||
*/
|
||||
max_size = htobe16(size);
|
||||
r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
|
||||
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
|
||||
2, &max_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
/* RFC7844 section 3:
|
||||
SHOULD NOT contain any other option. */
|
||||
if (!client->anonymize) {
|
||||
max_size = htobe16(size);
|
||||
r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
|
||||
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
|
||||
2, &max_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*_optlen = optlen;
|
||||
*_optoffset = optoffset;
|
||||
|
|
@ -1783,7 +1821,14 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (client->last_addr)
|
||||
/* RFC7844 section 3.3:
|
||||
SHOULD perform a complete four-way handshake, starting with a
|
||||
DHCPDISCOVER, to obtain a new address lease. If the client can
|
||||
ascertain that this is exactly the same network to which it was
|
||||
previously connected, and if the link-layer address did not change,
|
||||
the client MAY issue a DHCPREQUEST to try to reclaim the current
|
||||
address. */
|
||||
if (client->last_addr && !client->anonymize)
|
||||
client->state = DHCP_STATE_INIT_REBOOT;
|
||||
|
||||
r = client_start(client);
|
||||
|
|
@ -1875,7 +1920,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
|
|||
return mfree(client);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_new(sd_dhcp_client **ret) {
|
||||
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
|
||||
_cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
|
@ -1892,8 +1937,15 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) {
|
|||
client->mtu = DHCP_DEFAULT_MIN_SIZE;
|
||||
client->port = DHCP_PORT_CLIENT;
|
||||
|
||||
client->req_opts_size = ELEMENTSOF(default_req_opts);
|
||||
client->req_opts = memdup(default_req_opts, client->req_opts_size);
|
||||
client->anonymize = !!anonymize;
|
||||
/* NOTE: this could be moved to a function. */
|
||||
if (anonymize) {
|
||||
client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
|
||||
client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
|
||||
} else {
|
||||
client->req_opts_size = ELEMENTSOF(default_req_opts);
|
||||
client->req_opts = memdup(default_req_opts, client->req_opts_size);
|
||||
}
|
||||
if (!client->req_opts)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -58,9 +58,17 @@ enum {
|
|||
SD_DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
|
||||
SD_DHCP_OPTION_INTERFACE_MTU = 26,
|
||||
SD_DHCP_OPTION_BROADCAST = 28,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
SD_DHCP_OPTION_ROUTER_DISCOVER = 31,
|
||||
SD_DHCP_OPTION_STATIC_ROUTE = 33,
|
||||
SD_DHCP_OPTION_NTP_SERVER = 42,
|
||||
SD_DHCP_OPTION_VENDOR_SPECIFIC = 43,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
SD_DHCP_OPTION_NETBIOS_NAMESERVER = 44,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
SD_DHCP_OPTION_NETBIOS_NODETYPE = 46,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
SD_DHCP_OPTION_NETBIOS_SCOPE = 47,
|
||||
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
|
||||
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
|
||||
SD_DHCP_OPTION_OVERLOAD = 52,
|
||||
|
|
@ -79,6 +87,10 @@ enum {
|
|||
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
|
||||
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
||||
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252,
|
||||
SD_DHCP_OPTION_PRIVATE_LAST = 254,
|
||||
SD_DHCP_OPTION_END = 255,
|
||||
};
|
||||
|
|
@ -146,7 +158,9 @@ int sd_dhcp_client_start(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);
|
||||
|
||||
int sd_dhcp_client_new(sd_dhcp_client **ret);
|
||||
/* NOTE: anonymize parameter is used to initialize PRL memory with different
|
||||
* options when using RFC7844 Anonymity Profiles */
|
||||
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize);
|
||||
|
||||
int sd_dhcp_client_attach_event(
|
||||
sd_dhcp_client *client,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue