* 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,
* 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@
*/
/*
/*
* 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:
* 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
*/
/*
* 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
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;
} 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;
{
va_list v;
char *out = NULL;
+
+ if (str == NULL) return;
if ((_mdns_debug & MDNS_DEBUG_OUT) == 0) return;
va_start(v, str);
x[64] = '\0';
j = 63;
+
for (i = 0; i < 16; i++)
{
d = addr[i];
return p;
}
-/* _mdns_canonicalize
+/*
+ * _mdns_canonicalize
* Canonicalize the domain name by converting to lower case and removing the
* trailing '.' if present.
*/
{
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
{
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;
}
_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);
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;
}
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;
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;
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;
_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;
}
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;
}
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;
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;
_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;
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)
{
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));
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;
}
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);
srv = srv->next;
}
}
+
_mdns_reply_clear(&reply);
return out;
}
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));
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;
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);
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);
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;
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;
* 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;
}
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.
*/
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;
{
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;
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
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);
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;
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);
}
}
ctx->flags = 0;
ctx->kq = -1;
- if (complete == 0) {
+ if (!complete)
+ {
_mdns_hostent_clear(ctx->host);
ctx->anslen = -1;
}
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);
}
}
}
+
_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;
}
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);
}
static void
-_mdns_now(struct timespec *now) {
+_mdns_now(struct timespec *now)
+{
struct timeval tv;
gettimeofday(&tv, NULL);
now->tv_sec = tv.tv_sec;
{
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)
{
{
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)
{
_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--;
- // <rdar://problem/7732497> limit the number of initialization retries
+ /* <rdar://problem/7732497> 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);
_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;
}