091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2014 Tom Gundersen <teg@jklm.no>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen ***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <netinet/in.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <poll.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <sys/ioctl.h>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering#include "af-list.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "dns-domain.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek#include "fileio-label.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "hostname-util.h"
c004493cdefc1f43a3956ca529e8070f8d70be56Lennart Poettering#include "io-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "netlink-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "network-internal.h"
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering#include "ordered-set.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include "random-util.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include "resolved-bus.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "resolved-conf.h"
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering#include "resolved-etc-hosts.h"
5f402ae84bbc08fe8de5682e371b3f66c387da52Daniel Mack#include "resolved-llmnr.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "resolved-manager.h"
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack#include "resolved-mdns.h"
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering#include "resolved-resolv-conf.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "socket-util.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "string-table.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "utf8.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint16_t type;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Link *l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int ifindex, r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rtnl);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(mm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_get_type(mm, &type);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l = hashmap_get(m->links, INT_TO_PTR(ifindex));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering switch (type) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering case RTM_NEWLINK:{
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering bool is_new = !l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering if (!l) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = link_new(m, &l, ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = link_update_rtnl(l, mm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering r = link_update_monitor(l);
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering if (r < 0)
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering goto fail;
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering if (is_new)
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering log_debug("Found new link %i/%s", ifindex, l->name);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case RTM_DELLINK:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (l) {
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering log_debug("Removing link %i/%s", l->ifindex, l->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering link_free(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfail:
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to process RTNL link message: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering union in_addr_union address;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint16_t type;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int r, ifindex, family;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LinkAddress *a;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Link *l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rtnl);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(mm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_get_type(mm, &type);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l = hashmap_get(m->links, INT_TO_PTR(ifindex));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!l)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_addr_get_family(mm, &family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering switch (family) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case AF_INET:
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case AF_INET6:
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering default:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a = link_find_address(l, family, &address);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering switch (type) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case RTM_NEWADDR:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!a) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = link_address_new(l, &a, family, &address);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = link_address_update_rtnl(a, mm);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case RTM_DELADDR:
3e044c492e3ebe64f4e3175c94f9db8a62557b82Markus Elfring link_address_free(a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfail:
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to process RTNL address message: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int manager_rtnl_listen(Manager *m) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen sd_netlink_message *i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø /* First, subscribe to interfaces coming and going */
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_open(&m->rtnl);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Then, enumerate all links */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_request_dump(req, true);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_call(m->rtnl, req, 0, &reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen for (i = reply; i; i = sd_netlink_message_next(i)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_process_link(m->rtnl, i, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen req = sd_netlink_message_unref(req);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen reply = sd_netlink_message_unref(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Finally, enumerate all addresses, too */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_message_request_dump(req, true);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_netlink_call(m->rtnl, req, 0, &reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen for (i = reply; i; i = sd_netlink_message_next(i)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_process_address(m->rtnl, i, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Iterator i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Link *l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_network_monitor_flush(m->network_monitor);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering HASHMAP_FOREACH(l, m->links, i) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = link_update_monitor(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_write_resolv_conf(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
77abf3c1159a0326d05dba9cc7475d947fde0aa0Zbigniew Jędrzejewski-Szmek log_warning_errno(r, "Could not update "PRIVATE_RESOLV_CONF": %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int manager_network_monitor_listen(Manager *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r, fd, events;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering r = sd_network_monitor_new(&m->network_monitor, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fd = sd_network_monitor_get_fd(m->network_monitor);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (fd < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return fd;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering events = sd_network_monitor_get_events(m->network_monitor);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (events < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return events;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering return r;
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering (void) sd_event_source_set_description(m->network_event_source, "network-monitor");
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_free_ char *h = NULL, *n = NULL;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering char label[DNS_LABEL_MAX];
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering const char *p;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int r, k;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(mdns_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Extract and normalize the first label of the locally
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering * configured hostname, and check it's not "localhost". */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering h = gethostname_malloc();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!h)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering p = h;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = dns_label_unescape(&p, label, sizeof(label));
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return log_error_errno(r, "Failed to unescape host name: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r == 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_error("Couldn't find a single label in hosntame.");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return -EINVAL;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering k = dns_label_undo_idna(label, r, label, sizeof(label));
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (k < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return log_error_errno(k, "Failed to undo IDNA: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (k > 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = k;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!utf8_is_valid(label)) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("System hostname is not UTF-8 clean.");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return -EINVAL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
422baca0f230913158078fddf884e06c8c64a316Lennart Poettering r = dns_label_escape_new(label, r, &n);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return log_error_errno(r, "Failed to escape host name: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (is_localhost(n)) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_debug("System hostname is 'localhost', ignoring.");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return -EINVAL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = dns_name_concat(n, "local", mdns_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return log_error_errno(r, "Failed to determine mDNS hostname: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering *llmnr_hostname = n;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering n = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering _cleanup_free_ char *llmnr_hostname = NULL, *mdns_hostname = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering Manager *m = userdata;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = determine_hostname(&llmnr_hostname, &mdns_hostname);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0; /* ignore invalid hostnames */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (streq(llmnr_hostname, m->llmnr_hostname) && streq(mdns_hostname, m->mdns_hostname))
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_info("System hostname changed to '%s'.", llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(m->llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(m->mdns_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->llmnr_hostname = llmnr_hostname;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->mdns_hostname = mdns_hostname;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering llmnr_hostname = mdns_hostname = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering manager_refresh_rrs(m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int manager_watch_hostname(Manager *m) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (m->hostname_fd < 0) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_warning_errno(errno, "Failed to watch hostname: %m");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r == -EPERM)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering m->hostname_fd = safe_close(m->hostname_fd);
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt else
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt return log_error_errno(r, "Failed to add hostname event source: %m");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = determine_hostname(&m->llmnr_hostname, &m->mdns_hostname);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_info("Defaulting to hostname 'linux'.");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->llmnr_hostname = strdup("linux");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!m->llmnr_hostname)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return log_oom();
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->mdns_hostname = strdup("linux.local");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!m->mdns_hostname)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering } else
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_info("Using system hostname '%s'.", m->llmnr_hostname);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poetteringstatic int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering _cleanup_free_ char *buffer = NULL;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering Manager *m = userdata;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering size_t size = 0;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering DnsScope *scope;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering assert(s);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering assert(si);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering assert(m);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering f = open_memstream(&buffer, &size);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (!f)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return log_oom();
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering LIST_FOREACH(scopes, scope, m->dns_scopes)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering dns_scope_dump(scope, f);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (fflush_and_check(f) < 0)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return log_oom();
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering log_dump(LOG_INFO, buffer);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return 0;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering}
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenint manager_new(Manager **ret) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(manager_freep) Manager *m = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering assert(ret);
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen m = new0(Manager, 1);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!m)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -ENOMEM;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack m->mdns_ipv4_fd = m->mdns_ipv6_fd = -1;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering m->hostname_fd = -1;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering m->llmnr_support = RESOLVE_SUPPORT_YES;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering m->mdns_support = RESOLVE_SUPPORT_NO;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering m->dnssec_mode = DNSSEC_NO;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering m->read_resolv_conf = true;
00fa60ae3b2823036cb3e7734f16bce30cb7441dLennart Poettering m->need_builtin_fallbacks = true;
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering r = dns_trust_anchor_load(&m->trust_anchor);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (r < 0)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return r;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering r = manager_parse_config_file(m);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (r < 0)
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return r;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = sd_event_default(&m->event);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen sd_event_set_watchdog(m->event, true);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = manager_watch_hostname(m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_network_monitor_listen(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_rtnl_listen(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_connect_bus(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen *ret = m;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen m = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poetteringint manager_start(Manager *m) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(m);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = manager_llmnr_start(m);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack r = manager_mdns_start(m);
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack if (r < 0)
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack return r;
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 0;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering}
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringManager *manager_free(Manager *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Link *l;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!m)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering dns_server_unlink_all(m->dns_servers);
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering dns_server_unlink_all(m->fallback_dns_servers);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering dns_search_domain_unlink_all(m->search_domains);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering while ((l = hashmap_first(m->links)))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering link_free(l);
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering while (m->dns_queries)
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering dns_query_free(m->dns_queries);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering dns_scope_free(m->unicast_scope);
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering hashmap_free(m->links);
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering hashmap_free(m->dns_transactions);
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering sd_event_source_unref(m->network_event_source);
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering sd_network_monitor_unref(m->network_monitor);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
a564ca2fd113b2876e677beab60b38d50591e246Lennart Poettering sd_netlink_unref(m->rtnl);
a564ca2fd113b2876e677beab60b38d50591e246Lennart Poettering sd_event_source_unref(m->rtnl_event_source);
a564ca2fd113b2876e677beab60b38d50591e246Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering manager_llmnr_stop(m);
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack manager_mdns_stop(m);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering sd_bus_slot_unref(m->prepare_for_sleep_slot);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_event_source_unref(m->bus_retry_event_source);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_bus_unref(m->bus);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering sd_event_source_unref(m->sigusr1_event_source);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_event_unref(m->event);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering dns_resource_key_unref(m->llmnr_host_ipv4_key);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering dns_resource_key_unref(m->llmnr_host_ipv6_key);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering sd_event_source_unref(m->hostname_event_source);
d9fcf2ba1abe81ed3a7a151d6db09139b4dc7a09Lennart Poettering safe_close(m->hostname_fd);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(m->llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(m->mdns_hostname);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering dns_trust_anchor_flush(&m->trust_anchor);
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering manager_etc_hosts_flush(m);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen free(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringint manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering union {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct cmsghdr header; /* For alignment */
40a1eebde6be7ac3f1885147fc24e06ad1da260cDavid Herrmann uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } control;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering union sockaddr_union sa;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct msghdr mh = {};
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct cmsghdr *cmsg;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct iovec iov;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering int ms = 0, r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ssize_t l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(fd >= 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(ret);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = ioctl(fd, FIONREAD, &ms);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ms < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EIO;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = dns_packet_new(&p, protocol, ms);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering iov.iov_base = DNS_PACKET_DATA(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering iov.iov_len = p->allocated;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering mh.msg_name = &sa.sa;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering mh.msg_namelen = sizeof(sa);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_iov = &iov;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_iovlen = 1;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering mh.msg_control = &control;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering mh.msg_controllen = sizeof(control);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a38d99451f2bf8026ec51aee91662292e823c6a8Lennart Poettering l = recvmsg(fd, &mh, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (l < 0) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (errno == EAGAIN || errno == EINTR)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (l <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EIO;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(!(mh.msg_flags & MSG_CTRUNC));
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(!(mh.msg_flags & MSG_TRUNC));
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p->size = (size_t) l;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->family = sa.sa.sa_family;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->ipproto = IPPROTO_UDP;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (p->family == AF_INET) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->sender.in = sa.in.sin_addr;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->sender_port = be16toh(sa.in.sin_port);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering } else if (p->family == AF_INET6) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->sender.in6 = sa.in6.sin6_addr;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->sender_port = be16toh(sa.in6.sin6_port);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->ifindex = sa.in6.sin6_scope_id;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering } else
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -EAFNOSUPPORT;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2a1288ff89322a2f49c79f6d1832c8164c14a05cLennart Poettering CMSG_FOREACH(cmsg, &mh) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (cmsg->cmsg_level == IPPROTO_IPV6) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(p->family == AF_INET6);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering switch (cmsg->cmsg_type) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering case IPV6_PKTINFO: {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (p->ifindex <= 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->ifindex = i->ipi6_ifindex;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->destination.in6 = i->ipi6_addr;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering break;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering case IPV6_HOPLIMIT:
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->ttl = *(int *) CMSG_DATA(cmsg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else if (cmsg->cmsg_level == IPPROTO_IP) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(p->family == AF_INET);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering switch (cmsg->cmsg_type) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering case IP_PKTINFO: {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (p->ifindex <= 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->ifindex = i->ipi_ifindex;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->destination.in = i->ipi_addr;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering break;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering case IP_TTL:
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering p->ttl = *(int *) CMSG_DATA(cmsg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering break;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering /* The Linux kernel sets the interface index to the loopback
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering * device if the packet came from the local host since it
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering * avoids the routing table in such a case. Let's unset the
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering * interface index in such a case. */
a5f035960006556beab51c42e6948985635e261aLennart Poettering if (p->ifindex == LOOPBACK_IFINDEX)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering p->ifindex = 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen if (protocol != DNS_PROTOCOL_DNS) {
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen /* If we don't know the interface index still, we look for the
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen * first local interface with a matching address. Yuck! */
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen if (p->ifindex <= 0)
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *ret = p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(fd >= 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(mh);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (;;) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (sendmsg(fd, mh, flags) >= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno == EINTR)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno != EAGAIN)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ETIMEDOUT;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersenstatic int write_loop(int fd, void *message, size_t length) {
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen int r;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen assert(fd >= 0);
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen assert(message);
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen for (;;) {
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen if (write(fd, message, length) >= 0)
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen return 0;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen if (errno == EINTR)
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen continue;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen if (errno != EAGAIN)
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen return -errno;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen if (r < 0)
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen return r;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen if (r == 0)
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen return -ETIMEDOUT;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen }
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen}
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersenint manager_write(Manager *m, int fd, DnsPacket *p) {
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen int r;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
deb3f3d335d64601bb2d8a7520d8303f99d8a071Lennart Poettering log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen if (r < 0)
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen return r;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen return 0;
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen}
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringstatic int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering union sockaddr_union sa = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .in.sin_family = AF_INET,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering };
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering union {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct cmsghdr header; /* For alignment */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } control;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct msghdr mh = {};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct iovec iov;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(fd >= 0);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(addr);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(port > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering iov.iov_base = DNS_PACKET_DATA(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering iov.iov_len = p->size;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering sa.in.sin_addr = *addr;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering sa.in.sin_port = htobe16(port),
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_iov = &iov;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_iovlen = 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_name = &sa.sa;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_namelen = sizeof(sa.in);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ifindex > 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct cmsghdr *cmsg;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct in_pktinfo *pi;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering zero(control);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering mh.msg_control = &control;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg = CMSG_FIRSTHDR(&mh);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg->cmsg_len = mh.msg_controllen;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg->cmsg_level = IPPROTO_IP;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg->cmsg_type = IP_PKTINFO;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pi->ipi_ifindex = ifindex;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sendmsg_loop(fd, &mh, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringstatic int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering union sockaddr_union sa = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .in6.sin6_family = AF_INET6,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering };
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering union {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering struct cmsghdr header; /* For alignment */
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } control;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct msghdr mh = {};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct iovec iov;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(fd >= 0);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(addr);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(port > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering iov.iov_base = DNS_PACKET_DATA(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering iov.iov_len = p->size;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering sa.in6.sin6_addr = *addr;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering sa.in6.sin6_port = htobe16(port),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sa.in6.sin6_scope_id = ifindex;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_iov = &iov;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_iovlen = 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_name = &sa.sa;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_namelen = sizeof(sa.in6);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ifindex > 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct cmsghdr *cmsg;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct in6_pktinfo *pi;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering zero(control);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering mh.msg_control = &control;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg = CMSG_FIRSTHDR(&mh);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg->cmsg_len = mh.msg_controllen;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg->cmsg_level = IPPROTO_IPV6;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cmsg->cmsg_type = IPV6_PKTINFO;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pi->ipi6_ifindex = ifindex;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sendmsg_loop(fd, &mh, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringint manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(m);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(fd >= 0);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(addr);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(port > 0);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(p);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
deb3f3d335d64601bb2d8a7520d8303f99d8a071Lennart Poettering log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (family == AF_INET)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering else if (family == AF_INET6)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return -EAFNOSUPPORT;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poetteringuint32_t manager_find_mtu(Manager *m) {
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering uint32_t mtu = 0;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering Link *l;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering Iterator i;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering /* If we don't know on which link a DNS packet would be
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering * delivered, let's find the largest MTU that works on all
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering * interfaces we know of */
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering HASHMAP_FOREACH(l, m->links, i) {
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering if (l->mtu <= 0)
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering continue;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering if (mtu <= 0 || l->mtu < mtu)
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering mtu = l->mtu;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering }
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering return mtu;
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringint manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering LinkAddress *a;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert(m);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering a = manager_find_link_address(m, family, in_addr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return a->link->ifindex;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return 0;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering}
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringvoid manager_refresh_rrs(Manager *m) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering Iterator i;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering Link *l;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering HASHMAP_FOREACH(l, m->links, i) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering link_add_rrs(l, true);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering link_add_rrs(l, false);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringint manager_next_hostname(Manager *m) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering const char *p;
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering uint64_t u, a;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering char *h, *k;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int r;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering assert(m);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering p = strchr(m->llmnr_hostname, 0);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert(p);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering while (p > m->llmnr_hostname) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (!strchr("0123456789", p[-1]))
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering break;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering p--;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering u = 1;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering /* Add a random number to the old value. This way we can avoid
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering * that two hosts pick the same hostname, win on IPv4 and lose
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering * on IPv6 (or vice versa), and pick the same hostname
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering * replacement hostname, ad infinitum. We still want the
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering * numbers to go up monotonically, hence we just add a random
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering * value 1..10 */
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering random_bytes(&a, sizeof(a));
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering u += 1 + a % 10;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->llmnr_hostname), m->llmnr_hostname, u) < 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return -ENOMEM;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = dns_name_concat(h, "local", &k);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(h);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return r;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(m->llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->llmnr_hostname = h;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(m->mdns_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->mdns_hostname = k;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering manager_refresh_rrs(m);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart PoetteringLinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering Iterator i;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering Link *l;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert(m);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering HASHMAP_FOREACH(l, m->links, i) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering LinkAddress *a;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a = link_find_address(l, family, in_addr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return a;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return NULL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering}
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poetteringbool manager_our_packet(Manager *m, DnsPacket *p) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert(m);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert(p);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering return !!manager_find_link_address(m, p->family, &p->sender);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering}
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
a407657425a3e47fd2b559cd3bc800f791303f63Lennart PoetteringDnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering Link *l;
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering assert(m);
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering assert(p);
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering if (!l)
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering return NULL;
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack switch (p->protocol) {
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack case DNS_PROTOCOL_LLMNR:
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering if (p->family == AF_INET)
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering return l->llmnr_ipv4_scope;
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering else if (p->family == AF_INET6)
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering return l->llmnr_ipv6_scope;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack break;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack case DNS_PROTOCOL_MDNS:
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (p->family == AF_INET)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return l->mdns_ipv4_scope;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack else if (p->family == AF_INET6)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack return l->mdns_ipv6_scope;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack break;
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack default:
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack break;
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering }
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering return NULL;
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering}
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poetteringvoid manager_verify_all(Manager *m) {
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering DnsScope *s;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering assert(m);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering LIST_FOREACH(scopes, s, m->dns_scopes)
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering dns_zone_verify_all(&s->zone);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering}
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringint manager_is_own_hostname(Manager *m, const char *name) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int r;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(m);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(name);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (m->llmnr_hostname) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = dns_name_equal(name, m->llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r != 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return r;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (m->mdns_hostname)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return dns_name_equal(name, m->mdns_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return 0;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering}
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poetteringint manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering DnsServer *s;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering Iterator i;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering Link *l;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering int r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering assert(m);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering assert(dns);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering /* First add the system-wide servers and domains */
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering LIST_FOREACH(servers, s, m->dns_servers) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_put(*dns, s);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r == -EEXIST)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering continue;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering /* Then, add the per-link servers */
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering HASHMAP_FOREACH(l, m->links, i) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering LIST_FOREACH(servers, s, l->dns_servers) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_put(*dns, s);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r == -EEXIST)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering continue;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering /* If we found nothing, add the fallback servers */
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (ordered_set_isempty(*dns)) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering LIST_FOREACH(servers, s, m->fallback_dns_servers) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_put(*dns, s);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r == -EEXIST)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering continue;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return 0;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering}
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poetteringint manager_compile_search_domains(Manager *m, OrderedSet **domains) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering DnsSearchDomain *d;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering Iterator i;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering Link *l;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering int r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering assert(m);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering assert(domains);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering LIST_FOREACH(domains, d, m->search_domains) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_put(*domains, d->name);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r == -EEXIST)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering continue;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering HASHMAP_FOREACH(l, m->links, i) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering LIST_FOREACH(domains, d, l->search_domains) {
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering r = ordered_set_put(*domains, d->name);
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r == -EEXIST)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering continue;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering if (r < 0)
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return r;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering }
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering return 0;
9176a57c101d51b4a7fb4141240b5ce03abac57dLennart Poettering}
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart PoetteringDnssecMode manager_get_dnssec_mode(Manager *m) {
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering assert(m);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return m->dnssec_mode;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return DNSSEC_NO;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering}
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poetteringbool manager_dnssec_supported(Manager *m) {
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering DnsServer *server;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering Iterator i;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering Link *l;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering assert(m);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (manager_get_dnssec_mode(m) == DNSSEC_NO)
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return false;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering server = manager_get_dns_server(m);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (server && !dns_server_dnssec_supported(server))
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return false;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering HASHMAP_FOREACH(l, m->links, i)
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (!link_dnssec_supported(l))
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return false;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return true;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering}
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poetteringvoid manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering assert(verdict >= 0);
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering assert(verdict < _DNSSEC_VERDICT_MAX);
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering if (log_get_max_level() >= LOG_DEBUG) {
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering _cleanup_free_ char *s = NULL;
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering (void) dns_resource_key_to_string(key, &s);
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering log_debug("Found verdict for lookup %s: %s", s ? strstrip(s) : "n/a", dnssec_verdict_to_string(verdict));
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering }
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering m->n_dnssec_verdict[verdict]++;
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering}
011696f76233486bc56c266b18a328924f70269cLennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poetteringbool manager_routable(Manager *m, int family) {
011696f76233486bc56c266b18a328924f70269cLennart Poettering Iterator i;
011696f76233486bc56c266b18a328924f70269cLennart Poettering Link *l;
011696f76233486bc56c266b18a328924f70269cLennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering assert(m);
011696f76233486bc56c266b18a328924f70269cLennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering /* Returns true if the host has at least one interface with a routable address of the specified type */
011696f76233486bc56c266b18a328924f70269cLennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering HASHMAP_FOREACH(l, m->links, i)
011696f76233486bc56c266b18a328924f70269cLennart Poettering if (link_relevant(l, family, false))
011696f76233486bc56c266b18a328924f70269cLennart Poettering return true;
011696f76233486bc56c266b18a328924f70269cLennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering return false;
011696f76233486bc56c266b18a328924f70269cLennart Poettering}