]> git.saurik.com Git - apple/libinfo.git/blobdiff - mdns.subproj/dnssd_clientstub.c
Libinfo-222.4.9.tar.gz
[apple/libinfo.git] / mdns.subproj / dnssd_clientstub.c
index eed342fc8bb467e0e1ba1ddea4ef75229692e1cf..e2e4fc1ef7cff51d05615e753770352c8e3441a6 100644 (file)
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+/* -*- Mode: C; tab-width: 4 -*-
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
- * 
- * 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,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * 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) 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.
+
+    Change History (most recent first):
+
+$Log: dnssd_clientstub.c,v $
+Revision 1.20.70.3  2006/05/02 16:17:04  majka
+Make NumTries unsigned.
+
+Revision 1.20.70.2  2006/05/01 21:43:09  majka
+Additional change (make NumTries static) for 4527193
+SUChardLondon Libinfo-222.4.6
+
+Revision 1.20.70.1  2006/05/01 16:10:54  majka
+Libinfo-222_4_5 is equivalent to Chardonnay Libinfo-222.0.5
+
+Revision 1.20.60.1  2006/04/27 21:33:30  majka
+Integrated 4527193
+
+Revision 1.20  2005/02/03 00:39:05  majka
+Integrated 3942900
+
+Revision 1.19.4.1  2005/02/02 00:47:40  ksekar
+<rdar://problem/3942900> dnd-sd shows the wrong port numbers
+
+Revision 1.19  2004/12/23 23:10:59  majka
+*** empty log message ***
+
+Revision 1.18.8.1  2004/12/23 17:32:56  ksekar
+<rdar://problem/3931319> Rendevzous calls leak sockets if mDNSResponder is not running
+
+Revision 1.18  2004/12/14 18:02:00  majka
+*** empty log message ***
+
+Revision 1.17.36.1  2004/12/13 17:22:39  ksekar
+<rdar://problem/3656389> Deprecate the DNSServiceDiscovery.h API in Tiger
+<rdar://problem/3873869> Add kDNSServiceInterfaceForceMulticast to header
+<rdar://problem/3526342> Remove overly-restrictive flag checks
+
+Revision 1.17  2004/09/22 20:05:38  majka
+Integrated
+3725573 - Need Error Codes for handling Lighthouse setup failure on NAT
+3805822 - Socket-based APIs aren't endian-safe
+3806739 - DNSServiceSetDefaultDomainForUser header comments incorrect
+
+Revision 1.16.2.1  2004/09/20 21:54:33  ksekar
+<rdar://problem/3805822> Socket-based APIs aren't endian-safe
+
+Revision 1.16  2004/09/17 20:19:00  majka
+Integrated 3804522
+
+Revision 1.15.2.1  2004/09/17 20:15:30  ksekar
+*** empty log message ***
+
+Revision 1.15  2004/09/16 23:45:24  majka
+Integrated 3775315 and 3765280.
+
+Revision 1.14.4.1  2004/09/02 19:43:41  ksekar
+<rdar://problem/3775315>: Sync dns-sd client files between Libinfo and
+mDNSResponder projects
+
+Revision 1.28  2004/08/11 17:10:04  cheshire
+Fix signed/unsigned warnings
+
+Revision 1.27  2004/08/11 00:54:16  cheshire
+Change "hdr->op.request_op" to just "hdr->op"
+
+Revision 1.26  2004/07/26 06:07:27  shersche
+fix bugs when using an error socket to communicate with the daemon
+
+Revision 1.25  2004/07/26 05:54:02  shersche
+DNSServiceProcessResult() returns NoError if socket read returns EWOULDBLOCK
+
+Revision 1.24  2004/07/20 06:46:21  shersche
+<rdar://problem/3730123> fix endless loop in my_read() if recv returns 0
+Bug #: 3730123
+
+Revision 1.23  2004/06/29 00:48:38  cheshire
+Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions;
+use an explicit while() loop instead.
+
+Revision 1.22  2004/06/26 03:16:34  shersche
+clean up warning messages on Win32 platform
+
+Submitted by: herscher
+
+Revision 1.21  2004/06/18 04:53:56  rpantos
+Use platform layer for socket types. Introduce USE_TCP_LOOPBACK. Remove dependency on mDNSClientAPI.h.
+
+Revision 1.20  2004/06/12 00:50:22  cheshire
+Changes for Windows compatibility
+
+Revision 1.19  2004/05/25 18:29:33  cheshire
+Move DNSServiceConstructFullName() from dnssd_clientstub.c to dnssd_clientlib.c,
+so that it's also accessible to dnssd_clientshim.c (single address space) clients.
+
+Revision 1.18  2004/05/18 23:51:27  cheshire
+Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
+
+Revision 1.17  2004/05/06 18:42:58  ksekar
+General dns_sd.h API cleanup, including the following radars:
+<rdar://problem/3592068>: Remove flags with zero value
+<rdar://problem/3479569>: Passing in NULL causes a crash.
+
+Revision 1.16  2004/03/12 22:00:37  cheshire
+Added: #include <sys/socket.h>
+
+Revision 1.15  2004/01/20 18:36:29  ksekar
+Propagated Libinfo fix for <rdar://problem/3483971>: SU:
+DNSServiceUpdateRecord() doesn't allow you to update the TXT record
+into TOT mDNSResponder.
+
+Revision 1.14  2004/01/19 22:39:17  cheshire
+Don't use "MSG_WAITALL"; it makes send() return "Invalid argument" on Linux;
+use an explicit while() loop instead. (In any case, this should only make a difference
+with non-blocking sockets, which we don't use on the client side right now.)
+
+Revision 1.13  2004/01/19 21:46:52  cheshire
+Fix compiler warning
+
+Revision 1.12  2003/12/23 20:46:47  ksekar
+<rdar://problem/3497428>: sync dnssd files between libinfo & mDNSResponder
+
+Revision 1.11  2003/12/08 21:11:42  rpantos
+Changes necessary to support mDNSResponder on Linux.
+
+Revision 1.10  2003/10/13 23:50:53  ksekar
+Updated dns_sd clientstub files to bring copies in synch with
+top-of-tree Libinfo:  A memory leak in dnssd_clientstub.c is fixed,
+and comments in dns_sd.h are improved.
+
+Revision 1.9  2003/08/15 21:30:39  cheshire
+Bring up to date with LibInfo version
+
+Revision 1.8  2003/08/13 23:54:52  ksekar
+Bringing dnssd_clientstub.c up to date with Libinfo, per radar 3376640
+
+Revision 1.7  2003/08/12 19:56:25  cheshire
+Update to APSL 2.0
+
  */
 
