From e01c85ef2f9f7acebbd18ef6e2eda0031af50fe1 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Mon, 12 Dec 2016 12:25:10 -0800 Subject: [PATCH 1/5] Implementing the ARC4_LOCK/UNLOCK functions for Windows. --- src/compat/arc4_lock.c | 58 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/compat/arc4_lock.c b/src/compat/arc4_lock.c index facf9575..34b85974 100644 --- a/src/compat/arc4_lock.c +++ b/src/compat/arc4_lock.c @@ -48,9 +48,65 @@ void _ARC4_UNLOCK(void) { pthread_mutex_unlock(&arc_lock); } +#elif defined(GETDNS_ON_WINDOWS) + /* + * There is no explicit arc4random_init call, and thus + * the critical section must be allocated on the first call to + * ARC4_LOCK(). The interlocked test is used to verify that + * the critical section will be allocated only once. + * + * The work around is for the main program to call arc4random() + * at the beginning of execution, before spinning new threads. + * + * There is also no explicit arc4random_close call, and thus + * the critical section is never deleted. It will remain allocated + * as long as the program runs. + */ +static CRITICAL_SECTION arc_critical_section; +static volatile long arc_critical_section_initialized = 0; + +void _ARC4_LOCK(void) +{ + long r = InterlockedCompareExchange(&arc_critical_section_initialized, 1, 0); + + if (r != 2) + { + if (r == 0) + { + InitializeCriticalSection(&arc_critical_section); + arc_critical_section_initialized = 2; + } + else if (r == 1) + { + /* + * If the critical section is initialized, the first test + * will return the value 2. + * + * If several threads try to initialize the arc4random + * state "at the same time", the first one will find + * the "initialized" variable at 0, the other ones at 1. + * + * Since this is a fairly rare event, we resolve it with a + * simple active wait loop. + */ + + while (arc_critical_section_initialized != 2) + { + Sleep(1); + } + } + } + + EnterCriticalSection(&arc_critical_section); +} + +void _ARC4_UNLOCK(void) +{ + LeaveCriticalSection(&arc_critical_section); +} #else -/* XXX - add windows-(or at least non pthread) specific lock routines here */ + /* XXX - add non pthread specific lock routines here */ void _ARC4_LOCK(void) { } From f1b8b25afad7c5448c88eb01fef14c8ffe53e4b2 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 22 Dec 2016 15:51:47 -0800 Subject: [PATCH 2/5] Implementation of basic MDNS support --- src/context.c | 4 +- src/debug.h | 30 ++++- src/general.c | 21 +++ src/mdns.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/mdns.h | 33 +++++ src/stub.c | 6 +- 6 files changed, 443 insertions(+), 6 deletions(-) create mode 100644 src/mdns.c create mode 100644 src/mdns.h diff --git a/src/context.c b/src/context.c index 7d542c45..10d6a066 100644 --- a/src/context.c +++ b/src/context.c @@ -1682,12 +1682,12 @@ getdns_context_set_namespaces(getdns_context *context, for (i = 0; i < namespace_count; i++) { if (namespaces[i] == GETDNS_NAMESPACE_NETBIOS || - namespaces[i] == GETDNS_NAMESPACE_MDNS || namespaces[i] == GETDNS_NAMESPACE_NIS) r = GETDNS_RETURN_NOT_IMPLEMENTED; else if (namespaces[i] != GETDNS_NAMESPACE_DNS && - namespaces[i] != GETDNS_NAMESPACE_LOCALNAMES) + namespaces[i] != GETDNS_NAMESPACE_LOCALNAMES && + namespaces[i] != GETDNS_NAMESPACE_MDNS) return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; } GETDNS_FREE(context->my_mf, context->namespaces); diff --git a/src/debug.h b/src/debug.h index e106cf67..5afbdea3 100644 --- a/src/debug.h +++ b/src/debug.h @@ -46,17 +46,33 @@ #define STUB_DEBUG_WRITE "------- WRITE: " #define STUB_DEBUG_CLEANUP "--- CLEANUP: " +#ifdef GETDNS_ON_WINDOWS +#define DEBUG_ON(...) do { \ + struct timeval tv; \ + struct tm tm; \ + char buf[10]; \ + time_t tsec; \ + \ + gettimeofday(&tv, NULL); \ + tsec = (time_t) tv.tv_sec; \ + gmtime_s(&tm, (const time_t *) &tsec); \ + strftime(buf, 10, "%H:%M:%S", &tm); \ + fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \ + fprintf(stderr, __VA_ARGS__); \ + } while (0) +#else #define DEBUG_ON(...) do { \ struct timeval tv; \ struct tm tm; \ char buf[10]; \ \ gettimeofday(&tv, NULL); \ - gmtime_r(&tv.tv_sec, &tm); \ + gmtime_r(&tm, &tv.tv_sec); \ strftime(buf, 10, "%H:%M:%S", &tm); \ fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \ fprintf(stderr, __VA_ARGS__); \ } while (0) +#endif #define DEBUG_NL(...) do { \ struct timeval tv; \ @@ -102,5 +118,17 @@ #define DEBUG_SERVER(...) DEBUG_OFF(__VA_ARGS__) #endif +#define MDNS_DEBUG_ENTRY "-> MDNS ENTRY: " +#define MDNS_DEBUG_READ "-- MDNS READ: " +#define MDNS_DEBUG_WRITE "-- MDNS WRITE: " +#define MDNS_DEBUG_CLEANUP "-- MDNS CLEANUP:" + +#if defined(MDNS_DEBUG) && MDNS_DEBUG +#include +#define DEBUG_MDNS(...) DEBUG_ON(__VA_ARGS__) +#else +#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__) +#endif + #endif /* debug.h */ diff --git a/src/general.c b/src/general.c index 99e4cff5..d40e2b52 100644 --- a/src/general.c +++ b/src/general.c @@ -52,6 +52,7 @@ #include "dnssec.h" #include "stub.h" #include "dict.h" +#include "mdns.h" /* cancel, cleanup and send timeout to callback */ static void @@ -476,6 +477,26 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, ( req, localnames_response); break; } + } else if (context->namespaces[i] == GETDNS_NAMESPACE_MDNS) { + /* Check whether the name belongs in the MDNS space */ + if (!(r = _getdns_mdns_namespace_check(req))) + { + // Submit the query to the MDNS transport. + for (netreq_p = req->netreqs + ; !r && (netreq = *netreq_p) + ; netreq_p++) { + if ((r = _getdns_submit_mdns_request(netreq))) { + if (r == DNS_REQ_FINISHED) { + if (return_netreq_p) + *return_netreq_p = NULL; + return GETDNS_RETURN_GOOD; + } + netreq->state = NET_REQ_FINISHED; + } + } + /* Stop processing more namespaces, since there was a match */ + break; + } } else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) { /* TODO: We will get a good return code here even if diff --git a/src/mdns.c b/src/mdns.c new file mode 100644 index 00000000..5e204ab5 --- /dev/null +++ b/src/mdns.c @@ -0,0 +1,355 @@ +/* + * Functions for MDNS resolving. + */ + + /* + * Copyright (c) 2016 Christian Huitema + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "config.h" +#include "debug.h" +#include "context.h" +#include "general.h" +#include "gldns/pkthdr.h" +#include "util-internal.h" +#include "mdns.h" + +#ifdef USE_WINSOCK +typedef u_short sa_family_t; +#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\ + WSAGetLastError() == WSAEWOULDBLOCK) +#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS) +#else +#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK) +#define _getdns_EINPROGRESS (errno == EINPROGRESS) +#endif + +uint64_t _getdns_get_time_as_uintt64(); + +/* + * Constants defined in RFC 6762 + */ + +#define MDNS_MCAST_IPV4_LONG 0xE00000FB /* 224.0.0.251 */ +#define MDNS_MCAST_PORT 5353 + +static uint8_t mdns_mcast_ipv6[] = { + 0xFF, 0x02, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0xFB }; + + +static uint8_t mdns_suffix_dot_local[] = { 5, 'l', 'o', 'c', 'a', 'l', 0 }; +static uint8_t mdns_suffix_254_169_in_addr_arpa[] = { + 3, '2', '5', '4', + 3, '1', '6', '9', + 7, 'i', 'n', '-', 'a', 'd', 'd', 'r', + 4, 'a', 'r', 'p', 'a', 0 }; +static uint8_t mdns_suffix_8_e_f_ip6_arpa[] = { + 1, '8', 1, 'e', 1, 'f', + 7, 'i', 'p', 'v', '6', + 4, 'a', 'r', 'p', 'a', 0 }; +static uint8_t mdns_suffix_9_e_f_ip6_arpa[] = { + 1, '9', 1, 'e', 1, 'f', + 7, 'i', 'p', 'v', '6', + 4, 'a', 'r', 'p', 'a', 0 }; +static uint8_t mdns_suffix_a_e_f_ip6_arpa[] = { + 1, 'a', 1, 'e', 1, 'f', + 7, 'i', 'p', 'v', '6', + 4, 'a', 'r', 'p', 'a', 0 }; +static uint8_t mdns_suffix_b_e_f_ip6_arpa[] = { + 1, 'b', 1, 'e', 1, 'f', + 7, 'i', 'p', 'v', '6', + 4, 'a', 'r', 'p', 'a', 0 }; + +/* TODO: actualy delete what is required.. */ +static void +mdns_cleanup(getdns_network_req *netreq) +{ + DEBUG_MDNS("%s %-35s: MSG: %p\n", + MDNS_DEBUG_CLEANUP, __FUNCTION__, netreq); + getdns_dns_req *dnsreq = netreq->owner; + + GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); + + GETDNS_NULL_FREE(dnsreq->context->mf, netreq->tcp.read_buf); +} + +void +_getdns_cancel_mdns_request(getdns_network_req *netreq) +{ + mdns_cleanup(netreq); + if (netreq->fd >= 0) { +#ifdef USE_WINSOCK + closesocket(netreq->fd); +#else + close(netreq->fd); +#endif + } +} + +static void +mdns_timeout_cb(void *userarg) +{ + getdns_network_req *netreq = (getdns_network_req *)userarg; + DEBUG_MDNS("%s %-35s: MSG: %p\n", + MDNS_DEBUG_CLEANUP, __FUNCTION__, netreq); + + /* TODO: do we need a retry logic here? */ + + /* Check the required cleanup */ + mdns_cleanup(netreq); + if (netreq->fd >= 0) +#ifdef USE_WINSOCK + closesocket(netreq->fd); +#else + close(netreq->fd); +#endif + netreq->state = NET_REQ_TIMED_OUT; + if (netreq->owner->user_callback) { + netreq->debug_end_time = _getdns_get_time_as_uintt64(); + (void)_getdns_context_request_timed_out(netreq->owner); + } + else + _getdns_check_dns_req_complete(netreq->owner); +} + + + +/**************************/ +/* UDP callback functions */ +/**************************/ + +static void +mdns_udp_read_cb(void *userarg) +{ + getdns_network_req *netreq = (getdns_network_req *)userarg; + getdns_dns_req *dnsreq = netreq->owner; + ssize_t read; + DEBUG_MDNS("%s %-35s: MSG: %p \n", MDNS_DEBUG_READ, + __FUNCTION__, netreq); + + GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); + + read = recvfrom(netreq->fd, (void *)netreq->response, + netreq->max_udp_payload_size + 1, /* If read == max_udp_payload_size + * then all is good. If read == + * max_udp_payload_size + 1, then + * we receive more then requested! + * i.e. overflow + */ + 0, NULL, NULL); + if (read == -1 && _getdns_EWOULDBLOCK) + return; + + if (read < GLDNS_HEADER_SIZE) + return; /* Not DNS */ + + if (GLDNS_ID_WIRE(netreq->response) != netreq->query_id) + return; /* Cache poisoning attempt ;) */ + + // TODO: check whether EDNS server cookies are required for MDNS + + // TODO: check that the source address originates from the local network. + // TODO: check TTL = 255 + +#ifdef USE_WINSOCK + closesocket(netreq->fd); +#else + close(netreq->fd); +#endif + /* + * TODO: how to handle an MDNS response with TC bit set? + * Ignore it for now, as we do not support any kind of TCP fallback + * for basic MDNS. + */ + + netreq->response_len = read; + netreq->debug_end_time = _getdns_get_time_as_uintt64(); + netreq->state = NET_REQ_FINISHED; + _getdns_check_dns_req_complete(dnsreq); +} + +static void +mdns_udp_write_cb(void *userarg) +{ + getdns_network_req *netreq = (getdns_network_req *)userarg; + getdns_dns_req *dnsreq = netreq->owner; + size_t pkt_len = netreq->response - netreq->query; + struct sockaddr_in mdns_mcast_v4; + int ttl = 255; + int r; + + DEBUG_MDNS("%s %-35s: MSG: %p \n", MDNS_DEBUG_WRITE, + __FUNCTION__, netreq); + + GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); + + netreq->debug_start_time = _getdns_get_time_as_uintt64(); + netreq->debug_udp = 1; + netreq->query_id = (uint16_t) arc4random(); + GLDNS_ID_SET(netreq->query, netreq->query_id); + + /* do we need to handle options valid in the MDNS context? */ + + /* Probably no need for TSIG in MDNS */ + + + /* Always use multicast address */ + mdns_mcast_v4.sin_family = AF_INET; + mdns_mcast_v4.sin_port = htons(MDNS_MCAST_PORT); + mdns_mcast_v4.sin_addr.s_addr = htonl(MDNS_MCAST_IPV4_LONG); + + + /* Set TTL=255 for compliance with RFC 6762 */ + r = setsockopt(netreq->fd, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(ttl)); + + if (r != 0 || + (ssize_t)pkt_len != sendto( + netreq->fd, (const void *)netreq->query, pkt_len, 0, + (struct sockaddr *)&mdns_mcast_v4, + sizeof(mdns_mcast_v4))) { +#ifdef USE_WINSOCK + closesocket(netreq->fd); +#else + close(netreq->fd); +#endif + return; + } + GETDNS_SCHEDULE_EVENT( + dnsreq->loop, netreq->fd, dnsreq->context->timeout, + getdns_eventloop_event_init(&netreq->event, netreq, + mdns_udp_read_cb, NULL, mdns_timeout_cb)); +} + +/* + * MDNS Request Submission + */ + +getdns_return_t +_getdns_submit_mdns_request(getdns_network_req *netreq) +{ + DEBUG_MDNS("%s %-35s: MSG: %p TYPE: %d\n", MDNS_DEBUG_ENTRY, __FUNCTION__, + netreq, netreq->request_type); + int fd = -1; + getdns_dns_req *dnsreq = netreq->owner; + + /* Open the UDP socket required for the request */ + if ((fd = socket( + AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + return -1; + /* TODO: do we need getdns_sock_nonblock(fd); */ + + /* Schedule the MDNS request */ + netreq->fd = fd; + GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); + GETDNS_SCHEDULE_EVENT( + dnsreq->loop, netreq->fd, dnsreq->context->timeout, + getdns_eventloop_event_init(&netreq->event, netreq, + NULL, mdns_udp_write_cb, mdns_timeout_cb)); + return GETDNS_RETURN_GOOD; +} + +/* + * MDNS name space management + */ + +static int +mdns_suffix_compare(register const uint8_t *d1, register const uint8_t *d2) +{ + int ret = 0; + uint8_t *d1_head = (uint8_t *) d1; + uint8_t *d1_current; + uint8_t *d2_current; + int is_matching = 0; + int part_length; + int i; + uint8_t c; + + /* Skip the first name part, since we want at least one label before the suffix */ + if (*d1_head != 0) + d1_head += *d1_head + 1; + + while (*d1_head != 0) + { + /* check whether we have a match at this point */ + d1_current = d1_head; + d2_current = (uint8_t *) d2; + is_matching = 0; + + /* compare length and value of all successive labels */ + while (*d1_current == *d2_current) + { + part_length = *d1_current; + if (part_length == 0) + { + /* We have reached the top label, there is a match */ + ret = 1; + break; + } + + /* The label's lengths are matching, check the content */ + is_matching = 1; + d1_current++; + d2_current++; + + for (i = 0; i < part_length; i++) + { + c = d1_current[i]; + if (isupper(c)) + c = tolower(c); + if (c != d2_current[i]) + { + is_matching = 0; + break; + } + } + + /* move the pointers to the next label */ + if (is_matching) + { + d1_current += part_length; + d2_current += part_length; + } + } + + /* if no match found yet, move to the next label of d1 */ + if (is_matching) + break; + else + d1_head += *d1_head + 1; + } + + return ret; +} + + +getdns_return_t +_getdns_mdns_namespace_check( + getdns_dns_req *dnsreq) +{ + getdns_return_t ret = GETDNS_RETURN_GENERIC_ERROR; + + /* Checking the prefixes defined in RFC 6762 */ + if (mdns_suffix_compare(dnsreq->name, mdns_suffix_dot_local) || + mdns_suffix_compare(dnsreq->name, mdns_suffix_254_169_in_addr_arpa) || + mdns_suffix_compare(dnsreq->name, mdns_suffix_8_e_f_ip6_arpa) || + mdns_suffix_compare(dnsreq->name, mdns_suffix_9_e_f_ip6_arpa) || + mdns_suffix_compare(dnsreq->name, mdns_suffix_a_e_f_ip6_arpa) || + mdns_suffix_compare(dnsreq->name, mdns_suffix_b_e_f_ip6_arpa)) + ret = GETDNS_RETURN_GOOD; + + return ret; +} \ No newline at end of file diff --git a/src/mdns.h b/src/mdns.h new file mode 100644 index 00000000..67800121 --- /dev/null +++ b/src/mdns.h @@ -0,0 +1,33 @@ +/* +* Functions for MDNS resolving. +*/ + +/* +* Copyright (c) 2016 Christian Huitema +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef MDNS_H +#define MDNS_H + +#include "getdns/getdns.h" +#include "types-internal.h" + +getdns_return_t +_getdns_submit_mdns_request(getdns_network_req *netreq); + +getdns_return_t +getdns_mdns_namespace_check(getdns_dns_req *dnsreq); + +#endif /* MDNS_H */ \ No newline at end of file diff --git a/src/stub.c b/src/stub.c index ed666368..e047462e 100644 --- a/src/stub.c +++ b/src/stub.c @@ -91,7 +91,7 @@ static int upstream_connect(getdns_upstream *upstream, static int fallback_on_write(getdns_network_req *netreq); static void stub_timeout_cb(void *userarg); -static uint64_t _getdns_get_time_as_uintt64(); +uint64_t _getdns_get_time_as_uintt64(); /*****************************/ /* General utility functions */ /*****************************/ @@ -475,7 +475,7 @@ stub_cleanup(getdns_network_req *netreq) GETDNS_NULL_FREE(dnsreq->context->mf, netreq->tcp.read_buf); /* Nothing globally scheduled? Then nothing queued */ - if (!(upstream = netreq->upstream)->event.ev) + if (!netreq->upstream || !(upstream = netreq->upstream)->event.ev) return; /* Delete from upstream->netreq_by_query_id (if present) */ @@ -1278,7 +1278,7 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp, return STUB_TCP_ERROR; } -static uint64_t +uint64_t _getdns_get_time_as_uintt64() { struct timeval tv; From 2e46a4b136355e4898621e0dd22f8d27d2a35f23 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 22 Dec 2016 19:37:49 -0800 Subject: [PATCH 3/5] Adding missing directives for mdns.c, .o, .lo in make file. --- src/Makefile.in | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index 02e8a0b7..f095d6a6 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -67,7 +67,8 @@ C99COMPATFLAGS=@C99COMPATFLAGS@ GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \ list.lo request-internal.lo pubkey-pinning.lo rr-dict.lo \ - rr-iter.lo stub.lo sync.lo ub_loop.lo util-internal.lo + rr-iter.lo stub.lo sync.lo ub_loop.lo util-internal.lo \ + mdns.lo GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \ str2wire.lo @@ -234,7 +235,7 @@ context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/debug.h $(srcdir)/g getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h + $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ @@ -256,7 +257,8 @@ general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/ge getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \ $(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ getdns/getdns_extra.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \ + $(srcdir)/mdns.h list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h config.h $(srcdir)/context.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ @@ -284,6 +286,12 @@ stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h get $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/context.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h +mdns.lo mdns.o: $(srcdir)/mdns.c config.h $(srcdir)/debug.h $(srcdir)/mdns.h getdns/getdns.h $(srcdir)/types-internal.h \ + getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/context.h \ + $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ + $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ From 1d24c9076899d20d2533b9c964fc60699a5ab5b4 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 22 Dec 2016 20:07:31 -0800 Subject: [PATCH 4/5] Fixing bad declaration in mdns.h --- src/mdns.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mdns.h b/src/mdns.h index 67800121..95458585 100644 --- a/src/mdns.h +++ b/src/mdns.h @@ -28,6 +28,6 @@ getdns_return_t _getdns_submit_mdns_request(getdns_network_req *netreq); getdns_return_t -getdns_mdns_namespace_check(getdns_dns_req *dnsreq); +_getdns_mdns_namespace_check(getdns_dns_req *dnsreq); #endif /* MDNS_H */ \ No newline at end of file From 99fb7100eabf3040db723d4e4895b3f0ade0fbb8 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 22 Dec 2016 20:30:14 -0800 Subject: [PATCH 5/5] Placing all MDNS code under ifdef HAVE MDNS SUPPORT to minimize risk in main branch. --- src/context.c | 9 +++++++-- src/general.c | 2 ++ src/mdns.c | 16 +++++++++++----- src/mdns.h | 4 +++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/context.c b/src/context.c index 10d6a066..34432780 100644 --- a/src/context.c +++ b/src/context.c @@ -1682,12 +1682,17 @@ getdns_context_set_namespaces(getdns_context *context, for (i = 0; i < namespace_count; i++) { if (namespaces[i] == GETDNS_NAMESPACE_NETBIOS || +#ifndef HAVE_MDNS_SUPPORT + namespaces[i] == GETDNS_NAMESPACE_MDNS || +#endif namespaces[i] == GETDNS_NAMESPACE_NIS) r = GETDNS_RETURN_NOT_IMPLEMENTED; else if (namespaces[i] != GETDNS_NAMESPACE_DNS && - namespaces[i] != GETDNS_NAMESPACE_LOCALNAMES && - namespaces[i] != GETDNS_NAMESPACE_MDNS) +#ifdef HAVE_MDNS_SUPPORT + namespaces[i] != GETDNS_NAMESPACE_MDNS && +#endif + namespaces[i] != GETDNS_NAMESPACE_LOCALNAMES ) return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; } GETDNS_FREE(context->my_mf, context->namespaces); diff --git a/src/general.c b/src/general.c index d40e2b52..97a97dcf 100644 --- a/src/general.c +++ b/src/general.c @@ -477,6 +477,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, ( req, localnames_response); break; } +#ifdef HAVE_MDNS_SUPPORT } else if (context->namespaces[i] == GETDNS_NAMESPACE_MDNS) { /* Check whether the name belongs in the MDNS space */ if (!(r = _getdns_mdns_namespace_check(req))) @@ -497,6 +498,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, /* Stop processing more namespaces, since there was a match */ break; } +#endif /* HAVE_MDNS_SUPPORT */ } else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) { /* TODO: We will get a good return code here even if diff --git a/src/mdns.c b/src/mdns.c index 5e204ab5..36950f36 100644 --- a/src/mdns.c +++ b/src/mdns.c @@ -27,6 +27,8 @@ #include "util-internal.h" #include "mdns.h" +#ifdef HAVE_MDNS_SUPPORT + #ifdef USE_WINSOCK typedef u_short sa_family_t; #define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\ @@ -46,10 +48,12 @@ uint64_t _getdns_get_time_as_uintt64(); #define MDNS_MCAST_IPV4_LONG 0xE00000FB /* 224.0.0.251 */ #define MDNS_MCAST_PORT 5353 -static uint8_t mdns_mcast_ipv6[] = { - 0xFF, 0x02, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xFB }; - +/* + * TODO: When we start supporting IPv6 with MDNS, need to define this: + * static uint8_t mdns_mcast_ipv6[] = { + * 0xFF, 0x02, 0, 0, 0, 0, 0, 0, + * 0, 0, 0, 0, 0, 0, 0, 0xFB }; + */ static uint8_t mdns_suffix_dot_local[] = { 5, 'l', 'o', 'c', 'a', 'l', 0 }; static uint8_t mdns_suffix_254_169_in_addr_arpa[] = { @@ -352,4 +356,6 @@ _getdns_mdns_namespace_check( ret = GETDNS_RETURN_GOOD; return ret; -} \ No newline at end of file +} + +#endif /* HAVE_MDNS_SUPPORT */ diff --git a/src/mdns.h b/src/mdns.h index 95458585..30ae3135 100644 --- a/src/mdns.h +++ b/src/mdns.h @@ -21,6 +21,7 @@ #ifndef MDNS_H #define MDNS_H +#ifdef HAVE_MDNS_SUPPORT #include "getdns/getdns.h" #include "types-internal.h" @@ -29,5 +30,6 @@ _getdns_submit_mdns_request(getdns_network_req *netreq); getdns_return_t _getdns_mdns_namespace_check(getdns_dns_req *dnsreq); +#endif /* HAVE_MDNS_SUPPORT */ -#endif /* MDNS_H */ \ No newline at end of file +#endif /* MDNS_H */