/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1.  Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <errno.h>
#include <stdlib.h>

#include "dnssd_ipc.h"

static int gDaemonErr = kDNSServiceErr_NoError;

#if defined(_WIN32)

	#define _SSIZE_T
	#include <CommonServices.h>
	#include <DebugServices.h>
	#include <winsock2.h>
	#include <ws2tcpip.h>
	#include <windows.h>
	#include <stdarg.h>
	
	#define sockaddr_mdns sockaddr_in
	#define AF_MDNS AF_INET
	
	// Disable warning: "'type cast' : from data pointer 'void *' to function pointer"
	#pragma warning(disable:4055)
	
	// Disable warning: "nonstandard extension, function/data pointer conversion in expression"
	#pragma warning(disable:4152)
	
	extern BOOL IsSystemServiceDisabled();
	
	#define sleep(X) Sleep((X) * 1000)
	
	static int g_initWinsock = 0;
	#define LOG_WARNING kDebugLevelWarning
	#define LOG_INFO kDebugLevelInfo
	static void syslog( int priority, const char * message, ...)
		{
		va_list args;
		int len;
		char * buffer;
		DWORD err = WSAGetLastError();
		(void) priority;
		va_start( args, message );
		len = _vscprintf( message, args ) + 1;
		buffer = malloc( len * sizeof(char) );
		if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugString( buffer ); free( buffer ); }
		WSASetLastError( err );
		}
#else

	#include <sys/fcntl.h>		// For O_RDWR etc.
	#include <sys/time.h>
	#include <sys/socket.h>
	#include <syslog.h>
	
	#define sockaddr_mdns sockaddr_un
	#define AF_MDNS AF_LOCAL

#endif

// <rdar://problem/4096913> Specifies how many times we'll try and connect to the server.

#define DNSSD_CLIENT_MAXTRIES 4

// Uncomment the line below to use the old error return mechanism of creating a temporary named socket (e.g. in /var/tmp)
//#define USE_NAMED_ERROR_RETURN_SOCKET 1

#define DNSSD_CLIENT_TIMEOUT 10  // In seconds

#ifndef CTL_PATH_PREFIX
#define CTL_PATH_PREFIX "/var/tmp/dnssd_result_socket."
#endif

typedef struct
	{
	ipc_msg_hdr         ipc_hdr;
	DNSServiceFlags     cb_flags;
	uint32_t            cb_interface;
	DNSServiceErrorType cb_err;
	} CallbackHeader;

typedef struct _DNSServiceRef_t DNSServiceOp;
typedef struct _DNSRecordRef_t DNSRecord;

// client stub callback to process message from server and deliver results to client application
typedef void (*ProcessReplyFn)(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *msg, const char *const end);

#define ValidatorBits 0x12345678
#define DNSServiceRefValid(X) (dnssd_SocketValid((X)->sockfd) && (((X)->sockfd ^ (X)->validator) == ValidatorBits))

// When using kDNSServiceFlagsShareConnection, there is one primary _DNSServiceOp_t, and zero or more subordinates
// For the primary, the 'next' field points to the first subordinate, and its 'next' field points to the next, and so on.
// For the primary, the 'primary' field is NULL; for subordinates the 'primary' field points back to the associated primary
//
// _DNS_SD_LIBDISPATCH is defined where libdispatch/GCD is available. This does not mean that the application will use the
// DNSServiceSetDispatchQueue API. Hence any new code guarded with _DNS_SD_LIBDISPATCH should still be backwards compatible.
struct _DNSServiceRef_t
	{
	DNSServiceOp     *next;				// For shared connection
	DNSServiceOp     *primary;			// For shared connection
	dnssd_sock_t      sockfd;			// Connected socket between client and daemon
	dnssd_sock_t      validator;		// Used to detect memory corruption, double disposals, etc.
	client_context_t  uid;				// For shared connection requests, each subordinate DNSServiceRef has its own ID,
										// unique within the scope of the same shared parent DNSServiceRef
	uint32_t          op;				// request_op_t or reply_op_t
	uint32_t          max_index;		// Largest assigned record index - 0 if no additional records registered
	uint32_t          logcounter;		// Counter used to control number of syslog messages we write
	int              *moreptr;			// Set while DNSServiceProcessResult working on this particular DNSServiceRef
	ProcessReplyFn    ProcessReply;		// Function pointer to the code to handle received messages
	void             *AppCallback;		// Client callback function and context
	void             *AppContext;
	DNSRecord        *rec;
#if _DNS_SD_LIBDISPATCH
	dispatch_source_t disp_source;
	dispatch_queue_t  disp_queue;
#endif
	};

struct _DNSRecordRef_t
	{
	DNSRecord		*recnext;
	void *AppContext;
	DNSServiceRegisterRecordReply AppCallback;
	DNSRecordRef recref;
	uint32_t record_index;  // index is unique to the ServiceDiscoveryRef
	DNSServiceOp *sdr;
	};