-#include "dnssd_ipc.h"
 #include <errno.h>
+#include <stdlib.h>
+#if defined(_WIN32)
+#include <winsock2.h>
+#include <windows.h>
+#define sockaddr_mdns sockaddr_in
+#define AF_MDNS AF_INET
+#else
 #include <sys/time.h>
+#include <sys/socket.h>
+#define sockaddr_mdns sockaddr_un
+#define AF_MDNS AF_LOCAL
+#endif
+
+#include "dnssd_ipc.h"
+
+#if defined(_WIN32)
+// 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)
+
+#define sleep(X) Sleep((X) * 1000)
+
+static int g_initWinsock = 0;
+#endif
 
 
 #define CTL_PATH_PREFIX "/tmp/dnssd_clippath."
 // last 3 digits of the time (in seconds) and n is the 6-digit microsecond time
 
 // general utility functions
-static DNSServiceRef connect_to_server(void);
-DNSServiceErrorType deliver_request(void *msg, DNSServiceRef sdr, int reuse_sd);
-static ipc_msg_hdr *create_hdr(int op, int *len, char **data_start, int reuse_socket);
-static int my_read(int sd, char *buf, int len);
-static int my_write(int sd, char *buf, int len);
-static int domain_ends_in_dot(const char *dom);
-// server response handlers
-static void handle_query_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *msg);
-static void handle_browse_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data);
-static void handle_regservice_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data);
-static void handle_regrecord_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data);
-static void handle_enumeration_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data);
-static void handle_resolve_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data);
-
 typedef struct _DNSServiceRef_t
     {
-    int sockfd;  // connected socket between client and daemon
-    int op;      // request/reply_op_t
+    dnssd_sock_t sockfd;  // connected socket between client and daemon
+    uint32_t op;          // request_op_t or reply_op_t
     process_reply_callback process_reply;
     void *app_callback;
     void *app_context;
     uint32_t max_index;  //largest assigned record index - 0 if no additl. recs registered
-    } _DNSServiceRef_t;                        
+    } _DNSServiceRef_t;
 
 typedef struct _DNSRecordRef_t
     {
     void *app_context;
     DNSServiceRegisterRecordReply app_callback;
     DNSRecordRef recref;
-    int record_index;  // index is unique to the ServiceDiscoveryRef
+    uint32_t record_index;  // index is unique to the ServiceDiscoveryRef
     DNSServiceRef sdr;
     } _DNSRecordRef_t;
 
-
 // exported functions
 
