resolved: add code to join/leave mDNS multicast groups

Per link, join the mDNS multicast groups when the scope is created, and
leave it again when the scope goes away.
This commit is contained in:
Daniel Mack 2015-07-11 14:33:58 -04:00
parent 4e5bf5e158
commit 0db4c90afd
3 changed files with 25 additions and 7 deletions

View file

@ -225,6 +225,9 @@ DnsProtocol dns_protocol_from_string(const char *s) _pure_;
#define LLMNR_MULTICAST_IPV4_ADDRESS ((struct in_addr) { .s_addr = htobe32(224U << 24 | 252U) })
#define LLMNR_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03 } })
#define MDNS_MULTICAST_IPV4_ADDRESS ((struct in_addr) { .s_addr = htobe32(224U << 24 | 251U) })
#define MDNS_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfb } })
static inline uint64_t SD_RESOLVED_FLAGS_MAKE(DnsProtocol protocol, int family, bool authenticated) {
uint64_t f;

View file

@ -59,6 +59,7 @@ int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int
LIST_PREPEND(scopes, m->dns_scopes, s);
dns_scope_llmnr_membership(s, true);
dns_scope_mdns_membership(s, true);
log_debug("New scope on link %s, protocol %s, family %s", l ? l->name : "*", dns_protocol_to_string(protocol), family == AF_UNSPEC ? "*" : af_to_name(family));
@ -95,6 +96,7 @@ DnsScope* dns_scope_free(DnsScope *s) {
log_debug("Removing scope on link %s, protocol %s, family %s", s->link ? s->link->name : "*", dns_protocol_to_string(s->protocol), s->family == AF_UNSPEC ? "*" : af_to_name(s->family));
dns_scope_llmnr_membership(s, false);
dns_scope_mdns_membership(s, false);
dns_scope_abort_transactions(s);
while (s->query_candidates)
@ -477,19 +479,15 @@ int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
return true;
}
int dns_scope_llmnr_membership(DnsScope *s, bool b) {
static int dns_scope_multicast_membership(DnsScope *s, bool b, struct in_addr in, struct in6_addr in6) {
int fd;
assert(s);
if (s->protocol != DNS_PROTOCOL_LLMNR)
return 0;
assert(s->link);
if (s->family == AF_INET) {
struct ip_mreqn mreqn = {
.imr_multiaddr = LLMNR_MULTICAST_IPV4_ADDRESS,
.imr_multiaddr = in,
.imr_ifindex = s->link->ifindex,
};
@ -508,7 +506,7 @@ int dns_scope_llmnr_membership(DnsScope *s, bool b) {
} else if (s->family == AF_INET6) {
struct ipv6_mreq mreq = {
.ipv6mr_multiaddr = LLMNR_MULTICAST_IPV6_ADDRESS,
.ipv6mr_multiaddr = in6,
.ipv6mr_interface = s->link->ifindex,
};
@ -527,6 +525,22 @@ int dns_scope_llmnr_membership(DnsScope *s, bool b) {
return 0;
}
int dns_scope_llmnr_membership(DnsScope *s, bool b) {
if (s->protocol != DNS_PROTOCOL_LLMNR)
return 0;
return dns_scope_multicast_membership(s, b, LLMNR_MULTICAST_IPV4_ADDRESS, LLMNR_MULTICAST_IPV6_ADDRESS);
}
int dns_scope_mdns_membership(DnsScope *s, bool b) {
if (s->protocol != DNS_PROTOCOL_MDNS)
return 0;
return dns_scope_multicast_membership(s, b, MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS);
}
static int dns_scope_make_reply_packet(
DnsScope *s,
uint16_t id,

View file

@ -93,6 +93,7 @@ DnsServer *dns_scope_get_dns_server(DnsScope *s);
void dns_scope_next_dns_server(DnsScope *s);
int dns_scope_llmnr_membership(DnsScope *s, bool b);
int dns_scope_mdns_membership(DnsScope *s, bool b);
void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p);