// Write len bytes. Return 0 on success, -1 on error
static int write_all(dnssd_sock_t sd, char *buf, size_t len)
	{
	// Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
	//if (send(sd, buf, len, MSG_WAITALL) != len) return -1;
	while (len)
		{
		ssize_t num_written = send(sd, buf, (long)len, 0);
		if (num_written < 0 || (size_t)num_written > len)
			{
			// Should never happen. If it does, it indicates some OS bug,
			// or that the mDNSResponder daemon crashed (which should never happen).
			#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
			int defunct;
			socklen_t dlen = sizeof (defunct);
			if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
				syslog(LOG_WARNING, "dnssd_clientstub write_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
			if (!defunct)
				syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
					(long)num_written, (long)len,
					(num_written < 0) ? dnssd_errno                 : 0,
					(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
			else
				syslog(LOG_INFO, "dnssd_clientstub write_all(%d) DEFUNCT", sd);
			#else
			syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
				(long)num_written, (long)len,
				(num_written < 0) ? dnssd_errno                 : 0,
				(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
			#endif
			return -1;
			}
		buf += num_written;
		len -= num_written;
		}
	return 0;
	}

enum { read_all_success = 0, read_all_fail = -1, read_all_wouldblock = -2 };

// Read len bytes. Return 0 on success, read_all_fail on error, or read_all_wouldblock for
static int read_all(dnssd_sock_t sd, char *buf, int len)
	{
	// Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
	//if (recv(sd, buf, len, MSG_WAITALL) != len) return -1;

	while (len)
		{
		ssize_t num_read = recv(sd, buf, len, 0);
		// It is valid to get an interrupted system call error e.g., somebody attaching
		// in a debugger, retry without failing
		if ((num_read < 0) && (errno == EINTR)) { syslog(LOG_INFO, "dnssd_clientstub read_all: EINTR continue"); continue; }
		if ((num_read == 0) || (num_read < 0) || (num_read > len))
			{
			int printWarn = 0;
			int defunct = 0;
			// Should never happen. If it does, it indicates some OS bug,
			// or that the mDNSResponder daemon crashed (which should never happen).
#if defined(WIN32)
			// <rdar://problem/7481776> Suppress logs for "A non-blocking socket operation
			//                          could not be completed immediately"
			if (WSAGetLastError() != WSAEWOULDBLOCK)
				printWarn = 1;
#endif
#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
			{
			socklen_t dlen = sizeof (defunct);
			if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
				syslog(LOG_WARNING, "dnssd_clientstub read_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
			}
			if (!defunct)
				printWarn = 1;
#endif
			if (printWarn)
				syslog(LOG_WARNING, "dnssd_clientstub read_all(%d) failed %ld/%ld %d %s", sd,
					(long)num_read, (long)len,
					(num_read < 0) ? dnssd_errno                 : 0,
					(num_read < 0) ? dnssd_strerror(dnssd_errno) : "");
			else if (defunct)
				syslog(LOG_INFO, "dnssd_clientstub read_all(%d) DEFUNCT", sd);
			return (num_read < 0 && dnssd_errno == dnssd_EWOULDBLOCK) ? read_all_wouldblock : read_all_fail;
			}
		buf += num_read;
		len -= num_read;
		}
	return read_all_success;
	}

// Returns 1 if more bytes remain to be read on socket descriptor sd, 0 otherwise
static int more_bytes(dnssd_sock_t sd)
	{
	struct timeval tv = { 0, 0 };
	fd_set readfds;
	fd_set *fs;
	int ret;

	if (sd < FD_SETSIZE)
		{
		fs = &readfds;
		FD_ZERO(fs);
		}
	else 
		{
		// Compute the number of integers needed for storing "sd". Internally fd_set is stored
		// as an array of ints with one bit for each fd and hence we need to compute
		// the number of ints needed rather than the number of bytes. If "sd" is 32, we need
		// two ints and not just one.
		int nfdbits = sizeof (int) * 8;
		int nints = (sd/nfdbits) + 1;
		fs = (fd_set *)calloc(nints, sizeof(int));
		if (fs == NULL) { syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed"); return 0; }
		}
	FD_SET(sd, fs);
	ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
	if (fs != &readfds) free(fs);
	return (ret > 0);
	}

// Wait for daemon to write to socket
static int wait_for_daemon(dnssd_sock_t sock, int timeout)
	{
#ifndef WIN32
	// At this point the next operation (accept() or read()) on this socket may block for a few milliseconds waiting
	// for the daemon to respond, but that's okay -- the daemon is a trusted service and we know if won't take more
	// than a few milliseconds to respond.  So we'll forego checking for readability of the socket.
	(void) sock;
	(void) timeout;
#else
	// Windows on the other hand suffers from 3rd party software (primarily 3rd party firewall software) that
	// interferes with proper functioning of the TCP protocol stack. Because of this and because we depend on TCP
	// to communicate with the system service, we want to make sure that the next operation on this socket (accept() or
	// read()) doesn't block indefinitely.
	if (!gDaemonErr)
		{
		struct timeval tv;
		fd_set set;

		FD_ZERO(&set);
		FD_SET(sock, &set);
		tv.tv_sec = timeout;
		tv.tv_usec = 0;
		if (!select((int)(sock + 1), &set, NULL, NULL, &tv))
			{
				syslog(LOG_WARNING, "dnssd_clientstub wait_for_daemon timed out");
				gDaemonErr = kDNSServiceErr_Timeout;
			}
		}
#endif
	return gDaemonErr;
	}

/* create_hdr
 *
 * allocate and initialize an ipc message header. Value of len should initially be the
 * length of the data, and is set to the value of the data plus the header. data_start
 * is set to point to the beginning of the data section. SeparateReturnSocket should be
 * non-zero for calls that can't receive an immediate error return value on their primary
 * socket, and therefore require a separate return path for the error code result.
 * if zero, the path to a control socket is appended at the beginning of the message buffer.
 * data_start is set past this string.
 */
static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int SeparateReturnSocket, DNSServiceOp *ref)
	{
	char *msg = NULL;
	ipc_msg_hdr *hdr;
	int datalen;
#if !defined(USE_TCP_LOOPBACK)
	char ctrl_path[64] = "";	// "/var/tmp/dnssd_result_socket.xxxxxxxxxx-xxx-xxxxxx"
#endif

	if (SeparateReturnSocket)
		{
#if defined(USE_TCP_LOOPBACK)
		*len += 2;  // Allocate space for two-byte port number
#elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
		struct timeval tv;
		if (gettimeofday(&tv, NULL) < 0)
			{ syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno)); return NULL; }
		sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
			(unsigned long)(tv.tv_sec & 0xFFF), (unsigned long)(tv.tv_usec));
		*len += strlen(ctrl_path) + 1;
#else
		*len += 1;		// Allocate space for single zero byte (empty C string)
#endif
		}

	datalen = (int) *len;
	*len += sizeof(ipc_msg_hdr);

	// Write message to buffer
	msg = malloc(*len);
	if (!msg) { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: malloc failed"); return NULL; }

	memset(msg, 0, *len);
	hdr = (ipc_msg_hdr *)msg;
	hdr->version                = VERSION;
	hdr->datalen                = datalen;
	hdr->ipc_flags              = 0;
	hdr->op                     = op;
	hdr->client_context         = ref->uid;
	hdr->reg_index              = 0;
	*data_start = msg + sizeof(ipc_msg_hdr);
#if defined(USE_TCP_LOOPBACK)
	// Put dummy data in for the port, since we don't know what it is yet.
	// The data will get filled in before we send the message. This happens in deliver_request().
	if (SeparateReturnSocket) put_uint16(0, data_start);
#else
	if (SeparateReturnSocket) put_string(ctrl_path, data_start);
#endif
	return hdr;
	}

static void FreeDNSRecords(DNSServiceOp *sdRef)
	{
	DNSRecord *rec = sdRef->rec;
	while (rec)
		{
		DNSRecord *next = rec->recnext;
		free(rec);
		rec = next;
		}
	}

static void FreeDNSServiceOp(DNSServiceOp *x)
	{
	// We don't use our DNSServiceRefValid macro here because if we're cleaning up after a socket() call failed
	// then sockfd could legitimately contain a failing value (e.g. dnssd_InvalidSocket)
	if ((x->sockfd ^ x->validator) != ValidatorBits)
		syslog(LOG_WARNING, "dnssd_clientstub attempt to dispose invalid DNSServiceRef %p %08X %08X", x, x->sockfd, x->validator);
	else
		{
		x->next         = NULL;
		x->primary      = NULL;
		x->sockfd       = dnssd_InvalidSocket;
		x->validator    = 0xDDDDDDDD;
		x->op           = request_op_none;
		x->max_index    = 0;
		x->logcounter   = 0;
		x->moreptr      = NULL;
		x->ProcessReply = NULL;
		x->AppCallback  = NULL;
		x->AppContext   = NULL;
#if _DNS_SD_LIBDISPATCH
		if (x->disp_source)	dispatch_release(x->disp_source);
		x->disp_source  = NULL;
		x->disp_queue   = NULL;
#endif
		// DNSRecords may have been added to subordinate sdRef e.g., DNSServiceRegister/DNSServiceAddRecord
		// or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiveRegisterRecord. DNSRecords may have
		// been freed if the application called DNSRemoveRecord
		FreeDNSRecords(x);
		free(x);
		}
	}

// Return a connected service ref (deallocate with DNSServiceRefDeallocate)
static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags flags, uint32_t op, ProcessReplyFn ProcessReply, void *AppCallback, void *AppContext)
	{
	#if APPLE_OSX_mDNSResponder
	int NumTries = DNSSD_CLIENT_MAXTRIES;
	#else
	int NumTries = 0;
	#endif

	dnssd_sockaddr_t saddr;
	DNSServiceOp *sdr;

	if (!ref) { syslog(LOG_WARNING, "dnssd_clientstub DNSService operation with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }

	if (flags & kDNSServiceFlagsShareConnection)
		{
		if (!*ref)
			{
			syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with NULL DNSServiceRef");
			return kDNSServiceErr_BadParam;
			}
		if (!DNSServiceRefValid(*ref) || (*ref)->op != connection_request || (*ref)->primary)
			{
			syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with invalid DNSServiceRef %p %08X %08X",
				(*ref), (*ref)->sockfd, (*ref)->validator);
			*ref = NULL;
			return kDNSServiceErr_BadReference;
			}
		}

	#if defined(_WIN32)
	if (!g_initWinsock)
		{
		WSADATA wsaData;
		g_initWinsock = 1;
		if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { *ref = NULL; return kDNSServiceErr_ServiceNotRunning; }
		}
	// <rdar://problem/4096913> If the system service is disabled, we only want to try to connect once
	if (IsSystemServiceDisabled()) NumTries = DNSSD_CLIENT_MAXTRIES;
	#endif

	sdr = malloc(sizeof(DNSServiceOp));
	if (!sdr) { syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: malloc failed"); *ref = NULL; return kDNSServiceErr_NoMemory; }
	sdr->next          = NULL;
	sdr->primary       = NULL;
	sdr->sockfd        = dnssd_InvalidSocket;
	sdr->validator     = sdr->sockfd ^ ValidatorBits;
	sdr->op            = op;
	sdr->max_index     = 0;
	sdr->logcounter    = 0;
	sdr->moreptr       = NULL;
	sdr->uid.u32[0]    = 0;
	sdr->uid.u32[1]    = 0;
	sdr->ProcessReply  = ProcessReply;
	sdr->AppCallback   = AppCallback;
	sdr->AppContext    = AppContext;
	sdr->rec           = NULL;
#if _DNS_SD_LIBDISPATCH
	sdr->disp_source   = NULL;
	sdr->disp_queue    = NULL;
#endif

	if (flags & kDNSServiceFlagsShareConnection)
		{
		DNSServiceOp **p = &(*ref)->next;		// Append ourselves to end of primary's list
		while (*p) p = &(*p)->next;
		*p = sdr;
		// Preincrement counter before we use it -- it helps with debugging if we know the all-zeroes ID should never appear
		if (++(*ref)->uid.u32[0] == 0) ++(*ref)->uid.u32[1];	// In parent DNSServiceOp increment UID counter
		sdr->primary    = *ref;					// Set our primary pointer
		sdr->sockfd     = (*ref)->sockfd;		// Inherit primary's socket
		sdr->validator  = (*ref)->validator;
		sdr->uid        = (*ref)->uid;
		//printf("ConnectToServer sharing socket %d\n", sdr->sockfd);
		}
	else
		{
		#ifdef SO_NOSIGPIPE
		const unsigned long optval = 1;
		#endif
		*ref = NULL;
		sdr->sockfd    = socket(AF_DNSSD, SOCK_STREAM, 0);
		sdr->validator = sdr->sockfd ^ ValidatorBits;
		if (!dnssd_SocketValid(sdr->sockfd))
			{
			syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: socket failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
			FreeDNSServiceOp(sdr);
			return kDNSServiceErr_NoMemory;
			}
		#ifdef SO_NOSIGPIPE
		// Some environments (e.g. OS X) support turning off SIGPIPE for a socket
		if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) < 0)
			syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_NOSIGPIPE failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
		#endif
		#if defined(USE_TCP_LOOPBACK)
		saddr.sin_family      = AF_INET;
		saddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
		saddr.sin_port        = htons(MDNS_TCP_SERVERPORT);
		#else
		saddr.sun_family      = AF_LOCAL;
		strcpy(saddr.sun_path, MDNS_UDS_SERVERPATH);
		#if !defined(__ppc__) && defined(SO_DEFUNCTOK)
		{
		int defunct = 1;
		if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_DEFUNCTOK, &defunct, sizeof(defunct)) < 0)
			syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_DEFUNCTOK failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
		}
		#endif	
		#endif
	
		while (1)
			{
			int err = connect(sdr->sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
			if (!err) break; // If we succeeded, return sdr
			// If we failed, then it may be because the daemon is still launching.
			// This can happen for processes that launch early in the boot process, while the
			// daemon is still coming up. Rather than fail here, we'll wait a bit and try again.
			// If, after four seconds, we still can't connect to the daemon,
			// then we give up and return a failure code.
			if (++NumTries < DNSSD_CLIENT_MAXTRIES) sleep(1); // Sleep a bit, then try again
			else { dnssd_close(sdr->sockfd); FreeDNSServiceOp(sdr); return kDNSServiceErr_ServiceNotRunning; }
			}
		//printf("ConnectToServer opened socket %d\n", sdr->sockfd);
		}

	*ref = sdr;
	return kDNSServiceErr_NoError;
	}

