1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <arpa/inet.h>
25 #include <sys/ioctl.h>
27 #include <netinet/in.h>
29 #include "rtnl-util.h"
30 #include "event-util.h"
31 #include "network-util.h"
32 #include "sd-dhcp-lease.h"
33 #include "dhcp-lease-internal.h"
34 #include "network-internal.h"
35 #include "conf-parser.h"
36 #include "socket-util.h"
39 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
41 static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
42 Manager *m = userdata;
51 r = sd_rtnl_message_get_type(mm, &type);
55 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
59 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
65 log_debug("Found link %i", ifindex);
67 r = link_new(m, &l, ifindex);
72 r = link_update_rtnl(l, mm);
80 log_debug("Removing link %i", l->ifindex);
90 log_warning("Failed to process RTNL link message: %s", strerror(-r));
94 static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
95 Manager *m = userdata;
96 union in_addr_union address;
107 r = sd_rtnl_message_get_type(mm, &type);
111 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
115 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
119 r = sd_rtnl_message_addr_get_family(mm, &family);
126 r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
128 r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
136 r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
138 r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
149 a = link_find_address(l, family, &address);
156 r = link_address_new(l, &a, family, &address);
161 r = link_address_update_rtnl(a, mm);
169 link_address_free(a);
176 log_warning("Failed to process RTNL address message: %s", strerror(-r));
181 static int manager_rtnl_listen(Manager *m) {
182 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
188 /* First, subscibe to interfaces coming and going */
189 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
193 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
197 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
201 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
205 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
209 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
213 /* Then, enumerate all links */
214 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
218 r = sd_rtnl_message_request_dump(req, true);
222 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
226 for (i = reply; i; i = sd_rtnl_message_next(i)) {
227 r = manager_process_link(m->rtnl, i, m);
232 req = sd_rtnl_message_unref(req);
233 reply = sd_rtnl_message_unref(reply);
235 /* Finally, enumerate all addresses, too */
236 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
240 r = sd_rtnl_message_request_dump(req, true);
244 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
248 for (i = reply; i; i = sd_rtnl_message_next(i)) {
249 r = manager_process_address(m->rtnl, i, m);
257 static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
258 Manager *m = userdata;
265 sd_network_monitor_flush(m->network_monitor);
267 HASHMAP_FOREACH(l, m->links, i) {
268 r = link_update_monitor(l);
270 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
273 r = manager_write_resolv_conf(m);
275 log_warning("Could not update resolv.conf: %s", strerror(-r));
280 static int manager_network_monitor_listen(Manager *m) {
285 r = sd_network_monitor_new(NULL, &m->network_monitor);
289 fd = sd_network_monitor_get_fd(m->network_monitor);
293 events = sd_network_monitor_get_events(m->network_monitor);
297 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
304 static int parse_dns_server_string(Manager *m, const char *string) {
312 FOREACH_WORD_QUOTED(word, length, string, state) {
313 char buffer[length+1];
315 union in_addr_union addr;
317 memcpy(buffer, word, length);
320 r = in_addr_from_string_auto(buffer, &family, &addr);
322 log_warning("Ignoring invalid DNS address '%s'", buffer);
326 /* filter out duplicates */
327 if (manager_find_dns_server(m, family, &addr))
330 r = dns_server_new(m, NULL, DNS_SERVER_SYSTEM, NULL, family, &addr);
338 int config_parse_dnsv(
340 const char *filename,
343 unsigned section_line,
350 Manager *m = userdata;
358 /* Empty assignment means clear the list */
359 if (isempty(rvalue)) {
360 while (m->dns_servers)
361 dns_server_free(m->dns_servers);
366 r = parse_dns_server_string(m, rvalue);
368 log_error("Failed to parse DNS server string");
375 int manager_parse_config_file(Manager *m) {
380 r = config_parse(NULL,
381 "/etc/systemd/resolved.conf", NULL,
383 config_item_perf_lookup, (void*) resolved_gperf_lookup,
386 log_warning("Failed to parse configuration file: %s", strerror(-r));
391 int manager_new(Manager **ret) {
392 _cleanup_(manager_freep) Manager *m = NULL;
397 m = new0(Manager, 1);
401 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
403 r = parse_dns_server_string(m, /* "172.31.0.125 2001:4860:4860::8888 2001:4860:4860::8889" */ DNS_SERVERS);
407 r = sd_event_default(&m->event);
411 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
412 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
414 sd_event_set_watchdog(m->event, true);
416 r = dns_scope_new(m, &m->unicast_scope, DNS_SCOPE_DNS);
420 r = manager_network_monitor_listen(m);
424 r = manager_rtnl_listen(m);
428 r = manager_connect_bus(m);
438 Manager *manager_free(Manager *m) {
444 while (m->dns_queries)
445 dns_query_free(m->dns_queries);
447 hashmap_free(m->dns_query_transactions);
449 while ((l = hashmap_first(m->links)))
451 hashmap_free(m->links);
453 dns_scope_free(m->unicast_scope);
455 while (m->dns_servers)
456 dns_server_free(m->dns_servers);
458 sd_event_source_unref(m->network_event_source);
459 sd_network_monitor_unref(m->network_monitor);
461 sd_event_source_unref(m->dns_ipv4_event_source);
462 sd_event_source_unref(m->dns_ipv6_event_source);
464 safe_close(m->dns_ipv4_fd);
465 safe_close(m->dns_ipv6_fd);
467 sd_event_source_unref(m->bus_retry_event_source);
468 sd_bus_unref(m->bus);
470 sd_event_unref(m->event);
476 static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
477 _cleanup_free_ char *t = NULL;
484 r = in_addr_to_string(s->family, &s->address, &t);
486 log_warning("Invalid DNS address. Ignoring.");
491 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
493 fprintf(f, "nameserver %s\n", t);
497 int manager_write_resolv_conf(Manager *m) {
498 const char *path = "/run/systemd/resolve/resolv.conf";
499 _cleanup_free_ char *temp_path = NULL;
500 _cleanup_fclose_ FILE *f = NULL;
509 r = fopen_temporary(path, &f, &temp_path);
513 fchmod(fileno(f), 0644);
515 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
516 "# Third party programs must not access this file directly, but\n"
517 "# only through the symlink at /etc/resolv.conf. To manage\n"
518 "# resolv.conf(5) in a different way, replace the symlink by a\n"
519 "# static file or a different symlink.\n\n", f);
521 HASHMAP_FOREACH(l, m->links, i) {
522 LIST_FOREACH(servers, s, l->link_dns_servers)
523 write_resolve_conf_server(s, f, &count);
525 LIST_FOREACH(servers, s, l->dhcp_dns_servers)
526 write_resolve_conf_server(s, f, &count);
529 LIST_FOREACH(servers, s, m->dns_servers)
530 write_resolve_conf_server(s, f, &count);
532 r = fflush_and_check(f);
536 if (rename(temp_path, path) < 0) {
549 int manager_dns_ipv4_recv(Manager *m, DnsPacket **ret) {
550 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
551 struct msghdr mh = {};
559 fd = manager_dns_ipv4_fd(m);
563 r = ioctl(fd, FIONREAD, &ms);
569 r = dns_packet_new(&p, ms);
573 iov.iov_base = DNS_PACKET_DATA(p);
574 iov.iov_len = p->allocated;
579 l = recvmsg(fd, &mh, 0);
590 p->size = (size_t) l;
598 int manager_dns_ipv6_recv(Manager *m, DnsPacket **ret) {
599 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
600 struct msghdr mh = {};
608 fd = manager_dns_ipv6_fd(m);
612 r = ioctl(fd, FIONREAD, &ms);
618 r = dns_packet_new(&p, ms);
622 iov.iov_base = DNS_PACKET_DATA(p);
623 iov.iov_len = p->allocated;
628 l = recvmsg(fd, &mh, 0);
639 p->size = (size_t) l;
647 static int on_dns_ipv4_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
648 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
649 DnsQueryTransaction *t = NULL;
650 Manager *m = userdata;
653 r = manager_dns_ipv4_recv(m, &p);
657 t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_HEADER(p)->id));
661 return dns_query_transaction_reply(t, p);
664 static int on_dns_ipv6_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
665 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
666 DnsQueryTransaction *t = NULL;
667 Manager *m = userdata;
670 r = manager_dns_ipv6_recv(m, &p);
674 t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_HEADER(p)->id));
678 return dns_query_transaction_reply(t, p);
681 int manager_dns_ipv4_fd(Manager *m) {
686 if (m->dns_ipv4_fd >= 0)
687 return m->dns_ipv4_fd;
689 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
690 if (m->dns_ipv4_fd < 0)
693 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_ipv4_packet, m);
697 return m->dns_ipv4_fd;
700 int manager_dns_ipv6_fd(Manager *m) {
705 if (m->dns_ipv6_fd >= 0)
706 return m->dns_ipv6_fd;
708 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
709 if (m->dns_ipv6_fd < 0)
712 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_ipv6_packet, m);
716 return m->dns_ipv6_fd;
719 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
726 if (sendmsg(fd, mh, flags) >= 0)
735 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
743 int manager_dns_ipv4_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p) {
744 union sockaddr_union sa = {
745 .in.sin_family = AF_INET,
746 .in.sin_port = htobe16(53),
748 struct msghdr mh = {};
750 uint8_t control[CMSG_SPACE(sizeof(struct in_pktinfo))];
757 fd = manager_dns_ipv4_fd(m);
761 iov.iov_base = DNS_PACKET_DATA(p);
762 iov.iov_len = p->size;
764 sa.in.sin_addr = srv->address.in;
768 mh.msg_name = &sa.sa;
769 mh.msg_namelen = sizeof(sa.in);
772 struct cmsghdr *cmsg;
773 struct in_pktinfo *pi;
777 mh.msg_control = control;
778 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
780 cmsg = CMSG_FIRSTHDR(&mh);
781 cmsg->cmsg_len = mh.msg_controllen;
782 cmsg->cmsg_level = IPPROTO_IP;
783 cmsg->cmsg_type = IP_PKTINFO;
785 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
786 pi->ipi_ifindex = ifindex;
789 return sendmsg_loop(fd, &mh, 0);
792 int manager_dns_ipv6_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p) {
793 union sockaddr_union sa = {
794 .in6.sin6_family = AF_INET6,
795 .in6.sin6_port = htobe16(53),
798 struct msghdr mh = {};
800 uint8_t control[CMSG_SPACE(sizeof(struct in6_pktinfo))];
807 fd = manager_dns_ipv6_fd(m);
811 iov.iov_base = DNS_PACKET_DATA(p);
812 iov.iov_len = p->size;
814 sa.in6.sin6_addr = srv->address.in6;
815 sa.in6.sin6_scope_id = ifindex;
819 mh.msg_name = &sa.sa;
820 mh.msg_namelen = sizeof(sa.in6);
823 struct cmsghdr *cmsg;
824 struct in6_pktinfo *pi;
828 mh.msg_control = control;
829 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
831 cmsg = CMSG_FIRSTHDR(&mh);
832 cmsg->cmsg_len = mh.msg_controllen;
833 cmsg->cmsg_level = IPPROTO_IPV6;
834 cmsg->cmsg_type = IPV6_PKTINFO;
836 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
837 pi->ipi6_ifindex = ifindex;
840 return sendmsg_loop(fd, &mh, 0);
843 DnsServer* manager_find_dns_server(Manager *m, unsigned char family, union in_addr_union *in_addr) {
849 LIST_FOREACH(servers, s, m->dns_servers) {
851 if (s->family == family &&
852 in_addr_equal(family, &s->address, in_addr))
859 DnsServer *manager_get_dns_server(Manager *m) {
862 if (!m->current_dns_server)
863 m->current_dns_server = m->dns_servers;
865 return m->current_dns_server;
868 void manager_next_dns_server(Manager *m) {
871 if (!m->current_dns_server) {
872 m->current_dns_server = m->dns_servers;
876 if (!m->current_dns_server)
879 if (m->current_dns_server->servers_next) {
880 m->current_dns_server = m->current_dns_server->servers_next;
884 m->current_dns_server = m->dns_servers;