74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2014 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
ad867662936a4c7ab2c7116d804c272338801231Lennart Poetteringstatic int reply_query_state(DnsQuery *q) {
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
7cc6ed7ba6c667caef9a92ba4d59e1ecdc3af8ffLennart Poettering return sd_bus_reply_method_errnof(q->request, q->answer_errno, "Lookup failed due to system error: %m");
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
a761c1ca851a9397b5a207ef600e077d0f7f4534Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s",
019036a47fcd10fcf0286800d144c706f3773e2fLennart Poettering dnssec_result_to_string(q->answer_dnssec_result));
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_TRUST_ANCHOR, "No suitable trust anchor known");
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED:
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_RR_TYPE_UNSUPPORTED, "Server does not support requested resource record type");
edbcc1fdd94355c5cf22263ba2c1cfa4ec2eb010Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NETWORK_DOWN, "Network is down");
0791110fbee9d7dfcabd6e338c290e90aeb79644Lennart Poettering /* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
0791110fbee9d7dfcabd6e338c290e90aeb79644Lennart Poettering * thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
0791110fbee9d7dfcabd6e338c290e90aeb79644Lennart Poettering return sd_bus_reply_method_errorf(q->request, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
3347dd5ea1dba5e27a677954b505bb6a2ee6cd75Lennart Poettering char p[DECIMAL_STR_MAX(q->answer_rcode)];
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering rc = dns_rcode_to_string(q->answer_rcode);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", dns_query_string(q), rc);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_error(q->request, &error);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'r', "iiay");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_append(reply, "i", ifindex);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_append(reply, "i", AF_INET);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering } else if (rr->key->type == DNS_TYPE_AAAA) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_append(reply, "i", AF_INET6);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_bus_message_close_container(reply);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poetteringstatic void bus_method_resolve_hostname_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering question = dns_query_question_for_protocol(q, q->answer_protocol);
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering r = dns_question_matches_rr(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Return the precise spelling and uppercasing and CNAME target reported by the server */
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to send hostname reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int check_ifindex_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
51323288fc628a5cac50914df915545d685b793eLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_new_address(&question_utf8, family, hostname, false);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_new_address(&question_idna, family, hostname, true);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_query_new(m, &q, question_utf8, question_idna, ifindex, flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->request = sd_bus_message_ref(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->complete = bus_method_resolve_hostname_complete;
011696f76233486bc56c266b18a328924f70269cLennart Poettering q->suppress_unroutable_family = family == AF_UNSPEC;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void bus_method_resolve_address_complete(DnsQuery *q) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(is)");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering question = dns_query_question_for_protocol(q, q->answer_protocol);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, rr, NULL);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering in_addr_to_string(q->request_family, &q->request_address, &ip);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", strna(ip));
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_close_container(reply);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to send address reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const void *d;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "ii", &ifindex, &family);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_read_array(message, 'y', &d, &sz);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "t", &flags);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = check_ifindex_flags(ifindex, &flags, 0, error);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_question_new_reverse(&question, family, d);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_query_new(m, &q, question, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->request = sd_bus_message_ref(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->complete = bus_method_resolve_address_complete;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int bus_message_append_rr(sd_bus_message *m, DnsResourceRecord *rr, int ifindex) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(m, 'r', "iqqay");
4e2d538f33df8a425487aaa4facc23065a9bdaf7Lennart Poettering r = dns_resource_record_to_wire_format(rr, false);
4e2d538f33df8a425487aaa4facc23065a9bdaf7Lennart Poettering r = sd_bus_message_append_array(m, 'y', rr->wire_format, rr->wire_format_size);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_message_close_container(m);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringstatic void bus_method_resolve_record_complete(DnsQuery *q) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iqqay)");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering question = dns_query_question_for_protocol(q, q->answer_protocol);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, rr, NULL);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = bus_message_append_rr(reply, rr, ifindex);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", dns_query_string(q));
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = sd_bus_message_close_container(reply);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to send record reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
eee026a7ba16336b6493828a2a13ddc9908667ffLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified resource record type %" PRIu16 " may not be used in a query.", type);
eee026a7ba16336b6493828a2a13ddc9908667ffLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = check_ifindex_flags(ifindex, &flags, 0, error);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering key = dns_resource_key_new(class, type, name);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_query_new(m, &q, question, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering q->request = sd_bus_message_ref(message);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering q->complete = bus_method_resolve_record_complete;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* First, let's see if we could find an appropriate A or AAAA
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * record for the SRV record */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->state != DNS_TRANSACTION_SUCCESS)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering question = dns_query_question_for_protocol(aux, aux->answer_protocol);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_name_equal(dns_question_first_name(question), rr->srv.name);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, zz, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'r', "qqqsa(iiay)s");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->state != DNS_TRANSACTION_SUCCESS)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering question = dns_query_question_for_protocol(aux, aux->answer_protocol);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_name_equal(dns_question_first_name(question), rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(zz, ifindex, aux->answer) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, zz, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Note that above we appended the hostname as encoded in the
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * SRV, and here the canonical hostname this maps to. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int append_txt(sd_bus_message *reply, DnsResourceRecord *rr) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append_array(reply, 'y', i->data, i->length);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void resolve_service_all_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* If an auxiliary query is still pending, let's wait */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* We can only return one error, hence pick the last error we encountered */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (bad->state == DNS_TRANSACTION_SUCCESS) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(bad));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(qqqsa(iiay)s)");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering question = dns_query_question_for_protocol(q, q->answer_protocol);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, rr, NULL);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (r == 0) /* not an SRV record */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'a', "ay");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, rr, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_service_split(DNS_RESOURCE_KEY_NAME(canonical->key), &name, &type, &domain);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error_errno(r, "Failed to send service reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void resolve_service_hostname_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering resolve_service_all_complete(q->auxiliary_for);
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering resolve_service_all_complete(q->auxiliary_for);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int resolve_service_hostname(DnsQuery *q, DnsResourceRecord *rr, int ifindex) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* OK, we found an SRV record for the service. Let's resolve
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * the hostname included in it */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_new_address(&question, q->request_family, rr->srv.name, false);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_query_new(q->manager, &aux, question, question, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering aux->complete = resolve_service_hostname_complete;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Too many auxiliary lookups? If so, don't complain,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * let's just not add this one, we already have more
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * than enough */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Note that auxiliary queries do not track the original bus
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * client, only the primary request does that. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void bus_method_resolve_service_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering question = dns_query_question_for_protocol(q, q->answer_protocol);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_matches_rr(question, rr, NULL);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = resolve_service_hostname(q, rr, ifindex);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering /* If there's exactly one SRV RR and it uses
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering * the root domain as host name, then the
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering * service is explicitly not offered on the
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering * domain. Report this as a recognizable
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering * error. See RFC 2782, Section "Usage
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide the requested service", dns_query_string(q));
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Maybe we are already finished? check now... */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error_errno(r, "Failed to send service reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_read(message, "isssit", &ifindex, &name, &type, &domain, &family, &flags);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering else if (!dns_service_name_is_valid(name))
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service name '%s'", name);
7e8131e9c6c150732503899a092206578fdc13deLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SRV service type '%s'", type);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid domain '%s'", domain);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_new_service(&question_utf8, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), false);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_question_new_service(&question_idna, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), true);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = dns_query_new(m, &q, question_utf8, question_idna, ifindex, flags|SD_RESOLVED_NO_SEARCH);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->request = sd_bus_message_ref(message);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->complete = bus_method_resolve_service_complete;
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poetteringint bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex) {
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = sd_bus_message_open_container(reply, 'r', with_ifindex ? "iiay" : "iay");
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = sd_bus_message_append(reply, "i", s->link ? s->link->ifindex : 0);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = sd_bus_message_append(reply, "i", s->family);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_append_array(reply, 'y', &s->address, FAMILY_ADDRESS_SIZE(s->family));
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return sd_bus_message_close_container(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering unsigned c = 0;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(servers, s, m->dns_servers) {
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = bus_dns_server_append(reply, s, true);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(servers, s, l->dns_servers) {
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = bus_dns_server_append(reply, s, true);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(servers, s, m->fallback_dns_servers) {
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = bus_dns_server_append(reply, s, true);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return sd_bus_message_close_container(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringstatic int bus_property_get_search_domains(
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(isb)");
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(domains, d, m->search_domains) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = sd_bus_message_append(reply, "(isb)", 0, d->name, d->route_only);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(domains, d, l->search_domains) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = sd_bus_message_append(reply, "(isb)", l->ifindex, d->name, d->route_only);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return sd_bus_message_close_container(reply);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poetteringstatic int bus_property_get_transaction_statistics(
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return sd_bus_message_append(reply, "(tt)",
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering (uint64_t) hashmap_size(m->dns_transactions),
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poetteringstatic int bus_property_get_cache_statistics(
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return sd_bus_message_append(reply, "(ttt)", size, hit, miss);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poetteringstatic int bus_property_get_dnssec_statistics(
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return sd_bus_message_append(reply, "(tttt)",
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering (uint64_t) m->n_dnssec_verdict[DNSSEC_SECURE],
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering (uint64_t) m->n_dnssec_verdict[DNSSEC_INSECURE],
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering (uint64_t) m->n_dnssec_verdict[DNSSEC_BOGUS],
59c5b5974d106c5ebad080739b41d0e92ab74d29Lennart Poettering (uint64_t) m->n_dnssec_verdict[DNSSEC_INDETERMINATE]);
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poetteringstatic int bus_property_get_dnssec_supported(
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return sd_bus_message_append(reply, "b", manager_dnssec_supported(m));
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poetteringstatic int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return sd_bus_reply_method_return(message, NULL);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poetteringstatic int get_any_link(Manager *m, int ifindex, Link **ret, sd_bus_error *error) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l = hashmap_get(m->links, INT_TO_PTR(ifindex));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poetteringstatic int get_unmanaged_link(Manager *m, int ifindex, Link **ret, sd_bus_error *error) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is loopback device.", l->name);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is managed.", l->name);
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poetteringstatic int call_link_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering r = sd_bus_message_read(message, "i", &ifindex);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering r = get_unmanaged_link(m, ifindex, &l, error);
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poetteringstatic int bus_method_set_link_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_set_dns_servers, error);
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poetteringstatic int bus_method_set_link_search_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_set_search_domains, error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int bus_method_set_link_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_set_llmnr, error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int bus_method_set_link_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_set_mdns, error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int bus_method_set_link_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_set_dnssec, error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_set_dnssec_negative_trust_anchors, error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int bus_method_revert_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608b93e3f74345c737637af24e9e75c209bLennart Poettering return call_link_method(userdata, message, bus_link_method_revert, error);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poetteringstatic int bus_method_get_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = sd_bus_message_read(message, "i", &ifindex);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering return sd_bus_reply_method_return(message, "o", p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic const sd_bus_vtable resolve_vtable[] = {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
e40f0647b48b57af5e874501ad9c05dc459108deLennart Poettering SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers, 0, 0),
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering SD_BUS_PROPERTY("SearchDomains", "a(isb)", bus_property_get_search_domains, 0, 0),
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0),
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0),
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_search_domains, 0),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering r = sd_bus_message_read(message, "b", &b);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering log_debug("Coming back from suspend, verifying all RRs...");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* We failed to connect? Yuck, we must be in early
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * boot. Let's try in 5s again. As soon as we have
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * kdbus we can stop doing this... */
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to install bus reconnect time event: %m");
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering (void) sd_event_source_set_description(m->bus_retry_event_source, "bus-retry");
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to register object: %m");
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable, link_object_find, m);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering return log_error_errno(r, "Failed to register link objects: %m");
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/link", link_node_enumerator, m);
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering return log_error_errno(r, "Failed to register link enumerator: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to register name: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_attach_event(m->bus, m->event, 0);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to attach bus to event loop: %m");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "type='signal',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "sender='org.freedesktop.login1',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "interface='org.freedesktop.login1.Manager',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "member='PrepareForSleep',"
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to add match for PrepareForSleep: %m");