#define deliver_request_bailout(MSG) \
	do { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup; } while(0)

static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
	{
	uint32_t datalen = hdr->datalen;	// We take a copy here because we're going to convert hdr->datalen to network byte order
	#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
	char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
	#endif
	dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
	DNSServiceErrorType err = kDNSServiceErr_Unknown;	// Default for the "goto cleanup" cases
	int MakeSeparateReturnSocket = 0;

	// Note: need to check hdr->op, not sdr->op.
	// hdr->op contains the code for the specific operation we're currently doing, whereas sdr->op
	// contains the original parent DNSServiceOp (e.g. for an add_record_request, hdr->op will be
	// add_record_request but the parent sdr->op will be connection_request or reg_service_request)
	if (sdr->primary ||
		hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request)
		MakeSeparateReturnSocket = 1;

	if (!DNSServiceRefValid(sdr))
		{
		syslog(LOG_WARNING, "dnssd_clientstub deliver_request: invalid DNSServiceRef %p %08X %08X", sdr, sdr->sockfd, sdr->validator);
		return kDNSServiceErr_BadReference;
		}

	if (!hdr) { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr"); return kDNSServiceErr_Unknown; }

	if (MakeSeparateReturnSocket)
		{
		#if defined(USE_TCP_LOOPBACK)
			{
			union { uint16_t s; u_char b[2]; } port;
			dnssd_sockaddr_t caddr;
			dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
			listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
			if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("TCP socket");

			caddr.sin_family      = AF_INET;
			caddr.sin_port        = 0;
			caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
			if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) deliver_request_bailout("TCP bind");
			if (getsockname(listenfd, (struct sockaddr*) &caddr, &len)   < 0) deliver_request_bailout("TCP getsockname");
			if (listen(listenfd, 1)                                      < 0) deliver_request_bailout("TCP listen");
			port.s = caddr.sin_port;
			data[0] = port.b[0];  // don't switch the byte order, as the
			data[1] = port.b[1];  // daemon expects it in network byte order
			}
		#elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
			{
			mode_t mask;
			int bindresult;
			dnssd_sockaddr_t caddr;
			listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
			if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");

			caddr.sun_family = AF_LOCAL;
			// According to Stevens (section 3.2), there is no portable way to
			// determine whether sa_len is defined on a particular platform.
			#ifndef NOT_HAVE_SA_LEN
			caddr.sun_len = sizeof(struct sockaddr_un);
			#endif
			strcpy(caddr.sun_path, data);
			mask = umask(0);
			bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
			umask(mask);
			if (bindresult          < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
			if (listen(listenfd, 1) < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
			}
		#else
			{
			dnssd_sock_t sp[2];
			if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) deliver_request_bailout("socketpair");
			else
				{
				errsd    = sp[0];	// We'll read our four-byte error code from sp[0]
				listenfd = sp[1];	// We'll send sp[1] to the daemon
				#if !defined(__ppc__) && defined(SO_DEFUNCTOK)
				{
				int defunct = 1;
				if (setsockopt(errsd, SOL_SOCKET, SO_DEFUNCTOK, &defunct, sizeof(defunct)) < 0)
					syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_DEFUNCTOK failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
				}
				#endif	
				}
			}
		#endif
		}

#if !defined(USE_TCP_LOOPBACK) && !defined(USE_NAMED_ERROR_RETURN_SOCKET)
	// If we're going to make a separate error return socket, and pass it to the daemon
	// using sendmsg, then we'll hold back one data byte to go with it.
	// On some versions of Unix (including Leopard) sending a control message without
	// any associated data does not work reliably -- e.g. one particular issue we ran
	// into is that if the receiving program is in a kqueue loop waiting to be notified
	// of the received message, it doesn't get woken up when the control message arrives.
	if (MakeSeparateReturnSocket || sdr->op == send_bpf) datalen--;		// Okay to use sdr->op when checking for op == send_bpf
#endif

	// At this point, our listening socket is set up and waiting, if necessary, for the daemon to connect back to
	ConvertHeaderBytes(hdr);
	//syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %lu bytes", (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
	//if (MakeSeparateReturnSocket) syslog(LOG_WARNING, "dnssd_clientstub deliver_request name is %s", data);
#if TEST_SENDING_ONE_BYTE_AT_A_TIME
	unsigned int i;
	for (i=0; i<datalen + sizeof(ipc_msg_hdr); i++)
		{
		syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %d", i);
		if (write_all(sdr->sockfd, ((char *)hdr)+i, 1) < 0)
			{ syslog(LOG_WARNING, "write_all (byte %u) failed", i); goto cleanup; }
		usleep(10000);
		}
#else
	if (write_all(sdr->sockfd, (char *)hdr, datalen + sizeof(ipc_msg_hdr)) < 0)
		{
		// write_all already prints an error message if there is an error writing to
		// the socket except for DEFUNCT. Logging here is unnecessary and also wrong
		// in the case of DEFUNCT sockets
		syslog(LOG_INFO, "dnssd_clientstub deliver_request ERROR: write_all(%d, %lu bytes) failed",
			sdr->sockfd, (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
		goto cleanup;
		}
#endif

	if (!MakeSeparateReturnSocket) errsd = sdr->sockfd;
	if (MakeSeparateReturnSocket || sdr->op == send_bpf)	// Okay to use sdr->op when checking for op == send_bpf
		{
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
		// At this point we may block in accept for a few milliseconds waiting for the daemon to connect back to us,
		// but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
		dnssd_sockaddr_t daddr;
		dnssd_socklen_t len = sizeof(daddr);
		if ((err = wait_for_daemon(listenfd, DNSSD_CLIENT_TIMEOUT)) != kDNSServiceErr_NoError) goto cleanup;
		errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
		if (!dnssd_SocketValid(errsd)) deliver_request_bailout("accept");
#else

#if APPLE_OSX_mDNSResponder
// On Leopard, the stock definitions of the CMSG_* macros in /usr/include/sys/socket.h,
// while arguably correct in theory, nonetheless in practice produce code that doesn't work on 64-bit machines
// For details see <rdar://problem/5565787> Bonjour API broken for 64-bit apps (SCM_RIGHTS sendmsg fails)
#undef  CMSG_DATA
#define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + (sizeof(struct cmsghdr)))
#undef  CMSG_SPACE
#define CMSG_SPACE(l)   ((sizeof(struct cmsghdr)) + (l))
#undef  CMSG_LEN
#define CMSG_LEN(l)     ((sizeof(struct cmsghdr)) + (l))
#endif

		struct iovec vec = { ((char *)hdr) + sizeof(ipc_msg_hdr) + datalen, 1 }; // Send the last byte along with the SCM_RIGHTS
		struct msghdr msg;
		struct cmsghdr *cmsg;
		char cbuf[CMSG_SPACE(sizeof(dnssd_sock_t))];

		if (sdr->op == send_bpf)	// Okay to use sdr->op when checking for op == send_bpf
			{
			int i;
			char p[12];		// Room for "/dev/bpf999" with terminating null
			for (i=0; i<100; i++)
				{
				snprintf(p, sizeof(p), "/dev/bpf%d", i);
				listenfd = open(p, O_RDWR, 0);
				//if (dnssd_SocketValid(listenfd)) syslog(LOG_WARNING, "Sending fd %d for %s", listenfd, p);
				if (!dnssd_SocketValid(listenfd) && dnssd_errno != EBUSY)
					syslog(LOG_WARNING, "Error opening %s %d (%s)", p, dnssd_errno, dnssd_strerror(dnssd_errno));
				if (dnssd_SocketValid(listenfd) || dnssd_errno != EBUSY) break;
				}
			}

		msg.msg_name       = 0;
		msg.msg_namelen    = 0;
		msg.msg_iov        = &vec;
		msg.msg_iovlen     = 1;
		msg.msg_control    = cbuf;
		msg.msg_controllen = CMSG_LEN(sizeof(dnssd_sock_t));
		msg.msg_flags      = 0;
		cmsg = CMSG_FIRSTHDR(&msg);
		cmsg->cmsg_len     = CMSG_LEN(sizeof(dnssd_sock_t));
		cmsg->cmsg_level   = SOL_SOCKET;
		cmsg->cmsg_type    = SCM_RIGHTS;
		*((dnssd_sock_t *)CMSG_DATA(cmsg)) = listenfd;

#if TEST_KQUEUE_CONTROL_MESSAGE_BUG
		sleep(1);
#endif

#if DEBUG_64BIT_SCM_RIGHTS
		syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d %ld %ld %ld/%ld/%ld/%ld",
			errsd, listenfd, sizeof(dnssd_sock_t), sizeof(void*),
			sizeof(struct cmsghdr) + sizeof(dnssd_sock_t),
			CMSG_LEN(sizeof(dnssd_sock_t)), (long)CMSG_SPACE(sizeof(dnssd_sock_t)),
			(long)((char*)CMSG_DATA(cmsg) + 4 - cbuf));
#endif // DEBUG_64BIT_SCM_RIGHTS

		if (sendmsg(sdr->sockfd, &msg, 0) < 0)
			{
			syslog(LOG_WARNING, "dnssd_clientstub deliver_request ERROR: sendmsg failed read sd=%d write sd=%d errno %d (%s)",
				errsd, listenfd, dnssd_errno, dnssd_strerror(dnssd_errno));
			err = kDNSServiceErr_Incompatible;
			goto cleanup;
			}

#if DEBUG_64BIT_SCM_RIGHTS
		syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d okay", errsd, listenfd);
#endif // DEBUG_64BIT_SCM_RIGHTS

#endif
		// Close our end of the socketpair *before* blocking in read_all to get the four-byte error code.
		// Otherwise, if the daemon closes our socket (or crashes), we block in read_all() forever
		// because the socket is not closed (we still have an open reference to it ourselves).
		dnssd_close(listenfd);
		listenfd = dnssd_InvalidSocket;		// Make sure we don't close it a second time in the cleanup handling below
		}

	// At this point we may block in read_all for a few milliseconds waiting for the daemon to send us the error code,
	// but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
	if (sdr->op == send_bpf)	// Okay to use sdr->op when checking for op == send_bpf
		err = kDNSServiceErr_NoError;
	else if ((err = wait_for_daemon(errsd, DNSSD_CLIENT_TIMEOUT)) == kDNSServiceErr_NoError)
		{
		if (read_all(errsd, (char*)&err, (int)sizeof(err)) < 0)
			err = kDNSServiceErr_ServiceNotRunning; // On failure read_all will have written a message to syslog for us
		else
			err = ntohl(err);
		}

	//syslog(LOG_WARNING, "dnssd_clientstub deliver_request: retrieved error code %d", err);

cleanup:
	if (MakeSeparateReturnSocket)
		{
		if (dnssd_SocketValid(listenfd)) dnssd_close(listenfd);
		if (dnssd_SocketValid(errsd))    dnssd_close(errsd);
#if defined(USE_NAMED_ERROR_RETURN_SOCKET)
		// syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removing UDS: %s", data);
		if (unlink(data) != 0)
			syslog(LOG_WARNING, "dnssd_clientstub WARNING: unlink(\"%s\") failed errno %d (%s)", data, dnssd_errno, dnssd_strerror(dnssd_errno));
		// else syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removed UDS: %s", data);
#endif
		}

	free(hdr);
	return err;
	}

int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
	{
	if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with NULL DNSServiceRef"); return dnssd_InvalidSocket; }

	if (!DNSServiceRefValid(sdRef))
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with invalid DNSServiceRef %p %08X %08X",
			sdRef, sdRef->sockfd, sdRef->validator);
		return dnssd_InvalidSocket;
		}

	if (sdRef->primary)
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD undefined for kDNSServiceFlagsShareConnection subordinate DNSServiceRef %p", sdRef);
		return dnssd_InvalidSocket;
		}

	return (int) sdRef->sockfd;
	}

