diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-08-06 16:15:35 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-08-11 15:06:22 +0200 |
commit | a407657425a3e47fd2b559cd3bc800f791303f63 (patch) | |
tree | 9d7dd0f9a286eb364769d9d39c6cdfce36e0a18a /src/resolve/resolved-manager.c | |
parent | resolved: properly check return value of dns_resource_record_equal() (diff) | |
download | systemd-a407657425a3e47fd2b559cd3bc800f791303f63.tar.xz systemd-a407657425a3e47fd2b559cd3bc800f791303f63.zip |
resolved: implement full LLMNR conflict detection logic
Diffstat (limited to 'src/resolve/resolved-manager.c')
-rw-r--r-- | src/resolve/resolved-manager.c | 89 |
1 files changed, 51 insertions, 38 deletions
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 12883952b1..a93f4a597f 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -1219,38 +1219,34 @@ static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *u _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; DnsTransaction *t = NULL; Manager *m = userdata; + DnsScope *scope; int r; r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p); if (r <= 0) return r; + scope = manager_find_scope(m, p); + if (!scope) { + log_warning("Got LLMNR UDP packet on unknown scope. Ignoring."); + return 0; + } + if (dns_packet_validate_reply(p) > 0) { log_debug("Got reply packet for id %u", DNS_PACKET_ID(p)); - t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p))); - if (!t) - return 0; - - dns_transaction_process_reply(t, p); + dns_scope_check_conflicts(scope, p); - } else if (dns_packet_validate_query(p) > 0) { - Link *l; - - l = hashmap_get(m->links, INT_TO_PTR(p->ifindex)); - if (l) { - DnsScope *scope = NULL; + t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p))); + if (t) + dns_transaction_process_reply(t, p); - if (p->family == AF_INET) - scope = l->llmnr_ipv4_scope; - else if (p->family == AF_INET6) - scope = l->llmnr_ipv6_scope; + } else if (dns_packet_validate_query(p) > 0) { + log_debug("Got query packet for id %u", DNS_PACKET_ID(p)); - if (scope) - dns_scope_process_query(scope, NULL, p); - } + dns_scope_process_query(scope, NULL, p); } else - log_debug("Invalid LLMNR packet."); + log_debug("Invalid LLMNR UDP packet."); return 0; } @@ -1413,29 +1409,26 @@ fail: } static int on_llmnr_stream_packet(DnsStream *s) { - assert(s); + DnsScope *scope; - if (dns_packet_validate_query(s->read_packet) > 0) { - Link *l; + assert(s); - l = hashmap_get(s->manager->links, INT_TO_PTR(s->read_packet->ifindex)); - if (l) { - DnsScope *scope = NULL; + scope = manager_find_scope(s->manager, s->read_packet); + if (!scope) { + log_warning("Got LLMNR TCP packet on unknown scope. Ignroing."); + return 0; + } - if (s->read_packet->family == AF_INET) - scope = l->llmnr_ipv4_scope; - else if (s->read_packet->family == AF_INET6) - scope = l->llmnr_ipv6_scope; + if (dns_packet_validate_query(s->read_packet) > 0) { + log_debug("Got query packet for id %u", DNS_PACKET_ID(s->read_packet)); - if (scope) { - dns_scope_process_query(scope, s, s->read_packet); + dns_scope_process_query(scope, s, s->read_packet); - /* If no reply packet was set, we free the stream */ - if (s->write_packet) - return 0; - } - } - } + /* If no reply packet was set, we free the stream */ + if (s->write_packet) + return 0; + } else + log_debug("Invalid LLMNR TCP packet."); dns_stream_free(s); return 0; @@ -1702,13 +1695,33 @@ LinkAddress* manager_find_link_address(Manager *m, int family, const union in_ad return NULL; } -int manager_our_packet(Manager *m, DnsPacket *p) { +bool manager_our_packet(Manager *m, DnsPacket *p) { assert(m); assert(p); return !!manager_find_link_address(m, p->family, &p->sender); } +DnsScope* manager_find_scope(Manager *m, DnsPacket *p) { + Link *l; + + assert(m); + assert(p); + + l = hashmap_get(m->links, INT_TO_PTR(p->ifindex)); + if (!l) + return NULL; + + if (p->protocol == DNS_PROTOCOL_LLMNR) { + if (p->family == AF_INET) + return l->llmnr_ipv4_scope; + else if (p->family == AF_INET6) + return l->llmnr_ipv6_scope; + } + + return NULL; +} + static const char* const support_table[_SUPPORT_MAX] = { [SUPPORT_NO] = "no", [SUPPORT_YES] = "yes", |