-int DNSServiceRefSockFD(DNSServiceRef sdRef)
+// write len bytes.  return 0 on success, -1 on error
+static int my_write(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 (send(sd, buf, len, MSG_WAITALL) != len)   return -1;
+    while (len)
+       {
+       ssize_t num_written = send(sd, buf, len, 0);
+       if (num_written < 0 || num_written > len) return -1;
+       buf += num_written;
+       len -= num_written;
+       }
+    return 0;
+    }
+
+// read len bytes.  return 0 on success, -1 on error
+static int my_read(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);
+       if ((num_read == 0) || (num_read < 0) || (num_read > len)) return -1;
+       buf += num_read;
+       len -= num_read;
+       }
+    return 0;
+    }
+
+/* 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.  reuse_socket should be non-zero
+ * for calls that can receive an immediate error return value on their primary socket.
+ * 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 reuse_socket)
+    {
+    char *msg = NULL;
+    ipc_msg_hdr *hdr;
+    int datalen;
+    char ctrl_path[256];
+
+    if (!reuse_socket)
+        {
+#if defined(USE_TCP_LOOPBACK)
+               *len += 2;      // Allocate space for two-byte port number
+#else
+               struct timeval time;
+               if (gettimeofday(&time, NULL) < 0) return NULL;
+               sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
+                       (unsigned long)(time.tv_sec & 0xFFF), (unsigned long)(time.tv_usec));
+        *len += strlen(ctrl_path) + 1;
+#endif
+        }
+
+    datalen = (int) *len;
+    *len += sizeof(ipc_msg_hdr);
+
+    // write message to buffer
+    msg = malloc(*len);
+    if (!msg) return NULL;
+
+    bzero(msg, *len);
+    hdr = (void *)msg;
+    hdr->datalen = datalen;
+    hdr->version = VERSION;
+    hdr->op = op;
+    if (reuse_socket) hdr->flags |= IPC_FLAGS_REUSE_SOCKET;
+    *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 (!reuse_socket)      put_short(0, data_start);
+#else
+    if (!reuse_socket)  put_string(ctrl_path, data_start);
+#endif
+    return hdr;
+    }
+
+    // return a connected service ref (deallocate with DNSServiceRefDeallocate)
+static DNSServiceRef connect_to_server(void)
+    {
+       dnssd_sockaddr_t saddr;
+       DNSServiceRef sdr;
+       static unsigned int NumTries = 0;
+
+#if defined(_WIN32)
+       if (!g_initWinsock)
+               {
+               WSADATA wsaData;
+               DNSServiceErrorType err;
+               
+               g_initWinsock = 1;
+
+               err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
+
+               if (err != 0) return NULL;
+               }
+#endif
+
+       sdr = malloc(sizeof(_DNSServiceRef_t));
+       if (!sdr) return(NULL);
+       sdr->sockfd = socket(AF_DNSSD, SOCK_STREAM, 0);
+       if (sdr->sockfd == dnssd_InvalidSocket) { free(sdr); return NULL; }
+#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);
+#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 ten seconds, we still can't connect to the daemon,
+               // then we give up and return a failure code.
+               if (++NumTries < 3)
+                       sleep(1);               // Sleep a bit, then try again
+               else
+                       {
+                       dnssd_close(sdr->sockfd);
+                       sdr->sockfd = dnssd_InvalidSocket;
+                       free(sdr);
+                       return NULL;
+                       }
+               }
+    return sdr;
+       }
+
+static DNSServiceErrorType deliver_request(void *msg, DNSServiceRef sdr, int reuse_sd)
+    {
+    ipc_msg_hdr *hdr = msg;
+    uint32_t datalen = hdr->datalen;
+    dnssd_sockaddr_t caddr, daddr;  // (client and daemon address structs)
+    char *data = (char *)msg + sizeof(ipc_msg_hdr);
+    dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
+       int ret;
+       unsigned int len = sizeof(caddr);
+    DNSServiceErrorType err = kDNSServiceErr_Unknown;
+
+    if (!hdr || sdr->sockfd < 0) return kDNSServiceErr_Unknown;
+
+       if (!reuse_sd)
+               {
+        // setup temporary error socket
+        if ((listenfd = socket(AF_DNSSD, SOCK_STREAM, 0)) < 0)
+            goto cleanup;
+        bzero(&caddr, sizeof(caddr));
+
+#if defined(USE_TCP_LOOPBACK)
+                       {
+                       union { uint16_t s; u_char b[2]; } port;
+                       caddr.sin_family      = AF_INET;
+                       caddr.sin_port        = 0;
+                       caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
+                       ret = bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr));
+                       if (ret < 0) goto cleanup;
+                       if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) goto cleanup;
+                       listen(listenfd, 1);
+                       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
+                       }
+#else
+                       {
+                       mode_t mask = umask(0);
+                       caddr.sun_family = AF_LOCAL;
+#ifndef NOT_HAVE_SA_LEN                // According to Stevens (section 3.2), there is no portable way to
+                                                               // determine whether sa_len is defined on a particular platform.
+                       caddr.sun_len = sizeof(struct sockaddr_un);
+#endif
+                       strcpy(caddr.sun_path, data);
+                       ret = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
+                       umask(mask);
+                       if (ret < 0) goto cleanup;
+                       listen(listenfd, 1);
+                       }
+#endif
+               }
+
+       ConvertHeaderBytes(hdr);
+    if (my_write(sdr->sockfd, msg, datalen + sizeof(ipc_msg_hdr)) < 0)
+        goto cleanup;
+    free(msg);
+    msg = NULL;
+
+    if (reuse_sd) errsd = sdr->sockfd;
+    else
+        {
+        len = sizeof(daddr);
+        errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
+        if (errsd < 0)  goto cleanup;
+        }
+
+    if (my_read(errsd, (char*)&err, (int)sizeof(err)) < 0)
+        err = kDNSServiceErr_Unknown;
+    else
+       err = ntohl(err);
+
+cleanup:
+    if (!reuse_sd && listenfd > 0) dnssd_close(listenfd);
+    if (!reuse_sd && errsd > 0) dnssd_close(errsd);
+#if !defined(USE_TCP_LOOPBACK)
+    if (!reuse_sd && data) unlink(data);
+#endif
+    if (msg) free(msg);
+    return err;
+    }
+
+int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
     {
     if (!sdRef) return -1;
-    return sdRef->sockfd;
+    return (int) sdRef->sockfd;
     }
 
 // 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 DNSServiceProcessResult(DNSServiceRef sdRef)
+DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
     {
     ipc_msg_hdr hdr;
     char *data;
 
-    if (!sdRef || sdRef->sockfd < 0 || !sdRef->process_reply) 
+    if (!sdRef || sdRef->sockfd < 0 || !sdRef->process_reply)
         return kDNSServiceErr_BadReference;
 
-    if (my_read(sdRef->sockfd, (void *)&hdr, sizeof(hdr)) < 0) 
-        return kDNSServiceErr_Unknown;
+    if (my_read(sdRef->sockfd, (void *)&hdr, sizeof(hdr)) < 0)
+               // 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.
+               return (dnssd_errno() == dnssd_EWOULDBLOCK) ? kDNSServiceErr_NoError : kDNSServiceErr_Unknown;
+       ConvertHeaderBytes(&hdr);
     if (hdr.version != VERSION)
         return kDNSServiceErr_Incompatible;
     data = malloc(hdr.datalen);
     if (!data) return kDNSServiceErr_NoMemory;
-    if (my_read(sdRef->sockfd, data, hdr.datalen) < 0) 
+    if (my_read(sdRef->sockfd, data, hdr.datalen) < 0)
         return kDNSServiceErr_Unknown;
     sdRef->process_reply(sdRef, &hdr, data);
     free(data);
     return kDNSServiceErr_NoError;
     }
 
-
-void DNSServiceRefDeallocate(DNSServiceRef sdRef)
+void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
     {
     if (!sdRef) return;
-    if (sdRef->sockfd > 0) close(sdRef->sockfd);
+    if (sdRef->sockfd > 0) dnssd_close(sdRef->sockfd);
     free(sdRef);
     }
 
+static void handle_resolve_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
+    {
+    DNSServiceFlags flags;
+    char fullname[kDNSServiceMaxDomainName];
+    char target[kDNSServiceMaxDomainName];
+    uint16_t txtlen;
+    union { uint16_t s; u_char b[2]; } port;
+    uint32_t ifi;
+    DNSServiceErrorType err;
+    char *txtrecord;
+    int str_error = 0;
+    (void)hdr;                 //unused
+
+    flags = get_flags(&data);
+    ifi = get_long(&data);
+    err = get_error_code(&data);
+    if (get_string(&data, fullname, kDNSServiceMaxDomainName) < 0) str_error = 1;
+    if (get_string(&data, target, kDNSServiceMaxDomainName) < 0) str_error = 1;
+    port.b[0] = *data++;
+    port.b[1] = *data++;
+    txtlen = get_short(&data);
+    txtrecord = get_rdata(&data, txtlen);
+
+       if (!err && str_error) err = kDNSServiceErr_Unknown;
+    ((DNSServiceResolveReply)sdr->app_callback)(sdr, flags, ifi, err, fullname, target, port.s, txtlen, txtrecord, sdr->app_context);
+    }
 
-DNSServiceErrorType DNSServiceResolve
+DNSServiceErrorType DNSSD_API DNSServiceResolve
     (
     DNSServiceRef                      *sdRef,
-    const DNSServiceFlags               flags,
-    const uint32_t                      interfaceIndex,
+    DNSServiceFlags               flags,
+    uint32_t                      interfaceIndex,
     const char                                 *name,
     const char                                 *regtype,
     const char                                 *domain,
-    const DNSServiceResolveReply        callBack,
+    DNSServiceResolveReply        callBack,
     void                                       *context
     )
     {
     char *msg = NULL, *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr;
     DNSServiceRef sdr;
     DNSServiceErrorType err;
-    
+
     if (!sdRef) return kDNSServiceErr_BadParam;
     *sdRef = NULL;
-    
+
+       if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
+
     // calculate total message length
     len = sizeof(flags);
     len += sizeof(interfaceIndex);
@@ -145,7 +547,7 @@ DNSServiceErrorType DNSServiceResolve
     put_string(name, &ptr);
     put_string(regtype, &ptr);
     put_string(domain, &ptr);
-    
+
     sdr = connect_to_server();
     if (!sdr) goto error;
     err = deliver_request(msg, sdr, 1);
@@ -159,7 +561,7 @@ DNSServiceErrorType DNSServiceResolve
     sdr->app_callback = callBack;
     sdr->app_context = context;
     *sdRef = sdr;
-    
+
     return err;
 
 error:
@@ -167,53 +569,52 @@ error:
     if (*sdRef) { free(*sdRef);  *sdRef = NULL; }
     return kDNSServiceErr_Unknown;
     }
-    
-    
-static void handle_resolve_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
+
+static void handle_query_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
     {
     DNSServiceFlags flags;
-    char fullname[kDNSServiceMaxDomainName];
-    char target[kDNSServiceMaxDomainName];
-    uint16_t port, txtlen;
-    uint32_t ifi;
-    DNSServiceErrorType err;
-    char *txtrecord;
-    
-    (void)hdr;                 //unused
-    
+    uint32_t interfaceIndex, ttl;
+    DNSServiceErrorType errorCode;
+    char name[kDNSServiceMaxDomainName];
+    uint16_t rrtype, rrclass, rdlen;
+    char *rdata;
+    int str_error = 0;
+    (void)hdr;//Unused
+
     flags = get_flags(&data);
-    ifi = get_long(&data);
-    err = get_error_code(&data);
-    get_string(&data, fullname, kDNSServiceMaxDomainName);
-    get_string(&data, target, kDNSServiceMaxDomainName);
-    port = get_short(&data);
-    txtlen = get_short(&data);
-    txtrecord = get_rdata(&data, txtlen);
-    
-    ((DNSServiceResolveReply)sdr->app_callback)(sdr, flags, ifi, err, fullname, target, port, txtlen, txtrecord, sdr->app_context);
-    }
-    
-    
+    interfaceIndex = get_long(&data);
+    errorCode = get_error_code(&data);
+    if (get_string(&data, name, kDNSServiceMaxDomainName) < 0) str_error = 1;
+    rrtype = get_short(&data);
+    rrclass = get_short(&data);
+    rdlen = get_short(&data);
+    rdata = get_rdata(&data, rdlen);
+       ttl = get_long(&data);
 
+       if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
+       ((DNSServiceQueryRecordReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, name, rrtype, rrclass,
+                                                                                                       rdlen, rdata, ttl, sdr->app_context);
+    return;
+    }
 
-DNSServiceErrorType DNSServiceQueryRecord
+DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
 (
  DNSServiceRef                         *sdRef,
const DNSServiceFlags                  flags,
const uint32_t                        interfaceIndex,
DNSServiceFlags                        flags,
uint32_t                              interfaceIndex,
  const char                            *name,
const uint16_t                        rrtype,
const uint16_t                        rrclass,
const DNSServiceQueryRecordReply      callBack,
uint16_t                              rrtype,
uint16_t                              rrclass,
DNSServiceQueryRecordReply            callBack,
  void                                  *context
  )
     {
     char *msg = NULL, *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr;
     DNSServiceRef sdr;
     DNSServiceErrorType err;
-    
+
     if (!sdRef) return kDNSServiceErr_BadParam;
     *sdRef = NULL;
 
@@ -257,45 +658,39 @@ error:
     return kDNSServiceErr_Unknown;
     }
 
-
-static void handle_query_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
+static void handle_browse_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
     {
-    DNSServiceFlags flags;
-    uint32_t interfaceIndex, ttl;
-    DNSServiceErrorType errorCode;
-    char name[256]; 
-    uint16_t rrtype, rrclass, rdlen;
-    char *rdata;
-    (void)hdr;//Unused
+    DNSServiceFlags      flags;
+    uint32_t                      interfaceIndex;
+    DNSServiceErrorType      errorCode;
+    char replyName[256], replyType[kDNSServiceMaxDomainName],
+        replyDomain[kDNSServiceMaxDomainName];
+    int str_error = 0;
+       (void)hdr;//Unused
 
     flags = get_flags(&data);
     interfaceIndex = get_long(&data);
     errorCode = get_error_code(&data);
-    (get_string(&data, name, 256) < 0);
-    rrtype = get_short(&data);
-    rrclass = get_short(&data);
-    rdlen = get_short(&data);
-    rdata = get_rdata(&data, rdlen);
-    ttl = get_long(&data);
-    if (!rdata) return;
-    ((DNSServiceQueryRecordReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, name, rrtype, rrclass,
-                                              rdlen, rdata, ttl, sdr->app_context);
-    return;
+    if (get_string(&data, replyName, 256) < 0) str_error = 1;
+    if (get_string(&data, replyType, kDNSServiceMaxDomainName) < 0) str_error = 1;
+    if (get_string(&data, replyDomain, kDNSServiceMaxDomainName) < 0) str_error = 1;
+       if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
+       ((DNSServiceBrowseReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, replyName, replyType, replyDomain, sdr->app_context);
     }
 
-DNSServiceErrorType DNSServiceBrowse
+DNSServiceErrorType DNSSD_API DNSServiceBrowse
 (
  DNSServiceRef                      *sdRef,
const DNSServiceFlags              flags,
const uint32_t                     interfaceIndex,
+ DNSServiceFlags              flags,
+ uint32_t                     interfaceIndex,
  const char                         *regtype,
  const char                         *domain,
const DNSServiceBrowseReply        callBack,
+ DNSServiceBrowseReply        callBack,
  void                               *context
  )
     {
     char *msg = NULL, *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr;
     DNSServiceRef sdr;
     DNSServiceErrorType err;
@@ -339,48 +734,71 @@ error:
     return kDNSServiceErr_Unknown;
     }
 
+DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser
+(
+ DNSServiceFlags                    flags,
+ const char                         *domain
+ )
+    {
+    DNSServiceRef sdr;
+    DNSServiceErrorType err;
+    char *ptr = NULL;
+    size_t len = sizeof(flags) + strlen(domain) + 1;
+    ipc_msg_hdr *hdr = create_hdr(setdomain_request, &len, &ptr, 1);
+
+    if (!hdr) return kDNSServiceErr_Unknown;
+    put_flags(flags, &ptr);
+    put_string(domain, &ptr);
 
+    sdr = connect_to_server();
+    if (!sdr) { free(hdr); return kDNSServiceErr_Unknown; }
+    err = deliver_request((char *)hdr, sdr, 1);                // deliver_request frees the message for us
+       DNSServiceRefDeallocate(sdr);
+       return err;
+    }
 
 
-static void handle_browse_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
+static void handle_regservice_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
     {
-    DNSServiceFlags      flags;
-    uint32_t                      interfaceIndex;
-    DNSServiceErrorType      errorCode;
-    char replyName[256], replyType[256], replyDomain[256];
+    DNSServiceFlags flags;
+    uint32_t interfaceIndex;
+    DNSServiceErrorType errorCode;
+    char name[256], regtype[kDNSServiceMaxDomainName], domain[kDNSServiceMaxDomainName];
+    int str_error = 0;
        (void)hdr;//Unused
 
     flags = get_flags(&data);
     interfaceIndex = get_long(&data);
     errorCode = get_error_code(&data);
-    get_string(&data, replyName, 256);
-    get_string(&data, replyType, 256);
-    get_string(&data, replyDomain, 256);
-    ((DNSServiceBrowseReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, replyName, replyType, replyDomain, sdr->app_context);
+    if (get_string(&data, name, 256) < 0) str_error = 1;
+    if (get_string(&data, regtype, kDNSServiceMaxDomainName) < 0) str_error = 1;
+    if (get_string(&data, domain, kDNSServiceMaxDomainName) < 0) str_error = 1;
+       if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
+    ((DNSServiceRegisterReply)sdr->app_callback)(sdr, flags, errorCode, name, regtype, domain, sdr->app_context);
     }
 
-
-DNSServiceErrorType DNSServiceRegister
+DNSServiceErrorType DNSSD_API DNSServiceRegister
     (
     DNSServiceRef                       *sdRef,
-    const DNSServiceFlags               flags,
-    const uint32_t                      interfaceIndex,
-    const char                          *name,         
-    const char                          *regtype,  
-    const char                          *domain,       
-    const char                          *host,         
-    const uint16_t                      port,
-    const uint16_t                      txtLen,
-    const void                          *txtRecord,    
-    const DNSServiceRegisterReply       callBack,      
-    void                                *context       
+    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 *msg = NULL, *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr;
     DNSServiceRef sdr;
     DNSServiceErrorType err;
+    union { uint16_t s; u_char b[2]; } port = { PortInNetworkByteOrder };
 
     if (!sdRef) return kDNSServiceErr_BadParam;
     *sdRef = NULL;
@@ -389,8 +807,8 @@ DNSServiceErrorType DNSServiceRegister
     if (!regtype) return kDNSServiceErr_BadParam;
     if (!domain) domain = "";
     if (!host) host = "";
-    if (!txtRecord) (char *)txtRecord = "";
-    
+    if (!txtRecord) txtRecord = (void*)"";
+
     // auto-name must also have auto-rename
     if (!name[0]  && (flags & kDNSServiceFlagsNoAutoRename))
         return kDNSServiceErr_BadParam;
@@ -414,7 +832,8 @@ DNSServiceErrorType DNSServiceRegister
     put_string(regtype, &ptr);
     put_string(domain, &ptr);
     put_string(host, &ptr);
-    put_short(port, &ptr);
+    *ptr++ = port.b[0];
+    *ptr++ = port.b[1];
     put_short(txtLen, &ptr);
     put_rdata(txtLen, txtRecord, &ptr);
 
@@ -426,7 +845,7 @@ DNSServiceErrorType DNSServiceRegister
         DNSServiceRefDeallocate(sdr);
         return err;
         }
-        
+
     sdr->op = reg_service_request;
     sdr->process_reply = callBack ? handle_regservice_response : NULL;
     sdr->app_callback = callBack;
@@ -434,51 +853,52 @@ DNSServiceErrorType DNSServiceRegister
     *sdRef = sdr;
 
     return err;
-    
+
 error:
     if (msg) free(msg);
     if (*sdRef)        { free(*sdRef);  *sdRef = NULL; }
     return kDNSServiceErr_Unknown;
     }
 
-
-static void handle_regservice_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
+static void handle_enumeration_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
     {
     DNSServiceFlags flags;
     uint32_t interfaceIndex;
-    DNSServiceErrorType errorCode;
-    char name[256], regtype[256], domain[256];
+    DNSServiceErrorType err;
+    char domain[kDNSServiceMaxDomainName];
+    int str_error = 0;
        (void)hdr;//Unused
 
     flags = get_flags(&data);
     interfaceIndex = get_long(&data);
-    errorCode = get_error_code(&data);
-    get_string(&data, name, 256);
-    get_string(&data, regtype, 256);
-    get_string(&data, domain, 256);
-    ((DNSServiceRegisterReply)sdr->app_callback)(sdr, flags, errorCode, name, regtype, domain, sdr->app_context);
+    err = get_error_code(&data);
+    if (get_string(&data, domain, kDNSServiceMaxDomainName) < 0) str_error = 1;
+       if (!err && str_error) err = kDNSServiceErr_Unknown;
+    ((DNSServiceDomainEnumReply)sdr->app_callback)(sdr, flags, interfaceIndex, err, domain, sdr->app_context);
     }
 
-DNSServiceErrorType DNSServiceEnumerateDomains
+DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
 (
  DNSServiceRef                    *sdRef,
const DNSServiceFlags            flags,
const uint32_t                   interfaceIndex,
const DNSServiceDomainEnumReply  callBack,
+ DNSServiceFlags            flags,
+ uint32_t                   interfaceIndex,
+ DNSServiceDomainEnumReply  callBack,
  void                             *context
  )
     {
     char *msg = NULL, *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr;
     DNSServiceRef sdr;
     DNSServiceErrorType err;
-
+    int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
+    int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
+    if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
 
     if (!sdRef) return kDNSServiceErr_BadParam;
     *sdRef = NULL;
 
-    len = sizeof(DNSServiceFlags);
+       len = sizeof(DNSServiceFlags);
     len += sizeof(uint32_t);
 
     hdr = create_hdr(enumeration_request, &len, &ptr, 1);
@@ -510,24 +930,26 @@ error:
     return kDNSServiceErr_Unknown;
     }
 
-
-static void handle_enumeration_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
+static void handle_regrecord_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
     {
     DNSServiceFlags flags;
     uint32_t interfaceIndex;
-    DNSServiceErrorType err;
-    char domain[256];
-       (void)hdr;//Unused
+    DNSServiceErrorType errorCode;
+    DNSRecordRef rref = hdr->client_context.context;
 
+    if (sdr->op != connection)
+        {
+        rref->app_callback(rref->sdr, rref, 0, kDNSServiceErr_Unknown, rref->app_context);
+        return;
+        }
     flags = get_flags(&data);
     interfaceIndex = get_long(&data);
-    err = get_error_code(&data);
-    get_string(&data, domain, 256);
-    ((DNSServiceDomainEnumReply)sdr->app_callback)(sdr, flags, interfaceIndex, err, domain, sdr->app_context);
-    }
+    errorCode = get_error_code(&data);
 
+    rref->app_callback(rref->sdr, rref, flags, errorCode, rref->app_context);
+    }
 
-DNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef)
+DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
     {
     if (!sdRef) return kDNSServiceErr_BadParam;
     *sdRef = connect_to_server();
@@ -538,54 +960,36 @@ DNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef)
     return 0;
     }
 
-
-
-static void handle_regrecord_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags flags;
-    uint32_t interfaceIndex;
-    DNSServiceErrorType errorCode;
-    DNSRecordRef rref = hdr->client_context.context;
-    
-    if (sdr->op != connection) 
-        {
-        rref->app_callback(rref->sdr, rref, 0, kDNSServiceErr_Unknown, rref->app_context);
-        return;
-        }
-    flags = get_flags(&data);
-    interfaceIndex = get_long(&data);
-    errorCode = get_error_code(&data);
-
-    rref->app_callback(rref->sdr, rref, flags, errorCode, rref->app_context);
-    }
-
-DNSServiceErrorType DNSServiceRegisterRecord
+DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
 (
const DNSServiceRef                   sdRef,
- DNSRecordRef                          *RecordRef,  
const DNSServiceFlags                 flags,
const uint32_t                        interfaceIndex,
DNSServiceRef                 sdRef,
+ DNSRecordRef                          *RecordRef,
DNSServiceFlags               flags,
uint32_t                              interfaceIndex,
  const char                            *fullname,
const uint16_t                        rrtype,
const uint16_t                        rrclass,
const uint16_t                        rdlen,
uint16_t                              rrtype,
uint16_t                              rrclass,
uint16_t                              rdlen,
  const void                            *rdata,
const uint32_t                        ttl,
const DNSServiceRegisterRecordReply   callBack,
uint32_t                              ttl,
DNSServiceRegisterRecordReply         callBack,
  void                                  *context
  )
     {
     char *msg = NULL, *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr = NULL;
     DNSServiceRef tmp = NULL;
     DNSRecordRef rref = NULL;
-    
-    if (!sdRef || sdRef->op != connection || sdRef->sockfd < 0) 
+    int f1 = (flags & kDNSServiceFlagsShared) != 0;
+    int f2 = (flags & kDNSServiceFlagsUnique) != 0;
+    if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
+
+    if (!sdRef || sdRef->op != connection || sdRef->sockfd < 0)
         return kDNSServiceErr_BadReference;
     *RecordRef = NULL;
-    
-    len = sizeof(DNSServiceFlags);
+
+       len = sizeof(DNSServiceFlags);
     len += 2 * sizeof(uint32_t);  // interfaceIndex, ttl
     len += 3 * sizeof(uint16_t);  // rrtype, rrclass, rdlen
     len += strlen(fullname) + 1;
@@ -611,8 +1015,8 @@ DNSServiceErrorType DNSServiceRegisterRecord
     rref->sdr = sdRef;
     *RecordRef = rref;
     hdr->client_context.context = rref;
-    hdr->reg_index = rref->record_index;  
-    
+    hdr->reg_index = rref->record_index;
+
     return deliver_request(msg, sdRef, 0);
 
 error:
@@ -623,26 +1027,26 @@ error:
     }
 
 //sdRef returned by DNSServiceRegister()
-DNSServiceErrorType DNSServiceAddRecord
+DNSServiceErrorType DNSSD_API DNSServiceAddRecord
     (
-    const DNSServiceRef                        sdRef,
+    DNSServiceRef                      sdRef,
     DNSRecordRef                       *RecordRef,
-    const DNSServiceFlags               flags,
-    const uint16_t                     rrtype,
-    const uint16_t                     rdlen,
+    DNSServiceFlags               flags,
+    uint16_t                   rrtype,
+    uint16_t                   rdlen,
     const void                         *rdata,
-    const uint32_t                     ttl
+    uint32_t                   ttl
     )
     {
     ipc_msg_hdr *hdr;
-    int len = 0;
+    size_t len = 0;
     char *ptr;
     DNSRecordRef rref;
 
-    if (!sdRef || (sdRef->op != reg_service_request) || !RecordRef) 
+    if (!sdRef || (sdRef->op != reg_service_request) || !RecordRef)
         return kDNSServiceErr_BadReference;
     *RecordRef = NULL;
-    
+
     len += 2 * sizeof(uint16_t);  //rrtype, rdlen
     len += rdlen;
     len += sizeof(uint32_t);
@@ -664,7 +1068,7 @@ DNSServiceErrorType DNSServiceAddRecord
     rref->sdr = sdRef;
     *RecordRef = rref;
     hdr->client_context.context = rref;
-    hdr->reg_index = rref->record_index;  
+    hdr->reg_index = rref->record_index;
     return deliver_request((char *)hdr, sdRef, 0);
 
 error:
@@ -673,26 +1077,24 @@ error:
     if (*RecordRef) *RecordRef = NULL;
     return kDNSServiceErr_Unknown;
 }
-    
 
 //DNSRecordRef returned by DNSServiceRegisterRecord or DNSServiceAddRecord
-DNSServiceErrorType DNSServiceUpdateRecord
+DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
     (
-    const DNSServiceRef                sdRef,
+    DNSServiceRef              sdRef,
     DNSRecordRef                       RecordRef,
-    const DNSServiceFlags               flags,
-    const uint16_t                     rdlen,
+    DNSServiceFlags               flags,
+    uint16_t                   rdlen,
     const void                         *rdata,
-    const uint32_t                     ttl
+    uint32_t                   ttl
     )
     {
     ipc_msg_hdr *hdr;
-    int len = 0;
+    size_t len = 0;
     char *ptr;
 
-    if (!sdRef || !RecordRef || !sdRef->max_index) 
-        return kDNSServiceErr_BadReference;
-    
+       if (!sdRef) return kDNSServiceErr_BadReference;
+
     len += sizeof(uint16_t);
     len += rdlen;
     len += sizeof(uint32_t);
@@ -707,24 +1109,22 @@ DNSServiceErrorType DNSServiceUpdateRecord
     put_long(ttl, &ptr);
     return deliver_request((char *)hdr, sdRef, 0);
     }
-    
-
 
-DNSServiceErrorType DNSServiceRemoveRecord
+DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
 (
const DNSServiceRef            sdRef,
const DNSRecordRef                    RecordRef,
const DNSServiceFlags          flags
+ DNSServiceRef            sdRef,
DNSRecordRef                  RecordRef,
+ DNSServiceFlags          flags
  )
     {
     ipc_msg_hdr *hdr;
-    int len = 0;
+    size_t len = 0;
     char *ptr;
     DNSServiceErrorType err;
 
-    if (!sdRef || !RecordRef || !sdRef->max_index) 
+    if (!sdRef || !RecordRef || !sdRef->max_index)
         return kDNSServiceErr_BadReference;
-    
+
     len += sizeof(flags);
     hdr = create_hdr(remove_record_request, &len, &ptr, 0);
     if (!hdr) return kDNSServiceErr_Unknown;
@@ -735,20 +1135,19 @@ DNSServiceErrorType DNSServiceRemoveRecord
     return err;
     }
 
-
-void DNSServiceReconfirmRecord
+void DNSSD_API DNSServiceReconfirmRecord
 (
const DNSServiceFlags              flags,
const uint32_t                     interfaceIndex,
+ DNSServiceFlags              flags,
+ uint32_t                     interfaceIndex,
  const char                         *fullname,
const uint16_t                     rrtype,
const uint16_t                     rrclass,
const uint16_t                     rdlen,
+ uint16_t                     rrtype,
+ uint16_t                     rrclass,
+ uint16_t                     rdlen,
  const void                         *rdata
  )
     {
     char *ptr;
-    int len;
+    size_t len;
     ipc_msg_hdr *hdr;
     DNSServiceRef tmp;
 
@@ -769,224 +1168,9 @@ void DNSServiceReconfirmRecord
     put_short(rrclass, &ptr);
     put_short(rdlen, &ptr);
     put_rdata(rdlen, rdata, &ptr);
-    my_write(tmp->sockfd, (char *)hdr, len);
+       ConvertHeaderBytes(hdr);
+    my_write(tmp->sockfd, (char *)hdr, (int) len);
+    free(hdr);
     DNSServiceRefDeallocate(tmp);
     }
-        
-        
-int DNSServiceConstructFullName 
-    (
-    char                      *fullName,
-    const char                *service,      /* may be NULL */
-    const char                *regtype,
-    const char                *domain
-    )
-    {
-    int len;
-    u_char c;
-    char *fn = fullName;
-    const char *s = service;
-    const char *r = regtype;
-    const char *d = domain;
-    
-    if (service)
-        {
-        while(*s)
-            {
-            c = *s++;
-            if (c == '.' || (c == '\\')) *fn++ = '\\';         // escape dot and backslash literals
-            else if (c <= ' ')                                 // escape non-printable characters
-                {
-                *fn++ = '\\';
-               *fn++ = (char) ('0' + (c / 100));
-               *fn++ = (char) ('0' + (c / 10) % 10);
-                c = (u_char)('0' + (c % 10));
-                }
-                *fn++ = c;
-            }
-        *fn++ = '.';
-        }
-
-    if (!regtype) return -1;
-    len = strlen(regtype);
-    if (domain_ends_in_dot(regtype)) len--;
-    if (len < 4) return -1;                                    // regtype must end in _udp or _tcp
-    if (strncmp((regtype + len - 4), "_tcp", 4) && strncmp((regtype + len - 4), "_udp", 4)) return -1;
-    while(*r)
-        *fn++ = *r++;                                                                                                                                                                                        
-    if (!domain_ends_in_dot(regtype)) *fn++ = '.';
-                                                                                        
-    if (!domain) return -1;
-    len = strlen(domain);
-    if (!len) return -1;
-    while(*d) 
-        *fn++ = *d++;                                          
-    if (!domain_ends_in_dot(domain)) *fn++ = '.';
-    *fn = '\0';
-    return 0;
-    }
-        
-static int domain_ends_in_dot(const char *dom)
-    {
-    while(*dom && *(dom + 1))
-        {
-        if (*dom == '\\')      // advance past escaped byte sequence
-            {          
-            if (*(dom + 1) >= '0' && *(dom + 1) <= '9') dom += 4;
-            else dom += 2;
-            }
-        else dom++;            // else read one character
-        }
-        return (*dom == '.');
-    }
-
-
-
-    // return a connected service ref (deallocate with DNSServiceRefDeallocate)
-static DNSServiceRef connect_to_server(void)
-    {
-    struct sockaddr_un saddr;
-    DNSServiceRef sdr;
-
-    sdr = malloc(sizeof(_DNSServiceRef_t));
-    if (!sdr) return NULL;
-
-    if ((sdr->sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) 
-       {
-        free(sdr);
-        return NULL;
-       }
-
-    saddr.sun_family = AF_LOCAL;
-    strcpy(saddr.sun_path, MDNS_UDS_SERVERPATH);
-    if (connect(sdr->sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
-       {
-        free(sdr);
-        return NULL;
-       }
-    return sdr;        
-    }
-
-
-
-
-int my_write(int sd, char *buf, int len)
-    {
-    if (send(sd, buf, len, MSG_WAITALL) != len)   return -1;
-    return 0;
-    }
-
-
-// read len bytes.  return 0 on success, -1 on error
-int my_read(int sd, char *buf, int len)
-    {
-    if (recv(sd, buf, len, MSG_WAITALL) != len)  return -1;
-    return 0;
-    }
-
-
-DNSServiceErrorType deliver_request(void *msg, DNSServiceRef sdr, int reuse_sd)
-    {
-    ipc_msg_hdr *hdr = msg;
-    mode_t mask;
-    struct sockaddr_un caddr, daddr;  // (client and daemon address structs)
-    char *path = NULL;
-    int listenfd = -1, errsd = -1, len;
-    DNSServiceErrorType err = kDNSServiceErr_Unknown;
-    
-    if (!hdr || sdr->sockfd < 0) return kDNSServiceErr_Unknown;
-
-    if (!reuse_sd) 
-        {
-        // setup temporary error socket
-        if ((listenfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) 
-            goto cleanup;
-
-        bzero(&caddr, sizeof(caddr));
-        caddr.sun_family = AF_LOCAL;
-       caddr.sun_len = sizeof(struct sockaddr_un);
-       path = (char *)msg + sizeof(ipc_msg_hdr);
-        strcpy(caddr.sun_path, path);
-        mask = umask(0);
-        if (bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr)) < 0)
-         {
-           umask(mask);
-            goto cleanup;
-         }
-        umask(mask);
-        listen(listenfd, 1);
-        }
-        
-    if (my_write(sdr->sockfd, msg, hdr->datalen + sizeof(ipc_msg_hdr)) < 0)  
-        goto cleanup;
-    free(msg);
-    msg = NULL;
 
-    if (reuse_sd) errsd = sdr->sockfd;
-    else 
-        {
-        len = sizeof(daddr);
-        errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
-        if (errsd < 0)  goto cleanup;
-        }
-    
-    len = recv(errsd, &err, sizeof(err), MSG_WAITALL);
-    if (len != sizeof(err))
-        {
-        err = kDNSServiceErr_Unknown;
-        }
-cleanup:
-    if (!reuse_sd && listenfd > 0) close(listenfd);
-    if (!reuse_sd && errsd > 0) close(errsd);  
-    if (!reuse_sd && path) unlink(path);
-    if (msg) free(msg);
-    return err;
-    }
-    
-    
-    
-/* 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.  reuse_socket should be non-zero
- * for calls that can receive an immediate error return value on their primary socket.
- * 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(int op, int *len, char **data_start, int reuse_socket)
-    {
-    char *msg = NULL;
-    ipc_msg_hdr *hdr;
-    int datalen;
-    char ctrl_path[256];
-    struct timeval time;
-
-    if (!reuse_socket)
-        {
-         if (gettimeofday(&time, NULL) < 0) return NULL;
-         sprintf(ctrl_path, "%s%d-%.3x-%.6u", CTL_PATH_PREFIX, (int)getpid(), 
-                 time.tv_sec & 0xFFF, time.tv_usec);
-
-        *len += strlen(ctrl_path) + 1;
-        }
-    
-        
-    datalen = *len;
-    *len += sizeof(ipc_msg_hdr);
-
-    // write message to buffer
-    msg = malloc(*len);
-    if (!msg) return NULL;
-
-    bzero(msg, *len);
-    hdr = (void *)msg;
-    hdr->datalen = datalen;
-    hdr->version = VERSION;
-    hdr->op.request_op = op;
-    if (reuse_socket) hdr->flags |= IPC_FLAGS_REUSE_SOCKET;
-    *data_start = msg + sizeof(ipc_msg_hdr);
-    if (!reuse_socket)  put_string(ctrl_path, data_start);
-    return hdr;
-    }