#if _DNS_SD_LIBDISPATCH
static void CallbackWithError(DNSServiceRef sdRef, DNSServiceErrorType error)
	{
	DNSServiceOp *sdr = sdRef;
	DNSServiceOp *sdrNext;
	DNSRecord *rec;
	DNSRecord *recnext;
	int morebytes;
	
	while (sdr)
		{
		// We can't touch the sdr after the callback as it can be deallocated in the callback
		sdrNext = sdr->next;
		morebytes = 1;
		sdr->moreptr = &morebytes;
		switch (sdr->op)
			{
			case resolve_request:
				if (sdr->AppCallback)((DNSServiceResolveReply)    sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, 0, 0, NULL,    sdr->AppContext);
				break;
			case query_request:
				if (sdr->AppCallback)((DNSServiceQueryRecordReply)sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, 0, 0, NULL, 0, sdr->AppContext);
				break;
			case addrinfo_request:
				if (sdr->AppCallback)((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, 0, 0, error, NULL, NULL, 0,          sdr->AppContext);
				break;
			case browse_request:
				if (sdr->AppCallback)((DNSServiceBrowseReply)     sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, NULL,          sdr->AppContext);
				break;
			case reg_service_request:
				if (sdr->AppCallback)((DNSServiceRegisterReply)   sdr->AppCallback)(sdr, 0,    error, NULL, 0, NULL,          sdr->AppContext);
				break;
			case enumeration_request:
				if (sdr->AppCallback)((DNSServiceDomainEnumReply) sdr->AppCallback)(sdr, 0, 0, error, NULL,                   sdr->AppContext);
				break;
			case connection_request:
				// This means Register Record, walk the list of DNSRecords to do the callback
				rec = sdr->rec;
				while (rec)
					{
					recnext = rec->recnext;
					if (rec->AppCallback) ((DNSServiceRegisterRecordReply)rec->AppCallback)(sdr, 0, 0, error, rec->AppContext);
					// The Callback can call DNSServiceRefDeallocate which in turn frees sdr and all the records.
					// Detect that and return early
					if (!morebytes){syslog(LOG_WARNING, "dnssdclientstub:Record: CallbackwithError morebytes zero"); return;}
					rec = recnext;
					}
				break;
			case port_mapping_request:
				if (sdr->AppCallback)((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, 0, 0, error, 0, 0, 0, 0, 0, sdr->AppContext);
				break;
			default:
				syslog(LOG_WARNING, "dnssd_clientstub CallbackWithError called with bad op %d", sdr->op);
			}
		// If DNSServiceRefDeallocate was called in the callback, morebytes will be zero. It means
		// all other sdrefs have been freed. This happens for shared connections where the
		// DNSServiceRefDeallocate on the first sdRef frees all other sdrefs.
		if (!morebytes){syslog(LOG_WARNING, "dnssdclientstub:sdRef: CallbackwithError morebytes zero"); return;}
		sdr = sdrNext;
		}
	}
#endif // _DNS_SD_LIBDISPATCH

// Handle reply from server, calling application client callback. If there is no reply
// from the daemon on the socket contained in sdRef, the call will block.
DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
	{
	int morebytes = 0;

	if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }

	if (!DNSServiceRefValid(sdRef))
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
		return kDNSServiceErr_BadReference;
		}

	if (sdRef->primary)
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult undefined for kDNSServiceFlagsShareConnection subordinate DNSServiceRef %p", sdRef);
		return kDNSServiceErr_BadReference;
		}

	if (!sdRef->ProcessReply)
		{
		static int num_logs = 0;
		if (num_logs < 10) syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function");
		if (num_logs < 1000) num_logs++; else sleep(1);
		return kDNSServiceErr_BadReference;
		}

	do
		{
		CallbackHeader cbh;
		char *data;
	
		// return NoError on EWOULDBLOCK. This will handle the case
		// where a non-blocking socket is told there is data, but it was a false positive.
		// On error, read_all will write a message to syslog for us, so don't need to duplicate that here
		// Note: If we want to properly support using non-blocking sockets in the future
		int result = read_all(sdRef->sockfd, (void *)&cbh.ipc_hdr, sizeof(cbh.ipc_hdr));
		if (result == read_all_fail)
			{
			// Set the ProcessReply to NULL before callback as the sdRef can get deallocated
			// in the callback.
			sdRef->ProcessReply = NULL;
#if _DNS_SD_LIBDISPATCH
			// Call the callbacks with an error if using the dispatch API, as DNSServiceProcessResult
			// is not called by the application and hence need to communicate the error. Cancel the
			// source so that we don't get any more events
			if (sdRef->disp_source)
				{
				dispatch_source_cancel(sdRef->disp_source);
				dispatch_release(sdRef->disp_source);
				sdRef->disp_source = NULL;
				CallbackWithError(sdRef, kDNSServiceErr_ServiceNotRunning);
				}
#endif
			// Don't touch sdRef anymore as it might have been deallocated
			return kDNSServiceErr_ServiceNotRunning;
			}
		else if (result == read_all_wouldblock)
			{
			if (morebytes && sdRef->logcounter < 100)
				{
				sdRef->logcounter++;
				syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult error: select indicated data was waiting but read_all returned EWOULDBLOCK");
				}
			return kDNSServiceErr_NoError;
			}
	
		ConvertHeaderBytes(&cbh.ipc_hdr);
		if (cbh.ipc_hdr.version != VERSION)
			{
			syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult daemon version %d does not match client version %d", cbh.ipc_hdr.version, VERSION);
			sdRef->ProcessReply = NULL;
			return kDNSServiceErr_Incompatible;
			}
	
		data = malloc(cbh.ipc_hdr.datalen);
		if (!data) return kDNSServiceErr_NoMemory;
		if (read_all(sdRef->sockfd, data, cbh.ipc_hdr.datalen) < 0) // On error, read_all will write a message to syslog for us
			{
			// Set the ProcessReply to NULL before callback as the sdRef can get deallocated
			// in the callback.
			sdRef->ProcessReply = NULL;
#if _DNS_SD_LIBDISPATCH
			// Call the callbacks with an error if using the dispatch API, as DNSServiceProcessResult
			// is not called by the application and hence need to communicate the error. Cancel the
			// source so that we don't get any more events
			if (sdRef->disp_source)
				{
				dispatch_source_cancel(sdRef->disp_source);
				dispatch_release(sdRef->disp_source);
				sdRef->disp_source = NULL;
				CallbackWithError(sdRef, kDNSServiceErr_ServiceNotRunning);
				}
#endif
			// Don't touch sdRef anymore as it might have been deallocated
			free(data);
			return kDNSServiceErr_ServiceNotRunning;
			}
		else
			{
			const char *ptr = data;
			cbh.cb_flags     = get_flags     (&ptr, data + cbh.ipc_hdr.datalen);
			cbh.cb_interface = get_uint32    (&ptr, data + cbh.ipc_hdr.datalen);
			cbh.cb_err       = get_error_code(&ptr, data + cbh.ipc_hdr.datalen);

			// CAUTION: We have to handle the case where the client calls DNSServiceRefDeallocate from within the callback function.
			// To do this we set moreptr to point to morebytes. If the client does call DNSServiceRefDeallocate(),
			// then that routine will clear morebytes for us, and cause us to exit our loop.
			morebytes = more_bytes(sdRef->sockfd);
			if (morebytes)
				{
				cbh.cb_flags |= kDNSServiceFlagsMoreComing;
				sdRef->moreptr = &morebytes;
				}
			if (ptr) sdRef->ProcessReply(sdRef, &cbh, ptr, data + cbh.ipc_hdr.datalen);
			// Careful code here:
			// If morebytes is non-zero, that means we set sdRef->moreptr above, and the operation was not
			// cancelled out from under us, so now we need to clear sdRef->moreptr so we don't leave a stray
			// dangling pointer pointing to a long-gone stack variable.
			// If morebytes is zero, then one of two thing happened:
			// (a) morebytes was 0 above, so we didn't set sdRef->moreptr, so we don't need to clear it
			// (b) morebytes was 1 above, and we set sdRef->moreptr, but the operation was cancelled (with DNSServiceRefDeallocate()),
			//     so we MUST NOT try to dereference our stale sdRef pointer.
			if (morebytes) sdRef->moreptr = NULL;
			}
		free(data);
		} while (morebytes);

	return kDNSServiceErr_NoError;
	}

