systemd: update code from upstream (2017-06-14)
This is a direct dump from systemd git on 2017-06-14, git commit 42d3bf86bb75842602d3712caa2baccd09a1c795. ====== SYSTEMD_DIR=../systemd COMMIT=42d3bf86bb75842602d3712caa2baccd09a1c795 ( 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/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:
@@ -51,7 +51,7 @@
|
||||
|
||||
#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
|
||||
|
||||
int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
|
||||
int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts) {
|
||||
|
||||
assert(f);
|
||||
assert(line);
|
||||
@@ -60,6 +60,13 @@ int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
|
||||
if (enforce_newline && !endswith(line, "\n"))
|
||||
fputc('\n', f);
|
||||
|
||||
if (ts) {
|
||||
struct timespec twice[2] = {*ts, *ts};
|
||||
|
||||
if (futimens(fileno(f), twice) < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return fflush_and_check(f);
|
||||
}
|
||||
|
||||
@@ -89,7 +96,7 @@ static int write_string_file_atomic(const char *fn, const char *line, bool enfor
|
||||
return r;
|
||||
}
|
||||
|
||||
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
|
||||
int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int q, r;
|
||||
|
||||
@@ -104,7 +111,8 @@ int write_string_file(const char *fn, const char *line, WriteStringFileFlags fla
|
||||
goto fail;
|
||||
|
||||
return r;
|
||||
}
|
||||
} else
|
||||
assert(ts == NULL);
|
||||
|
||||
if (flags & WRITE_STRING_FILE_CREATE) {
|
||||
f = fopen(fn, "we");
|
||||
@@ -131,7 +139,7 @@ int write_string_file(const char *fn, const char *line, WriteStringFileFlags fla
|
||||
}
|
||||
}
|
||||
|
||||
r = write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
|
||||
r = write_string_stream_ts(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE), ts);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
@@ -35,8 +35,14 @@ typedef enum {
|
||||
WRITE_STRING_FILE_VERIFY_ON_FAILURE = 8,
|
||||
} WriteStringFileFlags;
|
||||
|
||||
int write_string_stream(FILE *f, const char *line, bool enforce_newline);
|
||||
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags);
|
||||
int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts);
|
||||
static inline int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
|
||||
return write_string_stream_ts(f, line, enforce_newline, NULL);
|
||||
}
|
||||
int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
|
||||
static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
|
||||
return write_string_file_ts(fn, line, flags, NULL);
|
||||
}
|
||||
|
||||
int read_one_line_file(const char *fn, char **line);
|
||||
int read_full_file(const char *fn, char **contents, size_t *size);
|
||||
|
@@ -31,6 +31,16 @@
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
typedef enum LogRealm {
|
||||
LOG_REALM_SYSTEMD,
|
||||
LOG_REALM_UDEV,
|
||||
_LOG_REALM_MAX,
|
||||
} LogRealm;
|
||||
|
||||
#ifndef LOG_REALM
|
||||
# define LOG_REALM LOG_REALM_SYSTEMD
|
||||
#endif
|
||||
|
||||
typedef enum LogTarget{
|
||||
LOG_TARGET_CONSOLE,
|
||||
LOG_TARGET_CONSOLE_PREFIXED,
|
||||
@@ -46,12 +56,22 @@ typedef enum LogTarget{
|
||||
_LOG_TARGET_INVALID = -1
|
||||
} LogTarget;
|
||||
|
||||
#define LOG_REALM_PLUS_LEVEL(realm, level) \
|
||||
((realm) << 10 | (level))
|
||||
#define LOG_REALM_REMOVE_LEVEL(realm_level) \
|
||||
((realm_level >> 10))
|
||||
|
||||
void log_set_target(LogTarget target);
|
||||
void log_set_max_level(int level);
|
||||
void log_set_max_level_realm(LogRealm realm, int level);
|
||||
#define log_set_max_level(level) \
|
||||
log_set_max_level_realm(LOG_REALM, (level))
|
||||
|
||||
void log_set_facility(int facility);
|
||||
|
||||
int log_set_target_from_string(const char *e);
|
||||
int log_set_max_level_from_string(const char *e);
|
||||
int log_set_max_level_from_string_realm(LogRealm realm, const char *e);
|
||||
#define log_set_max_level_from_string(e) \
|
||||
log_set_max_level_from_string_realm(LOG_REALM, (e))
|
||||
|
||||
void log_show_color(bool b);
|
||||
bool log_get_show_color(void) _pure_;
|
||||
@@ -62,7 +82,9 @@ int log_show_color_from_string(const char *e);
|
||||
int log_show_location_from_string(const char *e);
|
||||
|
||||
LogTarget log_get_target(void) _pure_;
|
||||
int log_get_max_level(void) _pure_;
|
||||
int log_get_max_level_realm(LogRealm realm) _pure_;
|
||||
#define log_get_max_level() \
|
||||
log_get_max_level_realm(LOG_REALM)
|
||||
|
||||
int log_open(void);
|
||||
void log_close(void);
|
||||
@@ -73,7 +95,9 @@ void log_close_journal(void);
|
||||
void log_close_kmsg(void);
|
||||
void log_close_console(void);
|
||||
|
||||
void log_parse_environment(void);
|
||||
void log_parse_environment_realm(LogRealm realm);
|
||||
#define log_parse_environment() \
|
||||
log_parse_environment_realm(LOG_REALM)
|
||||
|
||||
int log_dispatch_internal(
|
||||
int level,
|
||||
@@ -87,15 +111,17 @@ int log_dispatch_internal(
|
||||
const char *extra_field,
|
||||
char *buffer);
|
||||
|
||||
int log_internal(
|
||||
int log_internal_realm(
|
||||
int level,
|
||||
int error,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *func,
|
||||
const char *format, ...) _printf_(6,7);
|
||||
#define log_internal(level, ...) \
|
||||
log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
|
||||
|
||||
int log_internalv(
|
||||
int log_internalv_realm(
|
||||
int level,
|
||||
int error,
|
||||
const char *file,
|
||||
@@ -103,7 +129,10 @@ int log_internalv(
|
||||
const char *func,
|
||||
const char *format,
|
||||
va_list ap) _printf_(6,0);
|
||||
#define log_internalv(level, ...) \
|
||||
log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
|
||||
|
||||
/* Realm is fixed to LOG_REALM_SYSTEMD for those */
|
||||
int log_object_internal(
|
||||
int level,
|
||||
int error,
|
||||
@@ -138,6 +167,7 @@ int log_struct_internal(
|
||||
const char *format, ...) _printf_(6,0) _sentinel_;
|
||||
|
||||
int log_oom_internal(
|
||||
LogRealm realm,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *func);
|
||||
@@ -161,37 +191,50 @@ int log_dump_internal(
|
||||
char *buffer);
|
||||
|
||||
/* Logging for various assertions */
|
||||
noreturn void log_assert_failed(
|
||||
noreturn void log_assert_failed_realm(
|
||||
LogRealm realm,
|
||||
const char *text,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *func);
|
||||
#define log_assert_failed(text, ...) \
|
||||
log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__)
|
||||
|
||||
noreturn void log_assert_failed_unreachable(
|
||||
noreturn void log_assert_failed_unreachable_realm(
|
||||
LogRealm realm,
|
||||
const char *text,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *func);
|
||||
#define log_assert_failed_unreachable(text, ...) \
|
||||
log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__)
|
||||
|
||||
void log_assert_failed_return(
|
||||
void log_assert_failed_return_realm(
|
||||
LogRealm realm,
|
||||
const char *text,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *func);
|
||||
#define log_assert_failed_return(text, ...) \
|
||||
log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__)
|
||||
|
||||
#define log_dispatch(level, error, buffer) \
|
||||
log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
|
||||
|
||||
/* Logging with level */
|
||||
#define log_full_errno(level, error, ...) \
|
||||
#define log_full_errno_realm(realm, level, error, ...) \
|
||||
({ \
|
||||
int _level = (level), _e = (error); \
|
||||
(log_get_max_level() >= LOG_PRI(_level)) \
|
||||
? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
|
||||
(log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \
|
||||
? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \
|
||||
__FILE__, __LINE__, __func__, __VA_ARGS__) \
|
||||
: -abs(_e); \
|
||||
})
|
||||
|
||||
#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
|
||||
#define log_full_errno(level, error, ...) \
|
||||
log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
|
||||
|
||||
#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
|
||||
|
||||
/* Normal logging */
|
||||
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
|
||||
@@ -216,13 +259,17 @@ void log_assert_failed_return(
|
||||
#endif
|
||||
|
||||
/* Structured logging */
|
||||
#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_struct_errno(level, error, ...) \
|
||||
log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
|
||||
error, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
|
||||
|
||||
/* This modifies the buffer passed! */
|
||||
#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer)
|
||||
#define log_dump(level, buffer) \
|
||||
log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
|
||||
0, __FILE__, __LINE__, __func__, buffer)
|
||||
|
||||
#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
|
||||
#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
|
||||
|
||||
bool log_on_console(void) _pure_;
|
||||
|
||||
|
@@ -19,7 +19,6 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/param.h>
|
||||
|
@@ -555,15 +555,29 @@ void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
|
||||
|
||||
int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
|
||||
uint64_t a, b;
|
||||
int r, pos;
|
||||
|
||||
assert(value);
|
||||
assert(t);
|
||||
|
||||
if (sscanf(value, "%" PRIu64 "%" PRIu64, &a, &b) != 2) {
|
||||
log_debug("Failed to parse dual timestamp value \"%s\": %m", value);
|
||||
pos = strspn(value, WHITESPACE);
|
||||
if (value[pos] == '-')
|
||||
return -EINVAL;
|
||||
pos += strspn(value + pos, DIGITS);
|
||||
pos += strspn(value + pos, WHITESPACE);
|
||||
if (value[pos] == '-')
|
||||
return -EINVAL;
|
||||
|
||||
r = sscanf(value, "%" PRIu64 "%" PRIu64 "%n", &a, &b, &pos);
|
||||
if (r != 2) {
|
||||
log_debug("Failed to parse dual timestamp value \"%s\".", value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (value[pos] != '\0')
|
||||
/* trailing garbage */
|
||||
return -EINVAL;
|
||||
|
||||
t->realtime = a;
|
||||
t->monotonic = b;
|
||||
|
||||
|
@@ -75,6 +75,7 @@ struct sd_dhcp_lease {
|
||||
uint16_t mtu; /* 0 if unset */
|
||||
|
||||
char *domainname;
|
||||
char **search_domains;
|
||||
char *hostname;
|
||||
char *root_path;
|
||||
|
||||
@@ -92,6 +93,7 @@ struct sd_dhcp_lease {
|
||||
int dhcp_lease_new(sd_dhcp_lease **ret);
|
||||
|
||||
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
|
||||
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains);
|
||||
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
|
||||
|
||||
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
|
||||
|
@@ -1655,7 +1655,8 @@ static int client_receive_message_udp(
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
return 0;
|
||||
|
||||
return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m");
|
||||
return log_dhcp_client_errno(client, errno,
|
||||
"Could not receive message from UDP socket: %m");
|
||||
}
|
||||
if ((size_t) len < sizeof(DHCPMessage)) {
|
||||
log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
|
||||
@@ -1748,9 +1749,8 @@ static int client_receive_message_raw(
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
return 0;
|
||||
|
||||
log_dhcp_client(client, "Could not receive message from raw socket: %m");
|
||||
|
||||
return -errno;
|
||||
return log_dhcp_client_errno(client, errno,
|
||||
"Could not receive message from raw socket: %m");
|
||||
} else if ((size_t)len < sizeof(DHCPPacket))
|
||||
return 0;
|
||||
|
||||
|
@@ -231,6 +231,21 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
|
||||
return (int) lease->static_route_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
|
||||
unsigned r;
|
||||
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(domains, -EINVAL);
|
||||
|
||||
r = strv_length(lease->search_domains);
|
||||
if (r > 0) {
|
||||
*domains = lease->search_domains;
|
||||
return (int) r;
|
||||
}
|
||||
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(data, -EINVAL);
|
||||
@@ -282,6 +297,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
|
||||
free(lease->static_route);
|
||||
free(lease->client_id);
|
||||
free(lease->vendor_specific);
|
||||
strv_free(lease->search_domains);
|
||||
return mfree(lease);
|
||||
}
|
||||
|
||||
@@ -594,6 +610,11 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
r = lease_parse_u16(option, len, &lease->mtu, 68);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
|
||||
if (lease->mtu < DHCP_DEFAULT_MIN_SIZE) {
|
||||
log_debug("MTU value of %" PRIu16 " too small. Using default MTU value of %d instead.", lease->mtu, DHCP_DEFAULT_MIN_SIZE);
|
||||
lease->mtu = DHCP_DEFAULT_MIN_SIZE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_DOMAIN_NAME:
|
||||
@@ -605,6 +626,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
|
||||
r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_HOST_NAME:
|
||||
r = lease_parse_domain(option, len, &lease->hostname);
|
||||
if (r < 0) {
|
||||
@@ -696,6 +723,96 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parses compressed domain names. */
|
||||
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) {
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
size_t pos = 0, cnt = 0;
|
||||
int r;
|
||||
|
||||
assert(domains);
|
||||
assert_return(option && len > 0, -ENODATA);
|
||||
|
||||
while (pos < len) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
size_t jump_barrier = pos, next_chunk = 0;
|
||||
bool first = true;
|
||||
|
||||
for (;;) {
|
||||
uint8_t c;
|
||||
c = option[pos++];
|
||||
|
||||
if (c == 0) {
|
||||
/* End of name */
|
||||
break;
|
||||
} else if (c <= 63) {
|
||||
const char *label;
|
||||
|
||||
/* Literal label */
|
||||
label = (const char*) (option + pos);
|
||||
pos += c;
|
||||
if (pos >= len)
|
||||
return -EBADMSG;
|
||||
|
||||
if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
name[n++] = '.';
|
||||
|
||||
r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n += r;
|
||||
} else if ((c & 0xc0) == 0xc0) {
|
||||
/* Pointer */
|
||||
|
||||
uint8_t d;
|
||||
uint16_t ptr;
|
||||
|
||||
if (pos >= len)
|
||||
return -EBADMSG;
|
||||
|
||||
d = option[pos++];
|
||||
ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
|
||||
|
||||
/* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
|
||||
if (ptr >= jump_barrier)
|
||||
return -EBADMSG;
|
||||
jump_barrier = ptr;
|
||||
|
||||
/* Save current location so we don't end up re-parsing what's parsed so far. */
|
||||
if (next_chunk == 0)
|
||||
next_chunk = pos;
|
||||
|
||||
pos = ptr;
|
||||
} else
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(name, allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
name[n] = 0;
|
||||
|
||||
r = strv_extend(&names, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cnt++;
|
||||
|
||||
if (next_chunk != 0)
|
||||
pos = next_chunk;
|
||||
}
|
||||
|
||||
*domains = names;
|
||||
names = NULL;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
|
||||
struct sd_dhcp_raw_option *cur, *option;
|
||||
|
||||
@@ -751,6 +868,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
const char *string;
|
||||
uint16_t mtu;
|
||||
_cleanup_free_ sd_dhcp_route **routes = NULL;
|
||||
char **search_domains = NULL;
|
||||
uint32_t t1, t2, lifetime;
|
||||
int r;
|
||||
|
||||
@@ -824,6 +942,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
if (r >= 0)
|
||||
fprintf(f, "DOMAINNAME=%s\n", string);
|
||||
|
||||
r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
|
||||
if (r > 0) {
|
||||
fputs("DOMAIN_SEARCH_LIST=", f);
|
||||
fputstrv(f, search_domains, NULL, NULL);
|
||||
fputs("\n", f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_hostname(lease, &string);
|
||||
if (r >= 0)
|
||||
fprintf(f, "HOSTNAME=%s\n", string);
|
||||
@@ -905,6 +1030,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
*ntp = NULL,
|
||||
*mtu = NULL,
|
||||
*routes = NULL,
|
||||
*domains = NULL,
|
||||
*client_id_hex = NULL,
|
||||
*vendor_specific_hex = NULL,
|
||||
*lifetime = NULL,
|
||||
@@ -933,6 +1059,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
"MTU", &mtu,
|
||||
"DOMAINNAME", &lease->domainname,
|
||||
"HOSTNAME", &lease->hostname,
|
||||
"DOMAIN_SEARCH_LIST", &domains,
|
||||
"ROOT_PATH", &lease->root_path,
|
||||
"ROUTES", &routes,
|
||||
"CLIENTID", &client_id_hex,
|
||||
@@ -1038,6 +1165,18 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
|
||||
}
|
||||
|
||||
if (domains) {
|
||||
_cleanup_strv_free_ char **a = NULL;
|
||||
a = strv_split(domains, " ");
|
||||
if (!a)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!strv_isempty(a)) {
|
||||
lease->search_domains = a;
|
||||
a = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (routes) {
|
||||
r = deserialize_dhcp_routes(
|
||||
&lease->static_route,
|
||||
|
@@ -17,7 +17,9 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_LIBIDN
|
||||
#if defined(HAVE_LIBIDN2)
|
||||
# include <idn2.h>
|
||||
#elif defined(HAVE_LIBIDN)
|
||||
# include <idna.h>
|
||||
# include <stringprep.h>
|
||||
#endif
|
||||
@@ -299,8 +301,8 @@ int dns_label_escape_new(const char *p, size_t l, char **ret) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
|
||||
#ifdef HAVE_LIBIDN
|
||||
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
|
||||
_cleanup_free_ uint32_t *input = NULL;
|
||||
size_t input_size, l;
|
||||
const char *p;
|
||||
@@ -348,13 +350,9 @@ int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded
|
||||
decoded[l] = 0;
|
||||
|
||||
return (int) l;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
|
||||
#ifdef HAVE_LIBIDN
|
||||
size_t input_size, output_size;
|
||||
_cleanup_free_ uint32_t *input = NULL;
|
||||
_cleanup_free_ char *result = NULL;
|
||||
@@ -399,10 +397,8 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
|
||||
decoded[w] = 0;
|
||||
|
||||
return w;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int dns_name_concat(const char *a, const char *b, char **_ret) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
@@ -1274,6 +1270,23 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
|
||||
}
|
||||
|
||||
int dns_name_apply_idna(const char *name, char **ret) {
|
||||
/* Return negative on error, 0 if not implemented, positive on success. */
|
||||
|
||||
#if defined(HAVE_LIBIDN2)
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret,
|
||||
IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
|
||||
if (r == IDN2_OK)
|
||||
return 1; /* *ret has been written */
|
||||
else if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
|
||||
return -ENOSPC;
|
||||
else
|
||||
return -EINVAL;
|
||||
#elif defined(HAVE_LIBIDN)
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
bool first = true;
|
||||
@@ -1323,6 +1336,9 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
||||
buf = NULL;
|
||||
|
||||
return (int) n;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dns_name_is_valid_or_address(const char *name) {
|
||||
|
@@ -51,8 +51,10 @@ static inline int dns_name_parent(const char **name) {
|
||||
return dns_label_unescape(name, NULL, DNS_LABEL_MAX);
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBIDN)
|
||||
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
|
||||
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
|
||||
#endif
|
||||
|
||||
int dns_name_concat(const char *a, const char *b, char **ret);
|
||||
|
||||
|
@@ -76,6 +76,7 @@ enum {
|
||||
SD_DHCP_OPTION_FQDN = 81,
|
||||
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
||||
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
||||
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
|
||||
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
||||
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
||||
SD_DHCP_OPTION_PRIVATE_LAST = 254,
|
||||
|
@@ -49,6 +49,7 @@ 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_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_search_domains(sd_dhcp_lease *lease, char ***domains);
|
||||
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
|
||||
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
|
||||
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
|
||||
|
Reference in New Issue
Block a user