[systemd-commits] 4 commits - src/resolve
Lennart Poettering
lennart at kemper.freedesktop.org
Thu Jul 31 10:56:36 PDT 2014
src/resolve/resolved-bus.c | 7 +-
src/resolve/resolved-dns-domain.c | 18 ++---
src/resolve/resolved-dns-packet.c | 2
src/resolve/resolved-manager.c | 128 +++++++++++++++++++++++++++++++++-----
src/resolve/resolved.h | 5 +
5 files changed, 136 insertions(+), 24 deletions(-)
New commits:
commit eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jul 31 19:54:43 2014 +0200
hostnamed: watch system hostname changes and update LLMNR RRs accordingly
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 72034c1..6987c29 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -34,6 +34,8 @@
#include "socket-util.h"
#include "af-list.h"
#include "resolved.h"
+#include "utf8.h"
+#include "resolved-dns-domain.h"
#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
@@ -384,6 +386,92 @@ int manager_parse_config_file(Manager *m) {
false, false, true, m);
}
+static int determine_hostname(char **ret) {
+ _cleanup_free_ char *h = NULL, *n = NULL;
+ int r;
+
+ assert(ret);
+
+ h = gethostname_malloc();
+ if (!h)
+ return log_oom();
+
+ if (!utf8_is_valid(h)) {
+ log_error("System hostname is not UTF-8 clean.");
+ return -EINVAL;
+ }
+
+ r = dns_name_normalize(h, &n);
+ if (r < 0) {
+ log_error("System hostname '%s' cannot be normalized.", h);
+ return r;
+ }
+
+ *ret = n;
+ n = NULL;
+
+ return 0;
+}
+
+static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
+ _cleanup_free_ char *h = NULL;
+ Manager *m = userdata;
+ int r;
+
+ assert(m);
+
+ r = determine_hostname(&h);
+ if (r < 0)
+ return 0; /* ignore invalid hostnames */
+
+ if (streq(h, m->hostname))
+ return 0;
+
+ log_info("System hostname changed to '%s'.", h);
+ free(m->hostname);
+ m->hostname = h;
+ h = NULL;
+
+ manager_refresh_rrs(m);
+
+ return 0;
+}
+
+static int manager_watch_hostname(Manager *m) {
+ _cleanup_free_ char *h = NULL;
+ int r;
+
+ assert(m);
+
+ m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
+ if (m->hostname_fd < 0) {
+ log_warning("Failed to watch hostname: %m");
+ return 0;
+ }
+
+ r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
+ if (r < 0) {
+ if (r == -EPERM)
+ /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
+ m->hostname_fd = safe_close(m->hostname_fd);
+ else {
+ log_error("Failed to add hostname event source: %s", strerror(-r));
+ return r;
+ }
+ }
+
+ r = determine_hostname(&m->hostname);
+ if (r < 0) {
+ log_info("Defaulting to hostname 'linux'.");
+ m->hostname = strdup("linux");
+ if (!m->hostname)
+ return log_oom();
+ } else
+ log_info("Using system hostname '%s'.", m->hostname);
+
+ return 0;
+}
+
int manager_new(Manager **ret) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
@@ -397,6 +485,7 @@ int manager_new(Manager **ret) {
m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
+ m->hostname_fd = -1;
m->use_llmnr = true;
@@ -404,10 +493,6 @@ int manager_new(Manager **ret) {
if (r < 0)
return r;
- m->hostname = gethostname_malloc();
- if (!m->hostname)
- return -ENOMEM;
-
r = sd_event_default(&m->event);
if (r < 0)
return r;
@@ -417,6 +502,10 @@ int manager_new(Manager **ret) {
sd_event_set_watchdog(m->event, true);
+ r = manager_watch_hostname(m);
+ if (r < 0)
+ return r;
+
r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
if (r < 0)
return r;
@@ -497,7 +586,11 @@ Manager *manager_free(Manager *m) {
dns_resource_key_unref(m->host_ipv4_key);
dns_resource_key_unref(m->host_ipv6_key);
+
+ safe_close(m->hostname_fd);
+ sd_event_source_unref(m->hostname_event_source);
free(m->hostname);
+
free(m);
return NULL;
@@ -1408,12 +1501,25 @@ int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_a
return 0;
}
+void manager_refresh_rrs(Manager *m) {
+ Iterator i;
+ Link *l;
+
+ assert(m);
+
+ m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
+ m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
+
+ HASHMAP_FOREACH(l, m->links, i) {
+ link_add_rrs(l, true);
+ link_add_rrs(l, false);
+ }
+}
+
int manager_next_hostname(Manager *m) {
const char *p;
- Iterator i;
uint64_t u;
char *h;
- Link *l;
assert(m);
@@ -1435,18 +1541,12 @@ int manager_next_hostname(Manager *m) {
if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
return -ENOMEM;
- log_info("Hostname conflict, changing local hostname from '%s' to '%s'.", m->hostname, h);
+ log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
free(m->hostname);
m->hostname = h;
- m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
- m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
-
- HASHMAP_FOREACH(l, m->links, i) {
- link_add_rrs(l, true);
- link_add_rrs(l, false);
- }
+ manager_refresh_rrs(m);
return 0;
}
diff --git a/src/resolve/resolved.h b/src/resolve/resolved.h
index 0756055..34eb7b5 100644
--- a/src/resolve/resolved.h
+++ b/src/resolve/resolved.h
@@ -90,6 +90,10 @@ struct Manager {
char *hostname;
DnsResourceKey *host_ipv4_key;
DnsResourceKey *host_ipv6_key;
+
+ /* Watch the system hostname */
+ int hostname_fd;
+ sd_event_source *hostname_event_source;
};
/* Manager */
@@ -120,6 +124,7 @@ int manager_ifindex_is_loopback(Manager *m, int ifindex);
int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr);
LinkAddress* manager_find_address(Manager *m, int family, const union in_addr_union *in_addr);
+void manager_refresh_rrs(Manager *m);
int manager_next_hostname(Manager *m);
int manager_our_packet(Manager *m, DnsPacket *p);
commit 85818582574bcd1c3707c2a4609c9e283e47493f
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jul 31 19:54:24 2014 +0200
resolved: fix deserialization of UTF8 host names
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 3eda803..7793a01 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -840,7 +840,7 @@ int dns_packet_read_name(DnsPacket *p, char **_ret, size_t *start) {
else
first = false;
- memcpy(ret + n, t, c);
+ memcpy(ret + n, t, r);
n += r;
continue;
} else if ((c & 0xc0) == 0xc0) {
commit 7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cd
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jul 31 19:53:59 2014 +0200
resolved: accept UTF-8 hostnames from bus clients
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index bfb060d..6bd2b53 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -275,7 +275,8 @@ static int bus_method_resolve_hostname(sd_bus *bus, sd_bus_message *message, voi
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
- if (!hostname_is_valid(hostname))
+ r = dns_name_normalize(hostname, NULL);
+ if (r < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
question = dns_question_new(family == AF_UNSPEC ? 2 : 1);
@@ -566,6 +567,10 @@ static int bus_method_resolve_record(sd_bus *bus, sd_bus_message *message, void
if (r < 0)
return r;
+ r = dns_name_normalize(name, NULL);
+ if (r < 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
+
question = dns_question_new(1);
if (!question)
return -ENOMEM;
diff --git a/src/resolve/resolved-dns-domain.c b/src/resolve/resolved-dns-domain.c
index c2a4359..1bb011d 100644
--- a/src/resolve/resolved-dns-domain.c
+++ b/src/resolve/resolved-dns-domain.c
@@ -172,7 +172,6 @@ int dns_name_normalize(const char *s, char **_ret) {
int r;
assert(s);
- assert(_ret);
for (;;) {
_cleanup_free_ char *t = NULL;
@@ -210,8 +209,11 @@ int dns_name_normalize(const char *s, char **_ret) {
return -ENOMEM;
ret[n] = 0;
- *_ret = ret;
- ret = NULL;
+
+ if (_ret) {
+ *_ret = ret;
+ ret = NULL;
+ }
return 0;
}
commit 07bed172edc819cf85b72d5c67613511cbde5453
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Jul 31 19:51:11 2014 +0200
resolved: various fixes regarding encoding of UTF8 characters in DNS RRs
diff --git a/src/resolve/resolved-dns-domain.c b/src/resolve/resolved-dns-domain.c
index f3e7df7..c2a4359 100644
--- a/src/resolve/resolved-dns-domain.c
+++ b/src/resolve/resolved-dns-domain.c
@@ -88,7 +88,7 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
} else
return -EINVAL;
- } else if (*n >= ' ' && *n != 127) {
+ } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) {
/* Normal character */
*(d++) = *(n++);
@@ -141,13 +141,13 @@ int dns_label_escape(const char *p, size_t l, char **ret) {
/* Proper character */
*(q++) = *p;
- } else if (*p >= ' ' && *p != 127) {
+ } else if ((uint8_t) *p >= (uint8_t) ' ' && *p != 127) {
/* Everything else */
*(q++) = '\\';
- *(q++) = '0' + (char) ((unsigned) *p / 100);
- *(q++) = '0' + (char) (((unsigned) *p / 10) % 10);
- *(q++) = '0' + (char) ((unsigned) *p % 10);
+ *(q++) = '0' + (char) ((uint8_t) *p / 100);
+ *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10);
+ *(q++) = '0' + (char) ((uint8_t) *p % 10);
} else
return -EINVAL;
More information about the systemd-commits
mailing list