void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
	{
	if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefDeallocate called with NULL DNSServiceRef"); return; }

	if (!DNSServiceRefValid(sdRef))		// Also verifies dnssd_SocketValid(sdRef->sockfd) for us too
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefDeallocate called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
		return;
		}

	// If we're in the middle of a DNSServiceProcessResult() invocation for this DNSServiceRef, clear its morebytes flag to break it out of its while loop
	if (sdRef->moreptr) *(sdRef->moreptr) = 0;

	if (sdRef->primary)		// If this is a subordinate DNSServiceOp, just send a 'stop' command
		{
		DNSServiceOp **p = &sdRef->primary->next;
		while (*p && *p != sdRef) p = &(*p)->next;
		if (*p)
			{
			char *ptr;
			size_t len = 0;
			ipc_msg_hdr *hdr = create_hdr(cancel_request, &len, &ptr, 0, sdRef);
			if (hdr)
				{
				ConvertHeaderBytes(hdr);
				write_all(sdRef->sockfd, (char *)hdr, len);
				free(hdr);
				}
			*p = sdRef->next;
			FreeDNSServiceOp(sdRef);
			}
		}
	else					// else, make sure to terminate all subordinates as well
		{
#if _DNS_SD_LIBDISPATCH
		// The cancel handler will close the fd if a dispatch source has been set
		if (sdRef->disp_source)
			{
			// By setting the ProcessReply to NULL, we make sure that we never call
			// the application callbacks ever, after returning from this function. We
			// assume that DNSServiceRefDeallocate is called from the serial queue
			// that was passed to DNSServiceSetDispatchQueue. Hence, dispatch_source_cancel
			// should cancel all the blocks on the queue and hence there should be no more
			// callbacks when we return from this function. Setting ProcessReply to NULL
			// provides extra protection.
			sdRef->ProcessReply = NULL;
			dispatch_source_cancel(sdRef->disp_source);
			dispatch_release(sdRef->disp_source);
			sdRef->disp_source = NULL;
			}
			// if disp_queue is set, it means it used the DNSServiceSetDispatchQueue API. In that case,
			// when the source was cancelled, the fd was closed in the handler. Currently the source
			// is cancelled only when the mDNSResponder daemon dies
		else if (!sdRef->disp_queue) dnssd_close(sdRef->sockfd);
#else
		dnssd_close(sdRef->sockfd);
#endif
		// Free DNSRecords added in DNSRegisterRecord if they have not
		// been freed in DNSRemoveRecord
		while (sdRef)
			{
			DNSServiceOp *p = sdRef;
			sdRef = sdRef->next;
			FreeDNSServiceOp(p);
			}
		}
	}

DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *result, uint32_t *size)
	{
	char *ptr;
	size_t len = strlen(property) + 1;
	ipc_msg_hdr *hdr;
	DNSServiceOp *tmp;
	uint32_t actualsize;

	DNSServiceErrorType err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
	if (err) return err;

	hdr = create_hdr(getproperty_request, &len, &ptr, 0, tmp);
	if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }

	put_string(property, &ptr);
	err = deliver_request(hdr, tmp);		// Will free hdr for us
	if (read_all(tmp->sockfd, (char*)&actualsize, (int)sizeof(actualsize)) < 0)
		{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }

	actualsize = ntohl(actualsize);
	if (read_all(tmp->sockfd, (char*)result, actualsize < *size ? actualsize : *size) < 0)
		{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
	DNSServiceRefDeallocate(tmp);

	// Swap version result back to local process byte order
	if (!strcmp(property, kDNSServiceProperty_DaemonVersion) && *size >= 4)
		*(uint32_t*)result = ntohl(*(uint32_t*)result);

	*size = actualsize;
	return kDNSServiceErr_NoError;
	}

static void handle_resolve_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *end)
	{
	char fullname[kDNSServiceMaxDomainName];
	char target[kDNSServiceMaxDomainName];
	uint16_t txtlen;
	union { uint16_t s; u_char b[2]; } port;
	unsigned char *txtrecord;

	get_string(&data, end, fullname, kDNSServiceMaxDomainName);
	get_string(&data, end, target,   kDNSServiceMaxDomainName);
	if (!data || data + 2 > end) goto fail;

	port.b[0] = *data++;
	port.b[1] = *data++;
	txtlen = get_uint16(&data, end);
	txtrecord = (unsigned char *)get_rdata(&data, end, txtlen);

	if (!data) goto fail;
	((DNSServiceResolveReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, fullname, target, port.s, txtlen, txtrecord, sdr->AppContext);
	return;
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
fail:
	syslog(LOG_WARNING, "dnssd_clientstub handle_resolve_response: error reading result from daemon");
	}

DNSServiceErrorType DNSSD_API DNSServiceResolve
	(
	DNSServiceRef                 *sdRef,
	DNSServiceFlags               flags,
	uint32_t                      interfaceIndex,
	const char                    *name,
	const char                    *regtype,
	const char                    *domain,
	DNSServiceResolveReply        callBack,
	void                          *context
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err;

	if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;

	// Need a real InterfaceID for WakeOnResolve
	if ((flags & kDNSServiceFlagsWakeOnResolve) != 0 &&
		((interfaceIndex == kDNSServiceInterfaceIndexAny) ||
		(interfaceIndex == kDNSServiceInterfaceIndexLocalOnly) ||
		(interfaceIndex == kDNSServiceInterfaceIndexUnicast) ||
		(interfaceIndex == kDNSServiceInterfaceIndexP2P)))
		{
		return kDNSServiceErr_BadParam;
		}
		
	err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	// Calculate total message length
	len = sizeof(flags);
	len += sizeof(interfaceIndex);
	len += strlen(name) + 1;
	len += strlen(regtype) + 1;
	len += strlen(domain) + 1;

	hdr = create_hdr(resolve_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_string(name, &ptr);
	put_string(regtype, &ptr);
	put_string(domain, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

static void handle_query_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
	{
	uint32_t ttl;
	char name[kDNSServiceMaxDomainName];
	uint16_t rrtype, rrclass, rdlen;
	const char *rdata;

	get_string(&data, end, name, kDNSServiceMaxDomainName);
	rrtype  = get_uint16(&data, end);
	rrclass = get_uint16(&data, end);
	rdlen   = get_uint16(&data, end);
	rdata   = get_rdata(&data, end, rdlen);
	ttl     = get_uint32(&data, end);

	if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_query_response: error reading result from daemon");
	else ((DNSServiceQueryRecordReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, name, rrtype, rrclass, rdlen, rdata, ttl, sdr->AppContext);
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
	}

DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
	(
	DNSServiceRef              *sdRef,
	DNSServiceFlags             flags,
	uint32_t                    interfaceIndex,
	const char                 *name,
	uint16_t                    rrtype,
	uint16_t                    rrclass,
	DNSServiceQueryRecordReply  callBack,
	void                       *context
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err = ConnectToServer(sdRef, flags, query_request, handle_query_response, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	if (!name) name = "\0";

	// Calculate total message length
	len = sizeof(flags);
	len += sizeof(uint32_t);  // interfaceIndex
	len += strlen(name) + 1;
	len += 2 * sizeof(uint16_t);  // rrtype, rrclass

	hdr = create_hdr(query_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_string(name, &ptr);
	put_uint16(rrtype, &ptr);
	put_uint16(rrclass, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

static void handle_addrinfo_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
	{
	char hostname[kDNSServiceMaxDomainName];
	uint16_t rrtype, rrclass, rdlen;
	const char *rdata;
	uint32_t ttl;

	get_string(&data, end, hostname, kDNSServiceMaxDomainName);
	rrtype  = get_uint16(&data, end);
	rrclass = get_uint16(&data, end);
	rdlen   = get_uint16(&data, end);
	rdata   = get_rdata (&data, end, rdlen);
	ttl     = get_uint32(&data, end);

	// We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
	// those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
	// Other result types, specifically CNAME referrals, are not communicated to the client, because
	// the DNSServiceGetAddrInfoReply interface doesn't have any meaningful way to communiate CNAME referrals.
	if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_addrinfo_response: error reading result from daemon");
	else if (rrtype == kDNSServiceType_A || rrtype == kDNSServiceType_AAAA)
		{
		struct sockaddr_in  sa4;
		struct sockaddr_in6 sa6;
		const struct sockaddr *const sa = (rrtype == kDNSServiceType_A) ? (struct sockaddr*)&sa4 : (struct sockaddr*)&sa6;
		if (rrtype == kDNSServiceType_A)
			{
			memset(&sa4, 0, sizeof(sa4));
			#ifndef NOT_HAVE_SA_LEN
			sa4.sin_len = sizeof(struct sockaddr_in);
			#endif
			sa4.sin_family = AF_INET;
			//  sin_port   = 0;
			if (!cbh->cb_err) memcpy(&sa4.sin_addr, rdata, rdlen);
			}
		else
			{
			memset(&sa6, 0, sizeof(sa6));
			#ifndef NOT_HAVE_SA_LEN
			sa6.sin6_len = sizeof(struct sockaddr_in6);
			#endif
			sa6.sin6_family     = AF_INET6;
			//  sin6_port     = 0;
			//  sin6_flowinfo = 0;
			//  sin6_scope_id = 0;
			if (!cbh->cb_err)
				{
				memcpy(&sa6.sin6_addr, rdata, rdlen);
				if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr)) sa6.sin6_scope_id = cbh->cb_interface;
				}
			}
		((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, hostname, sa, ttl, sdr->AppContext);
		// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
		}
	}

DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
	(
	DNSServiceRef                    *sdRef,
	DNSServiceFlags                  flags,
	uint32_t                         interfaceIndex,
	uint32_t                         protocol,
	const char                       *hostname,
	DNSServiceGetAddrInfoReply       callBack,
	void                             *context          /* may be NULL */
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err;

	if (!hostname) return kDNSServiceErr_BadParam;

	err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	// Calculate total message length
	len = sizeof(flags);
	len += sizeof(uint32_t);      // interfaceIndex
	len += sizeof(uint32_t);      // protocol
	len += strlen(hostname) + 1;

	hdr = create_hdr(addrinfo_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_uint32(protocol, &ptr);
	put_string(hostname, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}
	
static void handle_browse_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
	{
	char replyName[256], replyType[kDNSServiceMaxDomainName], replyDomain[kDNSServiceMaxDomainName];
	get_string(&data, end, replyName, 256);
	get_string(&data, end, replyType, kDNSServiceMaxDomainName);
	get_string(&data, end, replyDomain, kDNSServiceMaxDomainName);
	if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_browse_response: error reading result from daemon");
	else ((DNSServiceBrowseReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, replyName, replyType, replyDomain, sdr->AppContext);
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
	}

DNSServiceErrorType DNSSD_API DNSServiceBrowse
	(
	DNSServiceRef         *sdRef,
	DNSServiceFlags        flags,
	uint32_t               interfaceIndex,
	const char            *regtype,
	const char            *domain,
	DNSServiceBrowseReply  callBack,
	void                  *context
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	if (!domain) domain = "";
	len = sizeof(flags);
	len += sizeof(interfaceIndex);
	len += strlen(regtype) + 1;
	len += strlen(domain) + 1;

	hdr = create_hdr(browse_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_string(regtype, &ptr);
	put_string(domain, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain)
	{
	DNSServiceOp *tmp;
	char *ptr;
	size_t len = sizeof(flags) + strlen(domain) + 1;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
	if (err) return err;

	hdr = create_hdr(setdomain_request, &len, &ptr, 0, tmp);
	if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_string(domain, &ptr);
	err = deliver_request(hdr, tmp);		// Will free hdr for us
	DNSServiceRefDeallocate(tmp);
	return err;
	}

static void handle_regservice_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
	{
	char name[256], regtype[kDNSServiceMaxDomainName], domain[kDNSServiceMaxDomainName];
	get_string(&data, end, name, 256);
	get_string(&data, end, regtype, kDNSServiceMaxDomainName);
	get_string(&data, end, domain,  kDNSServiceMaxDomainName);
	if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_regservice_response: error reading result from daemon");
	else ((DNSServiceRegisterReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_err, name, regtype, domain, sdr->AppContext);
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
	}

DNSServiceErrorType DNSSD_API DNSServiceRegister
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *name,
	const char                          *regtype,
	const char                          *domain,
	const char                          *host,
	uint16_t                            PortInNetworkByteOrder,
	uint16_t                            txtLen,
	const void                          *txtRecord,
	DNSServiceRegisterReply             callBack,
	void                                *context
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err;
	union { uint16_t s; u_char b[2]; } port = { PortInNetworkByteOrder };

	if (!name) name = "";
	if (!regtype) return kDNSServiceErr_BadParam;
	if (!domain) domain = "";
	if (!host) host = "";
	if (!txtRecord) txtRecord = (void*)"";

	// No callback must have auto-rename
	if (!callBack && (flags & kDNSServiceFlagsNoAutoRename)) return kDNSServiceErr_BadParam;

	err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	len = sizeof(DNSServiceFlags);
	len += sizeof(uint32_t);  // interfaceIndex
	len += strlen(name) + strlen(regtype) + strlen(domain) + strlen(host) + 4;
	len += 2 * sizeof(uint16_t);  // port, txtLen
	len += txtLen;

	hdr = create_hdr(reg_service_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
	if (!callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_string(name, &ptr);
	put_string(regtype, &ptr);
	put_string(domain, &ptr);
	put_string(host, &ptr);
	*ptr++ = port.b[0];
	*ptr++ = port.b[1];
	put_uint16(txtLen, &ptr);
	put_rdata(txtLen, txtRecord, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

static void handle_enumeration_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
	{
	char domain[kDNSServiceMaxDomainName];
	get_string(&data, end, domain, kDNSServiceMaxDomainName);
	if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_enumeration_response: error reading result from daemon");
	else ((DNSServiceDomainEnumReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, domain, sdr->AppContext);
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
	}

DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
	(
	DNSServiceRef             *sdRef,
	DNSServiceFlags            flags,
	uint32_t                   interfaceIndex,
	DNSServiceDomainEnumReply  callBack,
	void                      *context
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err;

	int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
	int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
	if (f1 + f2 != 1) return kDNSServiceErr_BadParam;

	err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	len = sizeof(DNSServiceFlags);
	len += sizeof(uint32_t);

	hdr = create_hdr(enumeration_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

static void ConnectionResponse(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *const data, const char *const end)
	{
	DNSRecordRef rref = cbh->ipc_hdr.client_context.context;
	(void)data; // Unused

	//printf("ConnectionResponse got %d\n", cbh->ipc_hdr.op);
	if (cbh->ipc_hdr.op != reg_record_reply_op)
		{
		// When using kDNSServiceFlagsShareConnection, need to search the list of associated DNSServiceOps
		// to find the one this response is intended for, and then call through to its ProcessReply handler.
		// We start with our first subordinate DNSServiceRef -- don't want to accidentally match the parent DNSServiceRef.
		DNSServiceOp *op = sdr->next;
		while (op && (op->uid.u32[0] != cbh->ipc_hdr.client_context.u32[0] || op->uid.u32[1] != cbh->ipc_hdr.client_context.u32[1]))
			op = op->next;
		// Note: We may sometimes not find a matching DNSServiceOp, in the case where the client has
		// cancelled the subordinate DNSServiceOp, but there are still messages in the pipeline from the daemon
		if (op && op->ProcessReply) op->ProcessReply(op, cbh, data, end);
		// WARNING: Don't touch op or sdr after this -- client may have called DNSServiceRefDeallocate
		return;
		}

	if (sdr->op == connection_request)
		rref->AppCallback(rref->sdr, rref, cbh->cb_flags, cbh->cb_err, rref->AppContext);
	else
		{
		syslog(LOG_WARNING, "dnssd_clientstub ConnectionResponse: sdr->op != connection_request");
		rref->AppCallback(rref->sdr, rref, 0, kDNSServiceErr_Unknown, rref->AppContext);
		}
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
	}

DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
	{
	char *ptr;
	size_t len = 0;
	ipc_msg_hdr *hdr;
	DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL
	
	hdr = create_hdr(connection_request, &len, &ptr, 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
	(
	DNSServiceRef                  sdRef,
	DNSRecordRef                  *RecordRef,
	DNSServiceFlags                flags,
	uint32_t                       interfaceIndex,
	const char                    *fullname,
	uint16_t                       rrtype,
	uint16_t                       rrclass,
	uint16_t                       rdlen,
	const void                    *rdata,
	uint32_t                       ttl,
	DNSServiceRegisterRecordReply  callBack,
	void                          *context
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr = NULL;
	DNSRecordRef rref = NULL;
	DNSRecord **p;
	int f1 = (flags & kDNSServiceFlagsShared) != 0;
	int f2 = (flags & kDNSServiceFlagsUnique) != 0;
	if (f1 + f2 != 1) return kDNSServiceErr_BadParam;

	if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }

	if (!DNSServiceRefValid(sdRef))
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
		return kDNSServiceErr_BadReference;
		}

	if (sdRef->op != connection_request)
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with non-DNSServiceCreateConnection DNSServiceRef %p %d", sdRef, sdRef->op);
		return kDNSServiceErr_BadReference;
		}

	*RecordRef = NULL;

	len = sizeof(DNSServiceFlags);
	len += 2 * sizeof(uint32_t);  // interfaceIndex, ttl
	len += 3 * sizeof(uint16_t);  // rrtype, rrclass, rdlen
	len += strlen(fullname) + 1;
	len += rdlen;

	hdr = create_hdr(reg_record_request, &len, &ptr, 1, sdRef);
	if (!hdr) return kDNSServiceErr_NoMemory;

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_string(fullname, &ptr);
	put_uint16(rrtype, &ptr);
	put_uint16(rrclass, &ptr);
	put_uint16(rdlen, &ptr);
	put_rdata(rdlen, rdata, &ptr);
	put_uint32(ttl, &ptr);

	rref = malloc(sizeof(DNSRecord));
	if (!rref) { free(hdr); return kDNSServiceErr_NoMemory; }
	rref->AppContext = context;
	rref->AppCallback = callBack;
	rref->record_index = sdRef->max_index++;
	rref->sdr = sdRef;
	rref->recnext = NULL;
	*RecordRef = rref;
	hdr->client_context.context = rref;
	hdr->reg_index = rref->record_index;

	p = &(sdRef)->rec;
	while (*p) p = &(*p)->recnext;
	*p = rref;

	return deliver_request(hdr, sdRef);		// Will free hdr for us
	}

// sdRef returned by DNSServiceRegister()
DNSServiceErrorType DNSSD_API DNSServiceAddRecord
	(
	DNSServiceRef    sdRef,
	DNSRecordRef    *RecordRef,
	DNSServiceFlags  flags,
	uint16_t         rrtype,
	uint16_t         rdlen,
	const void      *rdata,
	uint32_t         ttl
	)
	{
	ipc_msg_hdr *hdr;
	size_t len = 0;
	char *ptr;
	DNSRecordRef rref;
	DNSRecord **p;

	if (!sdRef)     { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSServiceRef");        return kDNSServiceErr_BadParam; }
	if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSRecordRef pointer"); return kDNSServiceErr_BadParam; }
	if (sdRef->op != reg_service_request)
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with non-DNSServiceRegister DNSServiceRef %p %d", sdRef, sdRef->op);
		return kDNSServiceErr_BadReference;
		}

	if (!DNSServiceRefValid(sdRef))
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
		return kDNSServiceErr_BadReference;
		}

	*RecordRef = NULL;

	len += 2 * sizeof(uint16_t);  // rrtype, rdlen
	len += rdlen;
	len += sizeof(uint32_t);
	len += sizeof(DNSServiceFlags);

	hdr = create_hdr(add_record_request, &len, &ptr, 1, sdRef);
	if (!hdr) return kDNSServiceErr_NoMemory;
	put_flags(flags, &ptr);
	put_uint16(rrtype, &ptr);
	put_uint16(rdlen, &ptr);
	put_rdata(rdlen, rdata, &ptr);
	put_uint32(ttl, &ptr);

	rref = malloc(sizeof(DNSRecord));
	if (!rref) { free(hdr); return kDNSServiceErr_NoMemory; }
	rref->AppContext = NULL;
	rref->AppCallback = NULL;
	rref->record_index = sdRef->max_index++;
	rref->sdr = sdRef;
	rref->recnext = NULL;
	*RecordRef = rref;
	hdr->reg_index = rref->record_index;

	p = &(sdRef)->rec;
	while (*p) p = &(*p)->recnext;
	*p = rref;

	return deliver_request(hdr, sdRef);		// Will free hdr for us
	}

// DNSRecordRef returned by DNSServiceRegisterRecord or DNSServiceAddRecord
DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
	(
	DNSServiceRef    sdRef,
	DNSRecordRef     RecordRef,
	DNSServiceFlags  flags,
	uint16_t         rdlen,
	const void      *rdata,
	uint32_t         ttl
	)
	{
	ipc_msg_hdr *hdr;
	size_t len = 0;
	char *ptr;

	if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }

	if (!DNSServiceRefValid(sdRef))
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
		return kDNSServiceErr_BadReference;
		}

	// Note: RecordRef is allowed to be NULL

	len += sizeof(uint16_t);
	len += rdlen;
	len += sizeof(uint32_t);
	len += sizeof(DNSServiceFlags);

	hdr = create_hdr(update_record_request, &len, &ptr, 1, sdRef);
	if (!hdr) return kDNSServiceErr_NoMemory;
	hdr->reg_index = RecordRef ? RecordRef->record_index : TXT_RECORD_INDEX;
	put_flags(flags, &ptr);
	put_uint16(rdlen, &ptr);
	put_rdata(rdlen, rdata, &ptr);
	put_uint32(ttl, &ptr);
	return deliver_request(hdr, sdRef);		// Will free hdr for us
	}

DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
	(
	DNSServiceRef    sdRef,
	DNSRecordRef     RecordRef,
	DNSServiceFlags  flags
	)
	{
	ipc_msg_hdr *hdr;
	size_t len = 0;
	char *ptr;
	DNSServiceErrorType err;

	if (!sdRef)            { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
	if (!RecordRef)        { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with NULL DNSRecordRef");  return kDNSServiceErr_BadParam; }
	if (!sdRef->max_index) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with bad DNSServiceRef");  return kDNSServiceErr_BadReference; }

	if (!DNSServiceRefValid(sdRef))
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
		return kDNSServiceErr_BadReference;
		}

	len += sizeof(flags);
	hdr = create_hdr(remove_record_request, &len, &ptr, 1, sdRef);
	if (!hdr) return kDNSServiceErr_NoMemory;
	hdr->reg_index = RecordRef->record_index;
	put_flags(flags, &ptr);
	err = deliver_request(hdr, sdRef);		// Will free hdr for us
	if (!err)
		{
		// This RecordRef could have been allocated in DNSServiceRegisterRecord or DNSServiceAddRecord.
		// If so, delink from the list before freeing
		DNSRecord **p = &sdRef->rec;
		while (*p && *p != RecordRef) p = &(*p)->recnext;
		if (*p) *p = RecordRef->recnext;
		free(RecordRef);
		}
	return err;
	}

DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
	(
	DNSServiceFlags  flags,
	uint32_t         interfaceIndex,
	const char      *fullname,
	uint16_t         rrtype,
	uint16_t         rrclass,
	uint16_t         rdlen,
	const void      *rdata
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	DNSServiceOp *tmp;

	DNSServiceErrorType err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
	if (err) return err;

	len = sizeof(DNSServiceFlags);
	len += sizeof(uint32_t);
	len += strlen(fullname) + 1;
	len += 3 * sizeof(uint16_t);
	len += rdlen;
	hdr = create_hdr(reconfirm_record_request, &len, &ptr, 0, tmp);
	if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_string(fullname, &ptr);
	put_uint16(rrtype, &ptr);
	put_uint16(rrclass, &ptr);
	put_uint16(rdlen, &ptr);
	put_rdata(rdlen, rdata, &ptr);

	err = deliver_request(hdr, tmp);		// Will free hdr for us
	DNSServiceRefDeallocate(tmp);
	return err;
	}

static void handle_port_mapping_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
	{
	union { uint32_t l; u_char b[4]; } addr;
	uint8_t protocol;
	union { uint16_t s; u_char b[2]; } internalPort;
	union { uint16_t s; u_char b[2]; } externalPort;
	uint32_t ttl;

	if (!data || data + 13 > end) goto fail;

	addr        .b[0] = *data++;
	addr        .b[1] = *data++;
	addr        .b[2] = *data++;
	addr        .b[3] = *data++;
	protocol          = *data++;
	internalPort.b[0] = *data++;
	internalPort.b[1] = *data++;
	externalPort.b[0] = *data++;
	externalPort.b[1] = *data++;
	ttl               = get_uint32(&data, end);
	if (!data) goto fail;

	((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, addr.l, protocol, internalPort.s, externalPort.s, ttl, sdr->AppContext);
	return;
	// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function

fail:
	syslog(LOG_WARNING, "dnssd_clientstub handle_port_mapping_response: error reading result from daemon");
	}

DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	uint32_t                            protocol,     /* TCP and/or UDP */
	uint16_t                            internalPortInNetworkByteOrder,
	uint16_t                            externalPortInNetworkByteOrder,
	uint32_t                            ttl,          /* time to live in seconds */
	DNSServiceNATPortMappingReply       callBack,
	void                                *context      /* may be NULL */
	)
	{
	char *ptr;
	size_t len;
	ipc_msg_hdr *hdr;
	union { uint16_t s; u_char b[2]; } internalPort = { internalPortInNetworkByteOrder };
	union { uint16_t s; u_char b[2]; } externalPort = { externalPortInNetworkByteOrder };

	DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, callBack, context);
	if (err) return err;	// On error ConnectToServer leaves *sdRef set to NULL

	len = sizeof(flags);
	len += sizeof(interfaceIndex);
	len += sizeof(protocol);
	len += sizeof(internalPort);
	len += sizeof(externalPort);
	len += sizeof(ttl);

	hdr = create_hdr(port_mapping_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
	if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }

	put_flags(flags, &ptr);
	put_uint32(interfaceIndex, &ptr);
	put_uint32(protocol, &ptr);
	*ptr++ = internalPort.b[0];
	*ptr++ = internalPort.b[1];
	*ptr++ = externalPort.b[0];
	*ptr++ = externalPort.b[1];
	put_uint32(ttl, &ptr);

	err = deliver_request(hdr, *sdRef);		// Will free hdr for us
	if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
	return err;
	}

#if _DNS_SD_LIBDISPATCH
DNSServiceErrorType DNSSD_API DNSServiceSetDispatchQueue
	(
	DNSServiceRef service,
	dispatch_queue_t queue
	)
	{
	int dnssd_fd  = DNSServiceRefSockFD(service);
	if (dnssd_fd == dnssd_InvalidSocket) return kDNSServiceErr_BadParam;
	if (!queue)
		{
		syslog(LOG_WARNING, "dnssd_clientstub: DNSServiceSetDispatchQueue dispatch queue NULL");
		return kDNSServiceErr_BadParam;
		}
	if (service->disp_queue)
		{
		syslog(LOG_WARNING, "dnssd_clientstub DNSServiceSetDispatchQueue dispatch queue set already");
		return kDNSServiceErr_BadParam;
		}
	if (service->disp_source)
		{
		syslog(LOG_WARNING, "DNSServiceSetDispatchQueue dispatch source set already");
		return kDNSServiceErr_BadParam;
		}
	service->disp_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, dnssd_fd, 0, queue);
	if (!service->disp_source)
		{
		syslog(LOG_WARNING, "DNSServiceSetDispatchQueue dispatch_source_create failed");
		return kDNSServiceErr_NoMemory;
		}
	service->disp_queue = queue;
	dispatch_source_set_event_handler(service->disp_source, ^{DNSServiceProcessResult(service);});
	dispatch_source_set_cancel_handler(service->disp_source, ^{dnssd_close(dnssd_fd);});
	dispatch_resume(service->disp_source);
	return kDNSServiceErr_NoError;
	}
#endif // _DNS_SD_LIBDISPATCH
