From 87ed6543bc006aa76a15562f3c11d4be1ad2902b Mon Sep 17 00:00:00 2001 From: Apple Date: Sat, 14 Feb 2015 01:01:21 +0000 Subject: [PATCH] Libinfo-459.20.1.tar.gz --- lookup.subproj/mdns_module.c | 826 +++++++++++++++++++++++++++---------------- 1 file changed, 524 insertions(+), 302 deletions(-) diff --git a/lookup.subproj/mdns_module.c b/lookup.subproj/mdns_module.c index 63890e8..9784693 100644 --- a/lookup.subproj/mdns_module.c +++ b/lookup.subproj/mdns_module.c @@ -2,14 +2,14 @@ * Copyright (c) 2008-2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ /* @@ -39,7 +39,7 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -51,7 +51,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -66,14 +66,14 @@ */ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * 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, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -142,10 +142,11 @@ static int _mdns_debug = 0; -// mutex protects DNSServiceProcessResult and DNSServiceRefDeallocate +/* mutex protects DNSServiceProcessResult and DNSServiceRefDeallocate */ static pthread_mutex_t _mdns_mutex = PTHREAD_MUTEX_INITIALIZER; -typedef struct { +typedef struct +{ uint16_t priority; uint16_t weight; uint16_t port; @@ -153,18 +154,21 @@ typedef struct { } mdns_rr_srv_t; typedef struct mdns_srv_t mdns_srv_t; -struct mdns_srv_t { +struct mdns_srv_t +{ si_srv_t srv; mdns_srv_t *next; }; -typedef struct { +typedef struct +{ struct hostent host; int alias_count; int addr_count; } mdns_hostent_t; -typedef struct { +typedef struct +{ mdns_hostent_t *h4; mdns_hostent_t *h6; mdns_srv_t *srv; @@ -209,6 +213,8 @@ _mdns_debug_message(const char *str, ...) { va_list v; char *out = NULL; + + if (str == NULL) return; if ((_mdns_debug & MDNS_DEBUG_OUT) == 0) return; va_start(v, str); @@ -252,6 +258,7 @@ _mdns_reverse_ipv6(const char *addr) x[64] = '\0'; j = 63; + for (i = 0; i < 16; i++) { d = addr[i]; @@ -268,7 +275,8 @@ _mdns_reverse_ipv6(const char *addr) return p; } -/* _mdns_canonicalize +/* + * _mdns_canonicalize * Canonicalize the domain name by converting to lower case and removing the * trailing '.' if present. */ @@ -277,18 +285,26 @@ _mdns_canonicalize(const char *s) { int i; char *t; + if (s == NULL) return NULL; + t = strdup(s); if (t == NULL) return NULL; + if (t[0] == '\0') return t; - for (i = 0; t[i] != '\0'; i++) { + + for (i = 0; t[i] != '\0'; i++) + { if (t[i] >= 'A' && t[i] <= 'Z') t[i] += 32; } + if (t[i-1] == '.') t[i-1] = '\0'; + return t; } -/* _mdns_hostent_append_alias +/* + * _mdns_hostent_append_alias * Appends an alias to the mdns_hostent_t structure. */ static int @@ -296,56 +312,71 @@ _mdns_hostent_append_alias(mdns_hostent_t *h, const char *alias) { int i; char *name; - if (h == NULL || alias == NULL) return 0; + + if ((h == NULL) || (alias == NULL)) return 0; + name = _mdns_canonicalize(alias); if (name == NULL) return -1; - // don't add the name if it matches an existing name - if (h->host.h_name && string_equal(h->host.h_name, name)) { + /* don't add the name if it matches an existing name */ + if ((h->host.h_name != NULL) && string_equal(h->host.h_name, name)) + { free(name); return 0; } - for (i = 0; i < h->alias_count; ++i) { - if (string_equal(h->host.h_aliases[i], name)) { + + for (i = 0; i < h->alias_count; ++i) + { + if (string_equal(h->host.h_aliases[i], name)) + { free(name); return 0; } } - // add the alias and NULL terminate the list - h->host.h_aliases = (char **)reallocf(h->host.h_aliases, (h->alias_count+2) * sizeof(char *)); - if (h->host.h_aliases == NULL) { + /* add the alias and NULL terminate the list if it is new */ + h->host.h_aliases = (char **)reallocf(h->host.h_aliases, (h->alias_count + 2) * sizeof(char *)); + if (h->host.h_aliases == NULL) + { h->alias_count = 0; free(name); return -1; } + h->host.h_aliases[h->alias_count] = name; - ++h->alias_count; + h->alias_count++; + h->host.h_aliases[h->alias_count] = NULL; return 0; } -/* _mdns_hostent_append_addr +/* + * _mdns_hostent_append_addr * Appends an alias to the mdns_hostent_t structure. */ static int _mdns_hostent_append_addr(mdns_hostent_t *h, const uint8_t *addr, uint32_t len) { - if (h == NULL || addr == NULL || len == 0) return 0; + if ((h == NULL) || (addr == NULL) || (len == 0)) return 0; - // copy the address buffer + /* copy the address buffer */ uint8_t *buf = malloc(len); if (buf == NULL) return -1; + memcpy(buf, addr, len); - // add the address and NULL terminate the list - h->host.h_addr_list = (char **)reallocf(h->host.h_addr_list, (h->addr_count+2) * sizeof(char *)); - if (h->host.h_addr_list == NULL) { + /* add the address and NULL terminate the list if it is new */ + h->host.h_addr_list = (char **)reallocf(h->host.h_addr_list, (h->addr_count + 2) * sizeof(char *)); + + if (h->host.h_addr_list == NULL) + { h->addr_count = 0; return -1; } + h->host.h_addr_list[h->addr_count] = (char*)buf; h->addr_count++; + h->host.h_addr_list[h->addr_count] = NULL; return 0; } @@ -354,37 +385,38 @@ static void _mdns_hostent_clear(mdns_hostent_t *h) { if (h == NULL) return; + free(h->host.h_name); h->host.h_name = NULL; char **aliases = h->host.h_aliases; - while (aliases && *aliases) { - free(*aliases++); - } + while (aliases && *aliases) free(*aliases++); + free(h->host.h_aliases); h->host.h_aliases = NULL; h->alias_count = 0; char **addrs = h->host.h_addr_list; - while (addrs && *addrs) { - free(*addrs++); - } + while (addrs && *addrs) free(*addrs++); + free(h->host.h_addr_list); h->host.h_addr_list = NULL; h->addr_count = 0; - } static void _mdns_reply_clear(mdns_reply_t *r) { if (r == NULL) return; + r->ifnum = 0; _mdns_hostent_clear(r->h4); _mdns_hostent_clear(r->h6); mdns_srv_t *srv = r->srv; r->srv = NULL; - while (srv) { + + while (srv != NULL) + { mdns_srv_t *next = srv->next; free(srv->srv.target); free(srv); @@ -405,7 +437,8 @@ mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, u if (err != NULL) *err = SI_STATUS_NO_ERROR; - if (name == NULL) { + if ((name == NULL) || (si == NULL)) + { if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; } @@ -413,7 +446,8 @@ mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, u memset(&h, 0, sizeof(h)); memset(&reply, 0, sizeof(reply)); - switch (af) { + switch (af) + { case AF_INET: type = ns_t_a; h.host.h_length = 4; @@ -428,10 +462,14 @@ mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, u if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; } + + _mdns_debug_message(";; mdns_hostbyname %s type %u class %u\n", name, type, ns_c_in); + h.host.h_addrtype = af; status = _mdns_search(name, ns_c_in, type, interface, flags, NULL, NULL, &reply); - if (status != 0 || h.addr_count == 0) { + if ((status != 0) || (h.addr_count == 0)) + { _mdns_reply_clear(&reply); if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND; return NULL; @@ -439,7 +477,8 @@ mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, u bb = reply.ttl + time(NULL); - switch (af) { + switch (af) + { case AF_INET: out = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, CATEGORY_HOST_IPV4, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, h.host.h_addrtype, h.host.h_length, h.host.h_addr_list); break; @@ -450,7 +489,7 @@ mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, u _mdns_reply_clear(&reply); - if (out == NULL && err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; + if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return out; } @@ -469,7 +508,8 @@ mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, u if (err != NULL) *err = SI_STATUS_NO_ERROR; - if (addr == NULL || si == NULL) { + if ((addr == NULL) || (si == NULL)) + { if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; } @@ -477,7 +517,8 @@ mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, u memset(&h, 0, sizeof(h)); memset(&reply, 0, sizeof(reply)); - switch (af) { + switch (af) + { case AF_INET: h.host.h_length = 4; reply.h4 = &h; @@ -494,18 +535,23 @@ mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, u if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; } + h.host.h_addrtype = af; + _mdns_debug_message(";; mdns_hostbyaddr %s type %u class %u\n", name, ns_t_ptr, ns_c_in); + status = _mdns_search(name, ns_c_in, ns_t_ptr, interface, flags, NULL, NULL, &reply); free(name); - if (status != 0) { + if (status != 0) + { _mdns_reply_clear(&reply); if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND; return NULL; } status = _mdns_hostent_append_addr(&h, addr, h.host.h_length); - if (status != 0) { + if (status != 0) + { _mdns_hostent_clear(&h); if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; @@ -516,15 +562,15 @@ mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, u _mdns_hostent_clear(&h); - if (out == NULL && err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; + if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return out; } static si_list_t * mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err) { - int wantv4 = 1; - int wantv6 = 1; + bool wantv4 = true; + bool wantv6 = true; struct in_addr a4; struct in6_addr a6; mdns_hostent_t h4; @@ -533,13 +579,19 @@ mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t type; uint16_t port; + if (si == NULL) + { + if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; + return NULL; + } + if (family == AF_INET6) { - if ((flags & AI_V4MAPPED) == 0) wantv4 = 0; + if ((flags & AI_V4MAPPED) == 0) wantv4 = false; } else if (family == AF_INET) { - wantv6 = 0; + wantv6 = false; } else if (family != AF_UNSPEC) { @@ -548,6 +600,8 @@ mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, if (err != NULL) *err = SI_STATUS_NO_ERROR; + _mdns_debug_message(";; mdns_addrinfo node %s serv %s\n", (const char *)node, (const char *)serv); + si_list_t *out = NULL; memset(&h4, 0, sizeof(h4)); @@ -559,61 +613,90 @@ mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, h6.host.h_addrtype = AF_INET6; h6.host.h_length = 16; - if (wantv4 && wantv6) { + if (wantv4 && wantv6) + { type = 0; reply.h4 = &h4; reply.h6 = &h6; - } else if (wantv4) { + } + else if (wantv4) + { reply.h4 = &h4; type = ns_t_a; - } else if (wantv6) { + } + else if (wantv6) + { type = ns_t_aaaa; reply.h6 = &h6; - } else { + } + else + { if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; } - // service lookup - if ((flags & AI_NUMERICSERV) != 0) { - port = *(uint16_t *)serv; - } else { - if (_gai_serv_to_port(serv, proto, &port) != 0) { + /* service lookup */ + if ((flags & AI_NUMERICSERV) != 0) + { + if (serv == NULL) port = 0; + else port = *(uint16_t *)serv; + } + else + { + if (_gai_serv_to_port(serv, proto, &port) != 0) + { if (err) *err = SI_STATUS_EAI_NONAME; return NULL; } } - // host lookup - if ((flags & AI_NUMERICHOST) != 0) { + /* host lookup */ + if ((flags & AI_NUMERICHOST) != 0) + { char *cname = NULL; struct in_addr *p4 = NULL; struct in6_addr *p6 = NULL; - if (family == AF_INET) { + + if (node == NULL) return NULL; + + if (family == AF_INET) + { p4 = &a4; memcpy(p4, node, sizeof(a4)); - } else if (family == AF_INET6) { + } + else if (family == AF_INET6) + { p6 = &a6; memcpy(p6, node, sizeof(a6)); } + out = si_addrinfo_list(si, flags, socktype, proto, p4, p6, port, 0, cname, cname); - } else { + } + else + { + int res; DNSServiceFlags dns_flags = 0; - if (flags & AI_ADDRCONFIG) { + + if (node == NULL) return NULL; + + if (flags & AI_ADDRCONFIG) + { dns_flags |= kDNSServiceFlagsSuppressUnusable; } - int res; + res = _mdns_search(node, ns_c_in, type, interface, dns_flags, NULL, NULL, &reply); - if (res == 0 && (h4.addr_count > 0 || h6.addr_count > 0)) { - out = si_addrinfo_list_from_hostent(si, flags, socktype, proto, - port, 0, - (wantv4 ? &h4.host : NULL), - (wantv6 ? &h6.host : NULL)); - } else if (err != NULL) { + if ((res == 0) && ((h4.addr_count > 0) || (h6.addr_count > 0))) + { + out = si_addrinfo_list_from_hostent(si, flags, socktype, proto, port, 0, (wantv4 ? &h4.host : NULL), (wantv6 ? &h6.host : NULL)); + } + else if (err != NULL) + { *err = SI_STATUS_EAI_NONAME; } + _mdns_reply_clear(&reply); } + return out; } @@ -627,13 +710,23 @@ mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t const uint64_t unused = 0; DNSServiceFlags flags = 0; + if (si == NULL) + { + if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; + return NULL; + } + if (err != NULL) *err = SI_STATUS_NO_ERROR; + _mdns_debug_message(";; mdns_srv_byname %s type %u class %u\n", qname, ns_t_srv, ns_c_in); + memset(&reply, 0, sizeof(reply)); res = _mdns_search(qname, ns_c_in, ns_t_srv, interface, flags, NULL, NULL, &reply); - if (res == 0) { + if (res == 0) + { srv = reply.srv; - while (srv) { + while (srv != NULL) + { si_item_t *item; item = (si_item_t *)LI_ils_create("L4488222s", (unsigned long)si, CATEGORY_SRV, 1, unused, unused, srv->srv.priority, srv->srv.weight, srv->srv.port, srv->srv.target); out = si_list_add(out, item); @@ -641,6 +734,7 @@ mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t srv = srv->next; } } + _mdns_reply_clear(&reply); return out; } @@ -660,13 +754,16 @@ mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, co si_item_t *out; DNSServiceFlags flags = 0; - if (err != NULL) *err = SI_STATUS_NO_ERROR; - - if (name == NULL) { + if ((si == NULL) || (name == NULL)) + { if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; return NULL; } + if (err != NULL) *err = SI_STATUS_NO_ERROR; + + _mdns_debug_message(";; mdns_item_call %s type %u class %u\n", name, type, class); + memset(&h4, 0, sizeof(h4)); memset(&h6, 0, sizeof(h6)); memset(&reply, 0, sizeof(reply)); @@ -679,7 +776,8 @@ mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, co reply.h6 = &h6; res = _mdns_search(name, class, type, interface, flags, buf, &len, &reply); - if (res != 0 || len <= 0 || len > DNS_MAX_RECEIVE_SIZE) { + if ((res != 0) || (len <= 0) || (len > DNS_MAX_RECEIVE_SIZE)) + { _mdns_reply_clear(&reply); if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND; return NULL; @@ -691,13 +789,15 @@ mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, co from.sin6_len = fromlen; from.sin6_family = AF_INET6; from.sin6_addr.__u6_addr.__u6_addr8[15] = 1; - if (reply.ifnum != 0) { + + if (reply.ifnum != 0) + { from.sin6_addr.__u6_addr.__u6_addr16[0] = htons(0xfe80); from.sin6_scope_id = reply.ifnum; } out = (si_item_t *)LI_ils_create("L4488@@", (unsigned long)si, CATEGORY_DNSPACKET, 1, 0LL, 0LL, len, buf, fromlen, &from); - if (out == NULL && err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; + if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY; _mdns_reply_clear(&reply); @@ -718,21 +818,21 @@ mdns_close(si_mod_t *si) static void _mdns_atfork_prepare(void) { - // acquire our lock so that we know all other threads have "drained" + /* acquire our lock so that we know all other threads have "drained" */ pthread_mutex_lock(&_mdns_mutex); } static void _mdns_atfork_parent(void) { - // parent can simply resume + /* parent can simply resume */ pthread_mutex_unlock(&_mdns_mutex); } static void _mdns_atfork_child(void) { - // child needs to force re-initialization + /* child needs to force re-initialization */ _mdns_old_sdref = _mdns_sdref; // for later deallocation _mdns_sdref = NULL; pthread_mutex_unlock(&_mdns_mutex); @@ -746,6 +846,7 @@ _mdns_init(void) if (getenv("RES_DEBUG") != NULL) _mdns_debug |= MDNS_DEBUG_STDOUT; int fd = open(MDNS_DEBUG_FILE, O_RDONLY, 0); errno = 0; + if (fd >= 0) { int i, n; @@ -812,28 +913,40 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen) if ((data == NULL) || (datalen == 0)) return NULL; - // i: index into input data - // j: index into output string - while (datalen-- > 0) { + /* + * i: index into input data + * j: index into output string + */ + while (datalen-- > 0) + { len = data[i++]; domainlen += (len + 1); domain = reallocf(domain, domainlen); + if (domain == NULL) return NULL; + if (len == 0) break; // DNS root (NUL) - if (j > 0) { - domain[j++] = datalen ? '.' : '\0'; + + if (j > 0) + { + domain[j++] = datalen ? '.' : '\0'; } - while ((len-- > 0) && (datalen--)) { - if (data[i] == '.') { - // special case: escape the '.' with a '\' + while ((len-- > 0) && (0 != datalen--)) + { + if (data[i] == '.') + { + /* special case: escape the '.' with a '\' */ domain = reallocf(domain, ++domainlen); if (domain == NULL) return NULL; + domain[j++] = '\\'; } + domain[j++] = data[i++]; } } + domain[j] = '\0'; return domain; @@ -845,29 +958,38 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen) * Only used for one string at a time, therefore no need for compression. */ static int -_mdns_pack_domain_name(const char* str, uint8_t *buf, size_t buflen) { +_mdns_pack_domain_name(const char *str, uint8_t *buf, size_t buflen) +{ int i = 0; uintptr_t len = 0; - while (i < buflen) { - // calculate length to next '.' or '\0' + if ((str == NULL) || (buf == NULL)) return -1; + + while (i < buflen) + { + /* calculate length to next '.' or '\0' */ char *dot = strchr(str, '.'); if (dot == NULL) dot = strchr(str, '\0'); + len = (dot - str); if (len > NS_MAXLABEL) return -1; - // copy data for label + + /* copy data for label */ buf[i++] = len; - while (str < dot && i < buflen) { + while (str < dot && i < buflen) + { buf[i++] = *str++; } - // skip past '.', break if '\0' + + /* skip past '.', break if '\0' */ if (*str++ == '\0') break; } if (i >= buflen) return -1; - if (len > 0) { - // no trailing dot - add a null label + if (len > 0) + { + /* no trailing dot - add a null label */ buf[i++] = 0; if (i >= buflen) return -1; } @@ -909,7 +1031,8 @@ _is_rev_link_local(const char *name) return 1; } -/* _mdns_ipv6_extract_scope_id +/* + * _mdns_ipv6_extract_scope_id * If the input string is a link local IPv6 address with an encoded scope id, * the scope id is extracted and a new string is constructed with the scope id removed. */ @@ -922,9 +1045,10 @@ _mdns_ipv6_extract_scope_id(const char *name, uint32_t *out_ifnum) int i; if (out_ifnum != NULL) *out_ifnum = 0; + if (name == NULL) return NULL; /* examine the address, extract the scope id if present */ - if ((name != NULL) && (_is_rev_link_local(name))) + if (_is_rev_link_local(name)) { /* _is_rev_link_local rejects chars > 127 so it's safe to index into hexval */ i = IPv6_REVERSE_LINK_LOCAL_SCOPE_ID_LOW; @@ -966,7 +1090,8 @@ _mdns_make_query(const char* name, int class, int type, uint8_t *buf, uint32_t b { uint32_t len = 0; - if (buf == NULL || buflen < (NS_HFIXEDSZ + NS_QFIXEDSZ)) return -1; + if ((buf == NULL) || (buflen < (NS_HFIXEDSZ + NS_QFIXEDSZ))) return -1; + memset(buf, 0, NS_HFIXEDSZ); HEADER *hp = (HEADER *)buf; @@ -989,28 +1114,31 @@ _mdns_make_query(const char* name, int class, int type, uint8_t *buf, uint32_t b word = htons(class); memcpy(&buf[len], &word, sizeof(word)); len += sizeof(word); + return len; } -typedef struct { +typedef struct +{ mdns_reply_t *reply; mdns_hostent_t *host; - uint8_t *answer; // DNS packet buffer - size_t anslen; // DNS packet buffer current length - size_t ansmaxlen; // DNS packet buffer maximum length - int type; // type of query: A, AAAA, PTR, SRV... - uint16_t last_type; // last type received + uint8_t *answer; // DNS packet buffer + size_t anslen; // DNS packet buffer current length + size_t ansmaxlen; // DNS packet buffer maximum length + int type; // type of query: A, AAAA, PTR, SRV... + uint16_t last_type; // last type received uint32_t sd_gen; DNSServiceRef sd; DNSServiceFlags flags; DNSServiceErrorType error; - int kq; // kqueue to notify when callback received + int kq; // kqueue to notify when callback received } mdns_query_context_t; static void _mdns_query_callback(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char *, uint16_t, uint16_t, uint16_t, const void *, uint32_t, void *); -/* _mdns_query_start +/* + * _mdns_query_start * initializes the context and starts a DNS-SD query. */ static DNSServiceErrorType @@ -1026,8 +1154,9 @@ _mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answe memset(ctx, 0, sizeof(mdns_query_context_t)); - if (answer && anslen) { - // build a dummy DNS header to return to the caller + if ((answer != NULL) && (anslen != NULL)) + { + /* build a dummy DNS header to return to the caller */ ctx->answer = answer; ctx->ansmaxlen = *anslen; ctx->anslen = _mdns_make_query(name, class, type, answer, ctx->ansmaxlen); @@ -1038,7 +1167,9 @@ _mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answe ctx->sd = _mdns_sdref; ctx->sd_gen = _mdns_generation; ctx->kq = kq; - if (reply) { + + if (reply != NULL) + { ctx->reply = reply; if (type == ns_t_a) ctx->host = reply->h4; else if (type == ns_t_aaaa) ctx->host = reply->h6; @@ -1064,74 +1195,83 @@ _mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answe if (iface2 != 0) iface = iface2; } - _mdns_debug_message(";; mdns query %s %d %d [ctx %p]\n", qname, type, class, ctx); + _mdns_debug_message(";; mdns query %s type %d class %d [ctx %p]\n", qname, type, class, ctx); status = DNSServiceQueryRecord(&ctx->sd, flags, iface, qname, type, class, _mdns_query_callback, ctx); if (qname != name) free(qname); return status; } -/* _mdns_query_is_complete +/* + * _mdns_query_is_complete * Determines whether the specified query has sufficient information to be * considered complete. */ -static int +static bool _mdns_query_is_complete(mdns_query_context_t *ctx) { - int complete = 0; + bool complete = false; /* NULL context is an error, but we call it complete */ - if (ctx == NULL) return 1; + if (ctx == NULL) return true; /* * The default is to ignore kDNSServiceFlagsMoreComing, since it has either * never been supported or worked correctly. MDNS_DEBUG_MORE makes us honor it. */ - if (ctx->flags & kDNSServiceFlagsMoreComing) { - if (_mdns_debug & MDNS_DEBUG_MORE) { + if (ctx->flags & kDNSServiceFlagsMoreComing) + { + if (_mdns_debug & MDNS_DEBUG_MORE) + { _mdns_debug_message(";; mdns is_complete type %d ctx %p more coming - incomplete\n", ctx->type, ctx); - return 0; + return false; } } - if (ctx->last_type != ctx->type) { + if (ctx->last_type != ctx->type) + { _mdns_debug_message(";; mdns is_complete ctx %p type mismatch (%d != %d) - incomplete\n", ctx, ctx->last_type, ctx->type); - return 0; + return false; } - switch (ctx->type) { + switch (ctx->type) + { case ns_t_a: case ns_t_aaaa: - if (ctx->host != NULL && ctx->host->addr_count > 0) complete = 1; + if (ctx->host != NULL && ctx->host->addr_count > 0) complete = true; break; case ns_t_ptr: - if (ctx->host != NULL && ctx->host->host.h_name != NULL) complete = 1; + if (ctx->host != NULL && ctx->host->host.h_name != NULL) complete = true; break; case ns_t_srv: - if (ctx->reply != NULL && ctx->reply->srv != NULL) complete = 1; + if (ctx->reply != NULL && ctx->reply->srv != NULL) complete = true; break; default: _mdns_debug_message(";; mdns is_complete unexpected type %d ctx %p\n", ctx->type, ctx); } - _mdns_debug_message(";; mdns is_complete type %d ctx %p %s%scomplete\n", ctx->type, ctx, (ctx->flags & kDNSServiceFlagsMoreComing) ? "(more coming flag ignored)" : "", (complete == 0) ? " - in" : " - "); + _mdns_debug_message(";; mdns is_complete type %d ctx %p %s%scomplete\n", ctx->type, ctx, (ctx->flags & kDNSServiceFlagsMoreComing) ? "(more coming flag ignored)" : "", complete ? " - " : " - in"); return complete; } -/* _mdns_query_clear +/* + * _mdns_query_clear * Clear out the temporary fields of the context, and clear any result * structures that are incomplete. Retrns 1 if the query was complete. */ -static int +static bool _mdns_query_clear(mdns_query_context_t *ctx) { - int complete = _mdns_query_is_complete(ctx); + bool complete = _mdns_query_is_complete(ctx); + if (ctx == NULL) return complete; - if (ctx->sd != NULL) { + if (ctx->sd != NULL) + { /* only dealloc this DNSServiceRef if the "main" _mdns_sdref has not been deallocated */ - if (ctx->sd != NULL && ctx->sd_gen == _mdns_generation) { + if (ctx->sd != NULL && ctx->sd_gen == _mdns_generation) + { DNSServiceRefDeallocate(ctx->sd); } } @@ -1141,7 +1281,8 @@ _mdns_query_clear(mdns_query_context_t *ctx) ctx->flags = 0; ctx->kq = -1; - if (complete == 0) { + if (!complete) + { _mdns_hostent_clear(ctx->host); ctx->anslen = -1; } @@ -1161,48 +1302,55 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde context->error = errorCode; context->last_type = rrtype; - if (errorCode != kDNSServiceErr_NoError) { - _mdns_debug_message(";; [%s %hu %hu]: error %d [ctx %p]\n", fullname, rrtype, rrclass, errorCode, context); + if (errorCode != kDNSServiceErr_NoError) + { + _mdns_debug_message(";; [%s type %hu class %hu]: error %d [ctx %p]\n", fullname, rrtype, rrclass, errorCode, context); goto wakeup_kevent; } - // embed the scope ID into link-local IPv6 addresses - if (rrtype == ns_t_aaaa && rdlen == sizeof(struct in6_addr) && - IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)rdata)) { + /* embed the scope ID into link-local IPv6 addresses */ + if ((rrtype == ns_t_aaaa) && (rdlen == sizeof(struct in6_addr)) && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)rdata)) + { memcpy(&a6, rdata, rdlen); a6.__u6_addr.__u6_addr16[1] = htons(ifIndex); rdata = &a6; } - if (context->reply) { + if (context->reply != NULL) + { char *name; int malformed = 0; mdns_reply_t *reply = context->reply; - if (reply->ifnum == 0) { - reply->ifnum = ifIndex; - } + if (reply->ifnum == 0) reply->ifnum = ifIndex; _mdns_hostent_append_alias(context->host, fullname); - if (reply->ttl == 0 || ttl < reply->ttl) reply->ttl = ttl; + if ((reply->ttl == 0) || (ttl < reply->ttl)) reply->ttl = ttl; - switch (rrtype) { + switch (rrtype) + { case ns_t_a: case ns_t_aaaa: - if (((rrtype == ns_t_a && context->host->host.h_addrtype == AF_INET) || - (rrtype == ns_t_aaaa && context->host->host.h_addrtype == AF_INET6)) && - rdlen >= context->host->host.h_length) { - if (context->host->host.h_name == NULL) { + { + if ((context->host != NULL) && + ((((rrtype == ns_t_a) && (context->host->host.h_addrtype == AF_INET)) || ((rrtype == ns_t_aaaa) && (context->host->host.h_addrtype == AF_INET6))) && + (rdlen >= context->host->host.h_length))) + { + if (context->host->host.h_name == NULL) + { int i; mdns_hostent_t *h = context->host; char *h_name = _mdns_canonicalize(fullname); context->host->host.h_name = h_name; - // 6863416 remove h_name from h_aliases - for (i = 0; i < h->alias_count; ++i) { + /* 6863416 remove h_name from h_aliases */ + for (i = 0; i < h->alias_count; ++i) + { if (h_name == NULL) break; - if (string_equal(h->host.h_aliases[i], h_name)) { - // includes trailing NULL pointer + + if (string_equal(h->host.h_aliases[i], h_name)) + { + /* includes trailing NULL pointer */ int sz = sizeof(char *) * (h->alias_count - i); free(h->host.h_aliases[i]); memmove(&h->host.h_aliases[i], &h->host.h_aliases[i+1], sz); @@ -1211,86 +1359,121 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde } } } + _mdns_hostent_append_addr(context->host, rdata, context->host->host.h_length); - } else { + } + else + { malformed = 1; } + break; + } case ns_t_cname: + { name = _mdns_parse_domain_name(rdata, rdlen); - if (!name) malformed = 1; + if (name == NULL) malformed = 1; + _mdns_hostent_append_alias(context->host, name); - _mdns_debug_message(";; [%s %hu %hu] cname %s [ctx %p]\n", fullname, rrtype, rrclass, name, context); + _mdns_debug_message(";; [%s type %hu class %hu] cname %s [ctx %p]\n", fullname, rrtype, rrclass, name, context); free(name); break; + } case ns_t_ptr: + { name = _mdns_parse_domain_name(rdata, rdlen); - if (!name) malformed = 1; - if (context->host && context->host->host.h_name == NULL) { + if (name == NULL) malformed = 1; + + if ((context->host != NULL) && (context->host->host.h_name == NULL)) + { context->host->host.h_name = _mdns_canonicalize(name); } + _mdns_hostent_append_alias(context->host, name); free(name); break; - case ns_t_srv: { - mdns_rr_srv_t *p = (mdns_rr_srv_t*)rdata; + } + case ns_t_srv: + { + mdns_rr_srv_t *p = (mdns_rr_srv_t *)rdata; mdns_srv_t *srv = calloc(1, sizeof(mdns_srv_t)); if (srv == NULL) break; - if (rdlen < sizeof(mdns_rr_srv_t)) { + + if (rdlen < sizeof(mdns_rr_srv_t)) + { malformed = 1; break; } + srv->srv.priority = ntohs(p->priority); srv->srv.weight = ntohs(p->weight); srv->srv.port = ntohs(p->port); srv->srv.target = _mdns_parse_domain_name(&p->target[0], rdlen - 3*sizeof(uint16_t)); - if (srv->srv.target == NULL) { + + if (srv->srv.target == NULL) + { malformed = 1; break; } - // append to the end of the list - if (reply->srv == NULL) { + + /* append to the end of the list */ + if (reply->srv == NULL) + { reply->srv = srv; - } else { + } + else + { mdns_srv_t *iter = reply->srv; while (iter->next) iter = iter->next; iter->next = srv; } + break; } default: + { malformed = _mdns_debug; break; + } } - if (malformed != 0) { - _mdns_debug_message(";; [%s %hu %hu]: malformed reply [ctx %p]\n", fullname, rrtype, rrclass, context); + + if (malformed != 0) + { + _mdns_debug_message(";; [%s type %hu class %hu]: malformed reply [ctx %p]\n", fullname, rrtype, rrclass, context); goto wakeup_kevent; } } - if (context->answer) { + if (context->answer != NULL) + { int n; uint8_t *cp; HEADER *ans; size_t buflen = context->ansmaxlen - context->anslen; - if (buflen < NS_HFIXEDSZ) { - _mdns_debug_message(";; [%s %hu %hu]: malformed reply (too small) [ctx %p]\n", fullname, rrtype, rrclass, context); + + if (buflen < NS_HFIXEDSZ) + { + _mdns_debug_message(";; [%s type %hu class %hu]: malformed reply (too small) [ctx %p]\n", fullname, rrtype, rrclass, context); goto wakeup_kevent; } cp = context->answer + context->anslen; n = _mdns_pack_domain_name(fullname, cp, buflen); - if (n < 0) { - _mdns_debug_message(";; [%s %hu %hu]: name mismatch [ctx %p]\n", fullname, rrtype, rrclass, context); + if (n < 0) + { + _mdns_debug_message(";; [%s type %hu class %hu]: name mismatch [ctx %p]\n", fullname, rrtype, rrclass, context); goto wakeup_kevent; } - // check that there is enough space in the buffer for the - // resource name (n), the resource record data (rdlen) and - // the resource record header (10). - if (buflen < n + rdlen + 10) { - _mdns_debug_message(";; [%s %hu %hu]: insufficient buffer space for reply [ctx %p]\n", fullname, rrtype, rrclass, context); + /* + * check that there is enough space in the buffer for the + * resource name (n), the resource record data (rdlen) and + * the resource record header (10). + */ + if (buflen < (n + rdlen + 10)) + { + _mdns_debug_message(";; [%s type %hu class %hu]: insufficient buffer space for reply [ctx %p]\n", fullname, rrtype, rrclass, context); goto wakeup_kevent; } @@ -1325,11 +1508,13 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde context->anslen = (size_t)(cp - context->answer); } - _mdns_debug_message(";; [%s %hu %hu] reply [ctx %p]\n", fullname, rrtype, rrclass, context); + _mdns_debug_message(";; [%s type %hu class %hu] reply [ctx %p]\n", fullname, rrtype, rrclass, context); wakeup_kevent: - // Ping the waiting thread in case this callback was invoked on another - if (context->kq != -1) { + + /* Ping the waiting thread in case this callback was invoked on another */ + if (context->kq != -1) + { struct kevent ev; EV_SET(&ev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, 0); int res = kevent(context->kq, &ev, 1, NULL, 0, NULL); @@ -1338,7 +1523,8 @@ wakeup_kevent: } static void -_mdns_now(struct timespec *now) { +_mdns_now(struct timespec *now) +{ struct timeval tv; gettimeofday(&tv, NULL); now->tv_sec = tv.tv_sec; @@ -1350,13 +1536,15 @@ _mdns_add_time(struct timespec *sum, const struct timespec *a, const struct time { sum->tv_sec = a->tv_sec + b->tv_sec; sum->tv_nsec = a->tv_nsec + b->tv_nsec; - if (sum->tv_nsec > 1000000000) { + + if (sum->tv_nsec > 1000000000) + { sum->tv_sec += (sum->tv_nsec / 1000000000); sum->tv_nsec %= 1000000000; } } -// calculate a deadline from the current time based on the desired timeout +/* calculate a deadline from the current time based on the desired timeout */ static void _mdns_deadline(struct timespec *deadline, const struct timespec *delta) { @@ -1370,13 +1558,15 @@ _mdns_sub_time(struct timespec *delta, const struct timespec *a, const struct ti { delta->tv_sec = a->tv_sec - b->tv_sec; delta->tv_nsec = a->tv_nsec - b->tv_nsec; - if (delta->tv_nsec < 0) { + + if (delta->tv_nsec < 0) + { delta->tv_nsec += 1000000000; delta->tv_sec -= 1; } } -// calculate a timeout remaining before the given deadline +/* calculate a timeout remaining before the given deadline */ static void _mdns_timeout(struct timespec *timeout, const struct timespec *deadline) { @@ -1389,131 +1579,135 @@ int _mdns_search(const char *name, int class, int type, const char *interface, DNSServiceFlags flags, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply) { DNSServiceErrorType err = 0; - int kq, n, wait = 1; + int kq, n; struct kevent ev; struct timespec start, finish, delta, timeout; int res = 0; - int i, complete, got_a_response = 0; - int initialize = 1; + int i, got_a_response = 0; + bool complete, initialize = true; + bool wait = true; uint32_t n_iface_4 = 0; - // determine number of IPv4 interfaces (ignore loopback) + /* determine number of IPv4 interfaces (ignore loopback) */ si_inet_config(&n_iface_4, NULL); if (n_iface_4 > 0) n_iface_4--; - // limit the number of initialization retries + /* limit the number of initialization retries */ int initialize_retries = 3; - // 2 for A and AAAA parallel queries + /* 2 for A and AAAA parallel queries */ int n_ctx = 0; mdns_query_context_t ctx[2]; if (name == NULL) return -1; #if TARGET_OS_EMBEDDED - // log a warning for queries from the main thread + /* log a warning for queries from the main thread */ if (pthread_is_threaded_np() && pthread_main_np()) asl_log(NULL, NULL, ASL_LEVEL_WARNING, "Warning: Libinfo call to mDNSResponder on main thread"); -#endif // TARGET_OS_EMBEDDED - - // Timeout Logic - // The kevent(2) API timeout parameter is used to enforce the total - // timeout of the DNS query. Each iteraion recalculates the relative - // timeout based on the desired end time (total timeout from origin). - // - // In order to workaround some DNS configurations that do not return - // responses for AAAA queries, parallel queries modify the total - // timeout upon receipt of the first response. The new total timeout is - // set to an effective value of 2N where N is the time taken to receive - // the A response (the original total timeout is preserved if 2N would - // have exceeded it). However, since mDNSResponder caches values, a - // minimum value of 50ms for N is enforced in order to give some time - // for the receipt of a AAAA response. - - // determine the maximum time to wait for a result +#endif /* TARGET_OS_EMBEDDED */ + + /* + * Timeout Logic + * The kevent(2) API timeout parameter is used to enforce the total + * timeout of the DNS query. Each iteraion recalculates the relative + * timeout based on the desired end time (total timeout from origin). + * + * In order to workaround some DNS configurations that do not return + * responses for AAAA queries, parallel queries modify the total + * timeout upon receipt of the first response. The new total timeout is + * set to an effective value of 2N where N is the time taken to receive + * the A response (the original total timeout is preserved if 2N would + * have exceeded it). However, since mDNSResponder caches values, a + * minimum value of 50ms for N is enforced in order to give some time + * for the receipt of a AAAA response. + */ + + /* determine the maximum time to wait for a result */ delta.tv_sec = RES_MAXRETRANS + 5; delta.tv_nsec = 0; _mdns_deadline(&finish, &delta); timeout = delta; _mdns_now(&start); - for (i = 0; i < 2; ++i) { - memset(&ctx[i], 0 , sizeof(mdns_query_context_t)); - } + for (i = 0; i < 2; ++i) memset(&ctx[i], 0 , sizeof(mdns_query_context_t)); - // set up the kqueue + /* set up the kqueue */ kq = kqueue(); EV_SET(&ev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, 0); n = kevent(kq, &ev, 1, NULL, 0, NULL); - if (n != 0) wait = 0; + if (n != 0) wait = false; - while (wait == 1) { - if (initialize) { - initialize = 0; + while (wait) + { + if (initialize) + { + initialize = false; pthread_mutex_lock(&_mdns_mutex); - // clear any stale contexts - for (i = 0; i < n_ctx; ++i) { - _mdns_query_clear(&ctx[i]); - } + + /* clear any stale contexts */ + for (i = 0; i < n_ctx; ++i) _mdns_query_clear(&ctx[i]); n_ctx = 0; - if (_mdns_sdref == NULL) { - if (_mdns_old_sdref != NULL) { + if (_mdns_sdref == NULL) + { + if (_mdns_old_sdref != NULL) + { _mdns_generation++; DNSServiceRefDeallocate(_mdns_old_sdref); _mdns_old_sdref = NULL; } - // (re)initialize the shared connection + + /* (re)initialize the shared connection */ err = DNSServiceCreateConnection(&_mdns_sdref); - // limit the number of retries - if (initialize_retries-- <= 0 && err == 0) { - err = kDNSServiceErr_Unknown; - } - if (err != 0) { - wait = 0; + /* limit the number of retries */ + if ((initialize_retries-- <= 0) && (err == 0)) err = kDNSServiceErr_Unknown; + if (err != 0) + { + wait = false; pthread_mutex_unlock(&_mdns_mutex); break; } } - // issue (or reissue) the queries - // unspecified type: do parallel A and AAAA - if (err == 0) { - err = _mdns_query_start(&ctx[n_ctx++], reply, - answer, anslen, - name, class, - (type == 0) ? ns_t_a : type, interface, flags, kq); + /* + * issue (or reissue) the queries + * unspecified type: do parallel A and AAAA + */ + if (err == 0) + { + err = _mdns_query_start(&ctx[n_ctx++], reply, answer, anslen, name, class, (type == 0) ? ns_t_a : type, interface, flags, kq); } - if (err == 0 && type == 0) { - err = _mdns_query_start(&ctx[n_ctx++], reply, - answer, anslen, - name, class, ns_t_aaaa, interface, flags, kq); + if ((err == 0) && (type == 0)) + { + err = _mdns_query_start(&ctx[n_ctx++], reply, answer, anslen, name, class, ns_t_aaaa, interface, flags, kq); } - if (err != 0) { - _mdns_debug_message(";; initialization error %d\n", err); - } + if (err != 0) _mdns_debug_message(";; initialization error %d\n", err); - // try to reinitialize - if (err == kDNSServiceErr_Unknown || - err == kDNSServiceErr_ServiceNotRunning || - err == kDNSServiceErr_BadReference) { - if (_mdns_sdref) { + /* try to reinitialize */ + if ((err == kDNSServiceErr_Unknown) || (err == kDNSServiceErr_ServiceNotRunning) || (err == kDNSServiceErr_BadReference)) + { + if (_mdns_sdref != NULL) + { _mdns_generation++; DNSServiceRefDeallocate(_mdns_sdref); _mdns_sdref = NULL; } + err = 0; - initialize = 1; + initialize = true; pthread_mutex_unlock(&_mdns_mutex); continue; - } else if (err != 0) { + } + else if (err != 0) + { pthread_mutex_unlock(&_mdns_mutex); break; } - // (re)register the fd with kqueue + /* (re)register the fd with kqueue */ int fd = DNSServiceRefSockFD(_mdns_sdref); EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0); n = kevent(kq, &ev, 1, NULL, 0, NULL); @@ -1524,116 +1718,144 @@ _mdns_search(const char *name, int class, int type, const char *interface, DNSSe _mdns_debug_message(";; set kevent timeout %ld.%ld [ctx %p %p]\n", timeout.tv_sec, timeout.tv_nsec, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); n = kevent(kq, NULL, 0, &ev, 1, &timeout); - if (n < 0 && errno != EINTR) { + if ((n < 0) && (errno != EINTR)) + { res = -1; break; } pthread_mutex_lock(&_mdns_mutex); - // DNSServiceProcessResult() is a blocking API - // confirm that there is still data on the socket + + /* + * DNSServiceProcessResult() is a blocking API + * confirm that there is still data on the socket + */ const struct timespec notimeout = { 0, 0 }; int m = kevent(kq, NULL, 0, &ev, 1, ¬imeout); - if (_mdns_sdref == NULL) { - initialize = 1; - } else if (m > 0 && ev.filter == EVFILT_READ) { + + if (_mdns_sdref == NULL) + { + initialize = true; + } + else if (m > 0 && ev.filter == EVFILT_READ) + { err = DNSServiceProcessResult(_mdns_sdref); - if (err == kDNSServiceErr_ServiceNotRunning || - err == kDNSServiceErr_BadReference) { + if ((err == kDNSServiceErr_ServiceNotRunning) || (err == kDNSServiceErr_BadReference)) + { _mdns_debug_message(";; DNSServiceProcessResult status %d [ctx %p %p]\n", err, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); err = 0; - // re-initialize the shared connection + + /* re-initialize the shared connection */ _mdns_generation++; DNSServiceRefDeallocate(_mdns_sdref); _mdns_sdref = NULL; - initialize = 1; + initialize = true; } } - // Check if all queries are complete (including errors) - complete = 1; - for (i = 0; i < n_ctx; ++i) { - if ((ctx[i].error != 0) || _mdns_query_is_complete(&ctx[i])) { - if (ctx[i].type == ns_t_a) { + /* Check if all queries are complete (including errors) */ + complete = true; + for (i = 0; i < n_ctx; ++i) + { + if ((ctx[i].error != 0) || _mdns_query_is_complete(&ctx[i])) + { + if (ctx[i].type == ns_t_a) + { got_a_response = GOT_DATA; if (ctx[i].error != 0) got_a_response = GOT_ERROR; } - _mdns_debug_message(";; [%s %d %d] finished processing ctx %p\n", name, class, type, &(ctx[i])); - } else { - _mdns_debug_message(";; [%s %d %d] continuing ctx %p\n", name, class, type, &(ctx[i])); - complete = 0; + _mdns_debug_message(";; [%s type %d class %d] finished processing ctx %p\n", name, type, class, &(ctx[i])); + } + else + { + _mdns_debug_message(";; [%s type %d class %d] continuing ctx %p\n", name, type, class, &(ctx[i])); + complete = false; } } + pthread_mutex_unlock(&_mdns_mutex); - if (err != 0) { + if (err != 0) + { _mdns_debug_message(";; DNSServiceProcessResult error status %d [ctx %p %p]\n", err, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); break; - } else if (complete == 1) { - _mdns_debug_message(";; [%s %d %d] done [ctx %p %p]\n", name, class, type, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); + } + else if (complete) + { + _mdns_debug_message(";; [%s type %d class %d] done [ctx %p %p]\n", name, type, class, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); break; - } else if (got_a_response != 0) { - // got A, adjust deadline for AAAA + } + else if (got_a_response != 0) + { + /* got A, adjust deadline for AAAA */ struct timespec now, tn, extra; - // delta = now - start + /* delta = now - start */ _mdns_now(&now); _mdns_sub_time(&delta, &now, &start); extra.tv_sec = SHORT_AAAA_EXTRA; extra.tv_nsec = 0; - // if delta is small (<= 20 milliseconds), we probably got a result from mDNSResponder's cache - if ((delta.tv_sec == 0) && (delta.tv_nsec <= 20000000)) { + /* if delta is small (<= 20 milliseconds), we probably got a result from mDNSResponder's cache */ + if ((delta.tv_sec == 0) && (delta.tv_nsec <= 20000000)) + { extra.tv_sec = MEDIUM_AAAA_EXTRA; } - else if (n_iface_4 == 0) { + else if (n_iface_4 == 0) + { extra.tv_sec = LONG_AAAA_EXTRA; - } else if (got_a_response == GOT_ERROR) { + } + else if (got_a_response == GOT_ERROR) + { extra.tv_sec = MEDIUM_AAAA_EXTRA; } - // tn = 2 * delta + /* tn = 2 * delta */ _mdns_add_time(&tn, &delta, &delta); - // delta = tn + extra + /* delta = tn + extra */ _mdns_add_time(&delta, &tn, &extra); - // check that delta doesn't exceed our total timeout + /* check that delta doesn't exceed our total timeout */ _mdns_sub_time(&tn, &timeout, &delta); - if (tn.tv_sec >= 0) { - _mdns_debug_message(";; new timeout [%s %d %d] (waiting for AAAA) %ld.%ld [ctx %p %p]\n", name, class, type, delta.tv_sec, delta.tv_nsec, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); + if (tn.tv_sec >= 0) + { + _mdns_debug_message(";; new timeout [%s type %d class %d] (waiting for AAAA) %ld.%ld [ctx %p %p]\n", name, type, class, delta.tv_sec, delta.tv_nsec, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); _mdns_deadline(&finish, &delta); } } - // calculate remaining timeout + /* calculate remaining timeout */ _mdns_timeout(&timeout, &finish); - // check for time remaining - if (timeout.tv_sec < 0) { - _mdns_debug_message(";; [%s %d %d] timeout [ctx %p %p]\n", name, class, type, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); + /* check for time remaining */ + if (timeout.tv_sec < 0) + { + _mdns_debug_message(";; [%s type %d class %d] timeout [ctx %p %p]\n", name, type, class, (n_ctx > 0) ? &(ctx[0]) : NULL, (n_ctx > 1) ? &(ctx[1]) : NULL); break; } } - complete = 0; + complete = false; pthread_mutex_lock(&_mdns_mutex); - for (i = 0; i < n_ctx; ++i) { + + for (i = 0; i < n_ctx; ++i) + { if (err == 0) err = ctx[i].error; - // Only clears hostents if result is incomplete. - complete = _mdns_query_clear(&ctx[i]) || complete; + /* only clears hostents if result is incomplete */ + complete = _mdns_query_clear(&ctx[i]) | complete; } + pthread_mutex_unlock(&_mdns_mutex); - // Everything should be done with the kq by now. + + /* everything should be done with the kq by now */ close(kq); - // Return error if everything is incomplete - if (complete == 0) { - res = -1; - } + /* return error if everything is incomplete */ + if (!complete) res = -1; - if (anslen) *anslen = ctx[0].anslen; + if (anslen != NULL) *anslen = ctx[0].anslen; return res; } -- 2.7.4