Skip to content

Commit 2ac2f2a

Browse files
authored
Merge pull request systemd#111 from ssahani/dns
Add support for DNS
2 parents fc47937 + 9a55367 commit 2ac2f2a

18 files changed

+2139
-8
lines changed

src/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ libshared_sources = files('''
99
share/conf-parser.h
1010
share/conf-files.c
1111
share/conf-files.h
12+
share/dns-def.h
13+
share/dns-domain.c
14+
share/dns-domain.h
15+
share/hostname-util.c
16+
share/hostname-util.h
1217
share/alloc-util.c
1318
share/alloc-util.h
1419
share/build.h
@@ -95,6 +100,8 @@ libshared_sources = files('''
95100
share/virt.h
96101
share/sd-network.h
97102
share/sd-network.c
103+
share/sd-resolve.h
104+
share/sd-resolve.c
98105
'''.split())
99106

100107
libshared = static_library(

src/netlog/netlog-conf.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
/* SPDX-License-Identifier: LGPL-2.1-or-later */
22

3+
#include <resolv.h>
4+
5+
#include "conf-parser.h"
36
#include "def.h"
47
#include "in-addr-util.h"
58
#include "netlog-conf.h"
6-
#include "conf-parser.h"
9+
#include "parse-util.h"
10+
#include "sd-resolve.h"
711
#include "string-util.h"
812

913
int config_parse_netlog_remote_address(const char *unit,
@@ -17,6 +21,7 @@ int config_parse_netlog_remote_address(const char *unit,
1721
void *data,
1822
void *userdata) {
1923
Manager *m = userdata;
24+
char *e;
2025
int r;
2126

2227
assert(filename);
@@ -27,6 +32,43 @@ int config_parse_netlog_remote_address(const char *unit,
2732

2833
r = socket_address_parse(&m->address, rvalue);
2934
if (r < 0) {
35+
struct addrinfo hints = {
36+
.ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
37+
.ai_socktype = SOCK_DGRAM,
38+
.ai_family = socket_ipv6_is_supported() ? AF_UNSPEC : AF_INET,
39+
};
40+
uint32_t u;
41+
42+
e = strchr(rvalue, ':');
43+
if (e) {
44+
r = safe_atou(e+1, &u);
45+
if (r < 0)
46+
return r;
47+
48+
if (u <= 0 || u > 0xFFFF)
49+
return -EINVAL;
50+
51+
m->port = u;
52+
m->server_name = strndupa(rvalue, e-rvalue);
53+
if (!m->server_name)
54+
return log_oom();
55+
56+
log_debug("Remote server='%s' port: '%u'...", m->server_name, u);
57+
58+
/* Tell the resolver to reread /etc/resolv.conf, in
59+
* case it changed. */
60+
res_init();
61+
62+
log_debug("Resolving %s...", m->server_name);
63+
64+
r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->server_name, NULL, &hints, manager_resolve_handler, m);
65+
if (r < 0)
66+
return log_error_errno(r, "Failed to create resolver: %m");
67+
68+
m->resolving = true;
69+
return 0;
70+
}
71+
3072
log_syntax(unit, LOG_WARNING, filename, line, -r, "Failed to parse '%s=%s', ignoring.", lvalue, rvalue);
3173
return 0;
3274
}

src/netlog/netlog-manager.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ int manager_connect(Manager *m) {
426426

427427
assert(m);
428428

429+
if (m->resolving)
430+
return 0;
431+
429432
manager_disconnect(m);
430433

431434
log_debug("Connecting network ...");
@@ -469,6 +472,8 @@ void manager_disconnect(Manager *m) {
469472

470473
log_debug("Disconnecting network ...");
471474

475+
m->resolve_query = sd_resolve_query_unref(m->resolve_query);
476+
472477
close_journal_input(m);
473478

474479
manager_close_network_socket(m);
@@ -481,6 +486,62 @@ void manager_disconnect(Manager *m) {
481486
sd_notifyf(false, "STATUS=Idle.");
482487
}
483488

489+
int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
490+
Manager *m = userdata;
491+
492+
assert(q);
493+
assert(m);
494+
assert(m->server_name);
495+
496+
log_debug("Resolve %s: %s", m->server_name, gai_strerror(ret));
497+
498+
m->resolve_query = sd_resolve_query_unref(m->resolve_query);
499+
500+
if (ret != 0) {
501+
log_debug("Failed to resolve %s: %s", m->server_name, gai_strerror(ret));
502+
503+
/* Try next host */
504+
return manager_connect(m);
505+
}
506+
507+
for (; ai; ai = ai->ai_next) {
508+
_cleanup_free_ char *pretty = NULL;
509+
510+
assert(ai->ai_addr);
511+
assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
512+
513+
if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
514+
log_warning("Unsuitable address protocol for %s", m->server_name);
515+
continue;
516+
}
517+
518+
m->socklen = ai->ai_addrlen;
519+
memcpy(&m->address.sockaddr, (const union sockaddr_union*) ai->ai_addr, ai->ai_addrlen);
520+
521+
if (ai->ai_addr->sa_family == AF_INET6)
522+
m->address.sockaddr.in6.sin6_port = htobe16((uint16_t) m->port);
523+
else
524+
m->address.sockaddr.in.sin_port = htobe16((uint16_t) m->port);
525+
526+
sockaddr_pretty(&m->address.sockaddr.sa, m->socklen, true, true, &pretty);
527+
528+
log_debug("Resolved address %s for %s.", pretty, m->server_name);
529+
530+
/* take the first one */
531+
break;
532+
}
533+
534+
if (!IN_SET(m->address.sockaddr.sa.sa_family, AF_INET, AF_INET6)) {
535+
log_error("Failed to find suitable address for host %s.", m->server_name);
536+
537+
/* Try next host */
538+
return manager_connect(m);
539+
}
540+
541+
m->resolving = false;
542+
return manager_connect(m);
543+
}
544+
484545
static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
485546
Manager *m = userdata;
486547
bool connected, online;
@@ -551,6 +612,8 @@ void manager_free(Manager *m) {
551612
free(m->dir);
552613
free(m->namespace);
553614

615+
sd_resolve_unref(m->resolve);
616+
554617
sd_event_source_unref(m->network_event_source);
555618
sd_network_monitor_unref(m->network_monitor);
556619

@@ -586,7 +649,7 @@ int manager_new(const char *state_file, const char *cursor, Manager **ret) {
586649
},
587650
};
588651

589-
socket_address_parse(&m->address, "239.0.0.1:6000");
652+
(void) socket_address_parse(&m->address, "239.0.0.1:6000");
590653

591654
if (!m->state_file)
592655
return log_oom();
@@ -607,6 +670,14 @@ int manager_new(const char *state_file, const char *cursor, Manager **ret) {
607670

608671
sd_event_set_watchdog(m->event, true);
609672

673+
r = sd_resolve_default(&m->resolve);
674+
if (r < 0)
675+
return r;
676+
677+
r = sd_resolve_attach_event(m->resolve, m->event, 0);
678+
if (r < 0)
679+
return r;
680+
610681
r = manager_network_monitor_listen(m);
611682
if (r < 0)
612683
return r;

src/netlog/netlog-manager.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "netlog-dtls.h"
88
#include "netlog-tls.h"
99
#include "sd-network.h"
10+
#include "sd-resolve.h"
1011
#include "socket-util.h"
1112
#include "ratelimit.h"
1213

@@ -31,7 +32,9 @@ typedef enum SysLogTransmissionLogFormat {
3132
typedef struct Manager Manager;
3233

3334
struct Manager {
35+
sd_resolve *resolve;
3436
sd_event *event;
37+
3538
sd_event_source *event_journal_input;
3639
uint64_t timeout;
3740
usec_t retry_interval;
@@ -48,10 +51,19 @@ struct Manager {
4851

4952
RateLimit ratelimit;
5053

54+
/* peer */
55+
sd_resolve_query *resolve_query;
56+
sd_event_source *event_receive;
57+
sd_event_source *event_timeout;
58+
5159
int socket;
5260

5361
/* Multicast UDP address */
5462
SocketAddress address;
63+
socklen_t socklen;
64+
uint32_t port;
65+
66+
char *server_name;
5567

5668
/* journal */
5769
int journal_watch_fd;
@@ -79,6 +91,7 @@ struct Manager {
7991
bool keep_alive;
8092
bool no_delay;
8193
bool connected;
94+
bool resolving;
8295

8396
unsigned keep_alive_cnt;
8497

@@ -101,6 +114,8 @@ void manager_close_network_socket(Manager *m);
101114
int manager_open_network_socket(Manager *m);
102115
int manager_network_connect_socket(Manager *m);
103116

117+
int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata);
118+
104119
int manager_push_to_network(Manager *m,
105120
int severity,
106121
int facility,

src/netlog/netlog-protocol.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ void format_rfc3339_timestamp(const struct timeval *tv, char *header_time, size_
5151
char gm_buf[sizeof("+0530") + 1];
5252
struct tm tm;
5353
time_t t;
54-
size_t written;
54+
size_t w;
5555
int r;
5656

5757
assert(header_time);
5858

5959
t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC));
6060
localtime_r(&t, &tm);
6161

62-
written = strftime(header_time, header_size, "%Y-%m-%dT%T", &tm);
63-
assert(written != 0);
64-
header_time += written;
65-
header_size -= written;
62+
w = strftime(header_time, header_size, "%Y-%m-%dT%T", &tm);
63+
assert(w != 0);
64+
header_time += w;
65+
header_size -= w;
6666

6767
/* add fractional part */
6868
if (tv) {

src/share/dns-def.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2+
#pragma once
3+
4+
/* Length of a single label, with all escaping removed, excluding any trailing dot or NUL byte */
5+
#define DNS_LABEL_MAX 63
6+
7+
/* Worst case length of a single label, with all escaping applied and room for a trailing NUL byte. */
8+
#define DNS_LABEL_ESCAPED_MAX (DNS_LABEL_MAX*4+1)
9+
10+
/* Maximum length of a full hostname, consisting of a series of unescaped labels, and no trailing dot or NUL byte */
11+
#define DNS_HOSTNAME_MAX 253
12+
13+
/* Maximum length of a full hostname, on the wire, including the final NUL byte */
14+
#define DNS_WIRE_FORMAT_HOSTNAME_MAX 255
15+
16+
/* Maximum number of labels per valid hostname */
17+
#define DNS_N_LABELS_MAX 127

0 commit comments

Comments
 (0)