diff options
author | Thomas Haller <thaller@redhat.com> | 2017-06-14 12:07:26 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-06-14 13:10:05 +0200 |
commit | be3d897758086f86d5380bc518db92dab8dd8ce0 (patch) | |
tree | bb693eeef57863e0fee97d8c3a13ee349d62442b | |
parent | 49f8fc90bd2458174397c9c712c03fd35d96d5da (diff) | |
parent | cd5ef1ed7dbbd235f9cfe75c44fabe74e5b0300e (diff) | |
download | NetworkManager-be3d897758086f86d5380bc518db92dab8dd8ce0.tar.gz |
systemd: merge branch systemd into master
- adjust nm-sd-adapt.h to new LogRealm
- add support for DHCP search domain list
-rw-r--r-- | src/systemd/sd-adapt/nm-sd-adapt.h | 11 | ||||
-rw-r--r-- | src/systemd/sd-adapt/udev.h | 1 | ||||
-rw-r--r-- | src/systemd/src/basic/fileio.c | 16 | ||||
-rw-r--r-- | src/systemd/src/basic/fileio.h | 10 | ||||
-rw-r--r-- | src/systemd/src/basic/log.h | 89 | ||||
-rw-r--r-- | src/systemd/src/basic/macro.h | 1 | ||||
-rw-r--r-- | src/systemd/src/basic/time-util.c | 18 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/dhcp-lease-internal.h | 2 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-dhcp-client.c | 8 | ||||
-rw-r--r-- | src/systemd/src/libsystemd-network/sd-dhcp-lease.c | 139 | ||||
-rw-r--r-- | src/systemd/src/shared/dns-domain.c | 42 | ||||
-rw-r--r-- | src/systemd/src/shared/dns-domain.h | 2 | ||||
-rw-r--r-- | src/systemd/src/systemd/sd-dhcp-client.h | 1 | ||||
-rw-r--r-- | src/systemd/src/systemd/sd-dhcp-lease.h | 1 |
14 files changed, 291 insertions, 50 deletions
diff --git a/src/systemd/sd-adapt/nm-sd-adapt.h b/src/systemd/sd-adapt/nm-sd-adapt.h index a8ff18bc95..3a9a744da7 100644 --- a/src/systemd/sd-adapt/nm-sd-adapt.h +++ b/src/systemd/sd-adapt/nm-sd-adapt.h @@ -37,7 +37,7 @@ static inline NMLogLevel _slog_level_to_nm (int slevel) { - switch (slevel) { + switch (LOG_PRI (slevel)) { case LOG_DEBUG: return LOGL_DEBUG; case LOG_WARNING: return LOGL_WARN; case LOG_CRIT: @@ -48,7 +48,9 @@ _slog_level_to_nm (int slevel) } } -#define log_internal(level, error, file, line, func, format, ...) \ +#define log_get_max_level_realm(realm) (LOG_DEBUG) + +#define log_internal_realm(level, error, file, line, func, format, ...) \ ({ \ const int _nm_e = (error); \ const NMLogLevel _nm_l = _slog_level_to_nm ((level)); \ @@ -61,11 +63,6 @@ _slog_level_to_nm (int slevel) (_nm_e > 0 ? -_nm_e : _nm_e); \ }) -#define log_full_errno(level, error, ...) \ -({ \ - log_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__); \ -}) - #define log_assert_failed(text, file, line, func) \ G_STMT_START { \ log_internal (LOG_CRIT, 0, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.", text, file, line, func); \ diff --git a/src/systemd/sd-adapt/udev.h b/src/systemd/sd-adapt/udev.h index 00f60f92e4..419abcbfc2 100644 --- a/src/systemd/sd-adapt/udev.h +++ b/src/systemd/sd-adapt/udev.h @@ -3,3 +3,4 @@ /* dummy header */ #include "libudev.h" +#include "strv.h" diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c index 711580a4de..6bcb7c1503 100644 --- a/src/systemd/src/basic/fileio.c +++ b/src/systemd/src/basic/fileio.c @@ -53,7 +53,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); @@ -62,6 +62,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); } @@ -91,7 +98,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; @@ -106,7 +113,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"); @@ -133,7 +141,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; diff --git a/src/systemd/src/basic/fileio.h b/src/systemd/src/basic/fileio.h index e547614cc4..6098562265 100644 --- a/src/systemd/src/basic/fileio.h +++ b/src/systemd/src/basic/fileio.h @@ -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); diff --git a/src/systemd/src/basic/log.h b/src/systemd/src/basic/log.h index af67998b51..63052862b9 100644 --- a/src/systemd/src/basic/log.h +++ b/src/systemd/src/basic/log.h @@ -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, @@ -44,14 +54,24 @@ typedef enum LogTarget{ LOG_TARGET_NULL, _LOG_TARGET_MAX, _LOG_TARGET_INVALID = -1 -} LogTarget; +} 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,11 @@ 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_; +#if 0 /* NM_IGNORED */ +int log_get_max_level_realm(LogRealm realm) _pure_; +#endif /* NM_IGNORED */ +#define log_get_max_level() \ + log_get_max_level_realm(LOG_REALM) int log_open(void); void log_close(void); @@ -73,7 +97,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) #if 0 /* NM_IGNORED */ int log_dispatch_internal( @@ -88,15 +114,19 @@ 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); +#endif /* NM_IGNORED */ +#define log_internal(level, ...) \ + log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__) -int log_internalv( +#if 0 /* NM_IGNORED */ +int log_internalv_realm( int level, int error, const char *file, @@ -104,7 +134,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, @@ -139,6 +172,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); @@ -162,38 +196,51 @@ 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) +#endif /* NM_IGNORED */ /* 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); \ }) -#endif /* NM_IGNORED */ -#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__) @@ -218,13 +265,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_; diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h index 7db87b493a..afcde4597a 100644 --- a/src/systemd/src/basic/macro.h +++ b/src/systemd/src/basic/macro.h @@ -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> diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c index e8158d5584..d803df8b98 100644 --- a/src/systemd/src/basic/time-util.c +++ b/src/systemd/src/basic/time-util.c @@ -560,15 +560,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; diff --git a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h index 82cae2300a..7847ce0709 100644 --- a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h @@ -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); diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index 17393e2062..955c9ddabf 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -1659,7 +1659,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"); @@ -1752,9 +1753,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; diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c index 5a3bff2f76..f0ddf2dae1 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c @@ -233,6 +233,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); @@ -284,6 +299,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); } @@ -596,6 +612,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: @@ -607,6 +628,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) { @@ -698,6 +725,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; @@ -753,6 +870,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; @@ -826,6 +944,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); @@ -907,6 +1032,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, @@ -935,6 +1061,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, @@ -1040,6 +1167,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, diff --git a/src/systemd/src/shared/dns-domain.c b/src/systemd/src/shared/dns-domain.c index 5ed2719136..8b341461f0 100644 --- a/src/systemd/src/shared/dns-domain.c +++ b/src/systemd/src/shared/dns-domain.c @@ -19,9 +19,11 @@ #include "nm-sd-adapt.h" -#ifdef HAVE_LIBIDN -#include <idna.h> -#include <stringprep.h> +#if defined(HAVE_LIBIDN2) +# include <idn2.h> +#elif defined(HAVE_LIBIDN) +# include <idna.h> +# include <stringprep.h> #endif #include <endian.h> @@ -144,6 +146,7 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) { return r; } +#if 0 /* NM_IGNORED */ /* @label_terminal: terminal character of a label, updated to point to the terminal character of * the previous label (always skipping one dot) or to NULL if there are no more * labels. */ @@ -209,6 +212,7 @@ int dns_label_unescape_suffix(const char *name, const char **label_terminal, cha return r; } +#endif /* NM_IGNORED */ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) { char *q; @@ -277,6 +281,7 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) { return (int) (q - dest); } +#if 0 /* NM_IGNORED */ int dns_label_escape_new(const char *p, size_t l, char **ret) { _cleanup_free_ char *s = NULL; int r; @@ -301,8 +306,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; @@ -350,13 +355,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; @@ -401,10 +402,9 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, decoded[w] = 0; return w; -#else - return 0; -#endif } +#endif +#endif /* NM_IGNORED */ int dns_name_concat(const char *a, const char *b, char **_ret) { _cleanup_free_ char *ret = NULL; @@ -1279,6 +1279,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; @@ -1328,6 +1345,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) { diff --git a/src/systemd/src/shared/dns-domain.h b/src/systemd/src/shared/dns-domain.h index 03f160369c..fca025def0 100644 --- a/src/systemd/src/shared/dns-domain.h +++ b/src/systemd/src/shared/dns-domain.h @@ -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); diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h index ffe7f836de..f731fdcbd4 100644 --- a/src/systemd/src/systemd/sd-dhcp-client.h +++ b/src/systemd/src/systemd/sd-dhcp-client.h @@ -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, diff --git a/src/systemd/src/systemd/sd-dhcp-lease.h b/src/systemd/src/systemd/sd-dhcp-lease.h index 2f565ca825..7ab99cccd1 100644 --- a/src/systemd/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/src/systemd/sd-dhcp-lease.h @@ -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); |