/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2003-2012 Apple Computer, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if defined(_WIN32)
#include <process.h>
#define usleep(X) Sleep(((X)+999)/1000)
#else
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#endif

#include <stdlib.h>
#include <stdio.h>

#include "mDNSEmbeddedAPI.h"
#include "DNSCommon.h"
#include "uDNS.h"
#include "uds_daemon.h"

// Normally we append search domains only for queries with a single label that are not
// fully qualified. This can be overridden to apply search domains for queries (that are
// not fully qualified) with any number of labels e.g., moon, moon.cs, moon.cs.be, etc.
mDNSBool AlwaysAppendSearchDomains = mDNSfalse;

// Apple-specific functionality, not required for other platforms
#if APPLE_OSX_mDNSResponder
#include <sys/ucred.h>
#ifndef PID_FILE
#define PID_FILE ""
#endif
#endif

#ifdef LOCAL_PEERPID
#include <sys/un.h>         // for LOCAL_PEERPID
#include <sys/socket.h>     // for getsockopt
#include <sys/proc_info.h>  // for struct proc_bsdshortinfo
#include <libproc.h>        // for proc_pidinfo()
#endif //LOCAL_PEERPID

#if APPLE_OSX_mDNSResponder
#include <WebFilterDNS/WebFilterDNS.h>

#if !NO_WCF

int WCFIsServerRunning(WCFConnection *conn) __attribute__((weak_import));
int WCFNameResolvesToAddr(WCFConnection *conn, char* domainName, struct sockaddr* address, uid_t userid) __attribute__((weak_import));
int WCFNameResolvesToName(WCFConnection *conn, char* fromName, char* toName, uid_t userid) __attribute__((weak_import));

// Do we really need to define a macro for "if"?
#define CHECK_WCF_FUNCTION(X) if (X)
#endif // ! NO_WCF

#else
#define NO_WCF 1
#endif // APPLE_OSX_mDNSResponder

// User IDs 0-500 are system-wide processes, not actual users in the usual sense
// User IDs for real user accounts start at 501 and count up from there
#define SystemUID(X) ((X) <= 500)

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Types and Data Structures
#endif

typedef enum
{
    t_uninitialized,
    t_morecoming,
    t_complete,
    t_error,
    t_terminated
} transfer_state;

typedef struct request_state request_state;

typedef void (*req_termination_fn)(request_state *request);

typedef struct registered_record_entry
{
    struct registered_record_entry *next;
    mDNSu32 key;
    client_context_t regrec_client_context;
    request_state *request;
    mDNSBool external_advertise;
    mDNSInterfaceID origInterfaceID;
    AuthRecord *rr;             // Pointer to variable-sized AuthRecord (Why a pointer? Why not just embed it here?)
} registered_record_entry;

// A single registered service: ServiceRecordSet + bookkeeping
// Note that we duplicate some fields from parent service_info object
// to facilitate cleanup, when instances and parent may be deallocated at different times.
typedef struct service_instance
{
    struct service_instance *next;
    request_state *request;
    AuthRecord *subtypes;
    mDNSBool renameonmemfree;       // Set on config change when we deregister original name
    mDNSBool clientnotified;        // Has client been notified of successful registration yet?
    mDNSBool default_local;         // is this the "local." from an empty-string registration?
    mDNSBool external_advertise;    // is this is being advertised externally?
    domainname domain;
    ServiceRecordSet srs;           // note -- variable-sized object -- must be last field in struct
} service_instance;

// for multi-domain default browsing
typedef struct browser_t
{
    struct browser_t *next;
    domainname domain;
    DNSQuestion q;
} browser_t;

struct request_state
{
    request_state *next;
    request_state *primary;         // If this operation is on a shared socket, pointer to primary
                                    // request_state for the original DNSServiceCreateConnection() operation
    dnssd_sock_t sd;
    dnssd_sock_t errsd;
    mDNSu32 uid;
    void * platform_data;

    // Note: On a shared connection these fields in the primary structure, including hdr, are re-used
    // for each new request. This is because, until we've read the ipc_msg_hdr to find out what the
    // operation is, we don't know if we're going to need to allocate a new request_state or not.
    transfer_state ts;
    mDNSu32 hdr_bytes;              // bytes of header already read
    ipc_msg_hdr hdr;
    mDNSu32 data_bytes;             // bytes of message data already read
    char          *msgbuf;          // pointer to data storage to pass to free()
    const char    *msgptr;          // pointer to data to be read from (may be modified)
    char          *msgend;          // pointer to byte after last byte of message

    // reply, termination, error, and client context info
    int no_reply;                   // don't send asynchronous replies to client
    mDNSs32 time_blocked;           // record time of a blocked client
    int unresponsiveness_reports;
    struct reply_state *replies;    // corresponding (active) reply list
    req_termination_fn terminate;
    DNSServiceFlags flags;

    union
    {
        registered_record_entry *reg_recs;  // list of registrations for a connection-oriented request
        struct
        {
            mDNSInterfaceID interface_id;
            mDNSBool default_domain;
            mDNSBool ForceMCast;
            domainname regtype;
            browser_t *browsers;
        } browser;
        struct
        {
            mDNSInterfaceID InterfaceID;
            mDNSu16 txtlen;
            void *txtdata;
            mDNSIPPort port;
            domainlabel name;
            char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
            domainname type;
            mDNSBool default_domain;
            domainname host;
            mDNSBool autoname;              // Set if this name is tied to the Computer Name
            mDNSBool autorename;            // Set if this client wants us to automatically rename on conflict
            mDNSBool allowremotequery;      // Respond to unicast queries from outside the local link?
            int num_subtypes;
            service_instance *instances;
        } servicereg;
        struct
        {
            mDNSInterfaceID interface_id;
            mDNSu32 flags;
            mDNSu32 protocol;
            DNSQuestion q4;
            DNSQuestion          *q42;
            DNSQuestion q6;
            DNSQuestion          *q62;
        } addrinfo;
        struct
        {
            mDNSIPPort ReqExt;              // External port we originally requested, for logging purposes
            NATTraversalInfo NATinfo;
        } pm;
        struct
        {
#if 0
            DNSServiceFlags flags;
#endif
            DNSQuestion q_all;
            DNSQuestion q_default;
        } enumeration;
        struct
        {
            DNSQuestion q;
            DNSQuestion *q2;
        } queryrecord;
        struct
        {
            DNSQuestion qtxt;
            DNSQuestion qsrv;
            const ResourceRecord *txt;
            const ResourceRecord *srv;
            mDNSs32 ReportTime;
            mDNSBool external_advertise;
        } resolve;
    } u;
};

// struct physically sits between ipc message header and call-specific fields in the message buffer
typedef struct
{
    DNSServiceFlags flags;          // Note: This field is in NETWORK byte order
    mDNSu32 ifi;                    // Note: This field is in NETWORK byte order
    DNSServiceErrorType error;      // Note: This field is in NETWORK byte order
} reply_hdr;

typedef struct reply_state
{
    struct reply_state *next;       // If there are multiple unsent replies
    mDNSu32 totallen;
    mDNSu32 nwriten;
    ipc_msg_hdr mhdr[1];
    reply_hdr rhdr[1];
} reply_state;

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Globals
#endif

// globals
mDNSexport mDNS mDNSStorage;
mDNSexport const char ProgramName[] = "mDNSResponder";

static dnssd_sock_t listenfd = dnssd_InvalidSocket;
static request_state *all_requests = NULL;
#ifdef LOCAL_PEERPID
struct proc_bsdshortinfo proc;
#endif //LOCAL_PEERPID
//upto 16 characters of process name (defined in <sys/proc.h> but we do not want to include that file)
#define MAXCOMLEN 16
char pid_name[MAXCOMLEN];

// Note asymmetry here between registration and browsing.
// For service registrations we only automatically register in domains that explicitly appear in local configuration data
// (so AutoRegistrationDomains could equally well be called SCPrefRegDomains)
// For service browsing we also learn automatic browsing domains from the network, so for that case we have:
// 1. SCPrefBrowseDomains (local configuration data)
// 2. LocalDomainEnumRecords (locally-generated local-only PTR records -- equivalent to slElem->AuthRecs in uDNS.c)
// 3. AutoBrowseDomains, which is populated by tracking add/rmv events in AutomaticBrowseDomainChange, the callback function for our mDNS_GetDomains call.
// By creating and removing our own LocalDomainEnumRecords, we trigger AutomaticBrowseDomainChange callbacks just like domains learned from the network would.

mDNSexport DNameListElem *AutoRegistrationDomains;  // Domains where we automatically register for empty-string registrations

static DNameListElem *SCPrefBrowseDomains;          // List of automatic browsing domains read from SCPreferences for "empty string" browsing
static ARListElem    *LocalDomainEnumRecords;       // List of locally-generated PTR records to augment those we learn from the network
mDNSexport DNameListElem *AutoBrowseDomains;        // List created from those local-only PTR records plus records we get from the network

#define MSG_PAD_BYTES 5     // pad message buffer (read from client) with n zero'd bytes to guarantee
                            // n get_string() calls w/o buffer overrun
// initialization, setup/teardown functions

// If a platform specifies its own PID file name, we use that
#ifndef PID_FILE
#define PID_FILE "/var/run/mDNSResponder.pid"
#endif

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - General Utility Functions
#endif

mDNSlocal void FatalError(char *errmsg)
{
    char* ptr = NULL;
    LogMsg("%s: %s", errmsg, dnssd_strerror(dnssd_errno));
    *ptr = 0;   // On OS X abort() doesn't generate a crash log, but writing to zero does
    abort();    // On platforms where writing to zero doesn't generate an exception, abort instead
}

mDNSlocal mDNSu32 dnssd_htonl(mDNSu32 l)
{
    mDNSu32 ret;
    char *data = (char*) &ret;
    put_uint32(l, &data);
    return ret;
}

// hack to search-replace perror's to LogMsg's
mDNSlocal void my_perror(char *errmsg)
{
    LogMsg("%s: %d (%s)", errmsg, dnssd_errno, dnssd_strerror(dnssd_errno));
}

//Throttled version of my_perror: Logs once every 250 msgs
mDNSlocal void my_throttled_perror(char *err_msg)
{
    static int uds_throttle_count = 0;
    if ((uds_throttle_count++ % 250) == 0) 
        my_perror(err_msg);
} 

mDNSlocal void abort_request(request_state *req)
{
    if (req->terminate == (req_termination_fn) ~0)
    { LogMsg("abort_request: ERROR: Attempt to abort operation %p with req->terminate %p", req, req->terminate); return; }

    // First stop whatever mDNSCore operation we were doing
    // If this is actually a shared connection operation, then its req->terminate function will scan
    // the all_requests list and terminate any subbordinate operations sharing this file descriptor
    if (req->terminate) req->terminate(req);

    if (!dnssd_SocketValid(req->sd))
    { LogMsg("abort_request: ERROR: Attempt to abort operation %p with invalid fd %d",     req, req->sd);        return; }

    // Now, if this request_state is not subordinate to some other primary, close file descriptor and discard replies
    if (!req->primary)
    {
        if (req->errsd != req->sd) LogOperation("%3d: Removing FD and closing errsd %d", req->sd, req->errsd);
        else LogOperation("%3d: Removing FD", req->sd);
        udsSupportRemoveFDFromEventLoop(req->sd, req->platform_data);       // Note: This also closes file descriptor req->sd for us
        if (req->errsd != req->sd) { dnssd_close(req->errsd); req->errsd = req->sd; }

        while (req->replies)    // free pending replies
        {
            reply_state *ptr = req->replies;
            req->replies = req->replies->next;
            freeL("reply_state (abort)", ptr);
        }
    }

    // Set req->sd to something invalid, so that udsserver_idle knows to unlink and free this structure
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
    // Don't use dnssd_InvalidSocket (-1) because that's the sentinel value MACOSX_MDNS_MALLOC_DEBUGGING uses
    // for detecting when the memory for an object is inadvertently freed while the object is still on some list
    req->sd = req->errsd = -2;
#else
    req->sd = req->errsd = dnssd_InvalidSocket;
#endif
    // We also set req->terminate to a bogus value so we know if abort_request() gets called again for this request
    req->terminate = (req_termination_fn) ~0;
}

mDNSlocal void AbortUnlinkAndFree(request_state *req)
{
    request_state **p = &all_requests;
    abort_request(req);
    while (*p && *p != req) p=&(*p)->next;
    if (*p) { *p = req->next; freeL("request_state/AbortUnlinkAndFree", req); }
    else LogMsg("AbortUnlinkAndFree: ERROR: Attempt to abort operation %p not in list", req);
}

mDNSlocal reply_state *create_reply(const reply_op_t op, const size_t datalen, request_state *const request)
{
    reply_state *reply;

    if ((unsigned)datalen < sizeof(reply_hdr))
    {
        LogMsg("ERROR: create_reply - data length less than length of required fields");
        return NULL;
    }

    reply = mallocL("reply_state", sizeof(reply_state) + datalen - sizeof(reply_hdr));
    if (!reply) FatalError("ERROR: malloc");

    reply->next     = mDNSNULL;
    reply->totallen = (mDNSu32)datalen + sizeof(ipc_msg_hdr);
    reply->nwriten  = 0;

    reply->mhdr->version        = VERSION;
    reply->mhdr->datalen        = (mDNSu32)datalen;
    reply->mhdr->ipc_flags      = 0;
    reply->mhdr->op             = op;
    reply->mhdr->client_context = request->hdr.client_context;
    reply->mhdr->reg_index      = 0;

    return reply;
}

// Append a reply to the list in a request object
// If our request is sharing a connection, then we append our reply_state onto the primary's list
mDNSlocal void append_reply(request_state *req, reply_state *rep)
{
    request_state *r = req->primary ? req->primary : req;
    reply_state **ptr = &r->replies;
    while (*ptr) ptr = &(*ptr)->next;
    *ptr = rep;
    rep->next = NULL;
}

// Generates a response message giving name, type, domain, plus interface index,
// suitable for a browse result or service registration result.
// On successful completion rep is set to point to a malloc'd reply_state struct
mDNSlocal mStatus GenerateNTDResponse(const domainname *const servicename, const mDNSInterfaceID id,
                                      request_state *const request, reply_state **const rep, reply_op_t op, DNSServiceFlags flags, mStatus err)
{
    domainlabel name;
    domainname type, dom;
    *rep = NULL;
    if (!DeconstructServiceName(servicename, &name, &type, &dom))
        return kDNSServiceErr_Invalid;
    else
    {
        char namestr[MAX_DOMAIN_LABEL+1];
        char typestr[MAX_ESCAPED_DOMAIN_NAME];
        char domstr [MAX_ESCAPED_DOMAIN_NAME];
        int len;
        char *data;

        ConvertDomainLabelToCString_unescaped(&name, namestr);
        ConvertDomainNameToCString(&type, typestr);
        ConvertDomainNameToCString(&dom, domstr);

        // Calculate reply data length
        len = sizeof(DNSServiceFlags);
        len += sizeof(mDNSu32);  // if index
        len += sizeof(DNSServiceErrorType);
        len += (int) (strlen(namestr) + 1);
        len += (int) (strlen(typestr) + 1);
        len += (int) (strlen(domstr) + 1);

        // Build reply header
        *rep = create_reply(op, len, request);
        (*rep)->rhdr->flags = dnssd_htonl(flags);
        (*rep)->rhdr->ifi   = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(&mDNSStorage, id, mDNSfalse));
        (*rep)->rhdr->error = dnssd_htonl(err);

        // Build reply body
        data = (char *)&(*rep)->rhdr[1];
        put_string(namestr, &data);
        put_string(typestr, &data);
        put_string(domstr, &data);

        return mStatus_NoError;
    }
}

// Special support to enable the DNSServiceBrowse call made by Bonjour Browser
// Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
mDNSlocal void GenerateBonjourBrowserResponse(const domainname *const servicename, const mDNSInterfaceID id,
                                              request_state *const request, reply_state **const rep, reply_op_t op, DNSServiceFlags flags, mStatus err)
{
    char namestr[MAX_DOMAIN_LABEL+1];
    char typestr[MAX_ESCAPED_DOMAIN_NAME];
    static const char domstr[] = ".";
    int len;
    char *data;

    *rep = NULL;

    // 1. Put first label in namestr
    ConvertDomainLabelToCString_unescaped((const domainlabel *)servicename, namestr);

    // 2. Put second label and "local" into typestr
    mDNS_snprintf(typestr, sizeof(typestr), "%#s.local.", SecondLabel(servicename));

    // Calculate reply data length
    len = sizeof(DNSServiceFlags);
    len += sizeof(mDNSu32);  // if index
    len += sizeof(DNSServiceErrorType);
    len += (int) (strlen(namestr) + 1);
    len += (int) (strlen(typestr) + 1);
    len += (int) (strlen(domstr) + 1);

    // Build reply header
    *rep = create_reply(op, len, request);
    (*rep)->rhdr->flags = dnssd_htonl(flags);
    (*rep)->rhdr->ifi   = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(&mDNSStorage, id, mDNSfalse));
    (*rep)->rhdr->error = dnssd_htonl(err);

    // Build reply body
    data = (char *)&(*rep)->rhdr[1];
    put_string(namestr, &data);
    put_string(typestr, &data);
    put_string(domstr, &data);
}

// Returns a resource record (allocated w/ malloc) containing the data found in an IPC message
// Data must be in the following format: flags, interfaceIndex, name, rrtype, rrclass, rdlen, rdata, (optional) ttl
// (ttl only extracted/set if ttl argument is non-zero). Returns NULL for a bad-parameter error
mDNSlocal AuthRecord *read_rr_from_ipc_msg(request_state *request, int GetTTL, int validate_flags)
{
    DNSServiceFlags flags  = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    char name[256];
    int str_err = get_string(&request->msgptr, request->msgend, name, sizeof(name));
    mDNSu16 type    = get_uint16(&request->msgptr, request->msgend);
    mDNSu16     class   = get_uint16(&request->msgptr, request->msgend);
    mDNSu16 rdlen   = get_uint16(&request->msgptr, request->msgend);
    const char *rdata   = get_rdata (&request->msgptr, request->msgend, rdlen);
    mDNSu32 ttl   = GetTTL ? get_uint32(&request->msgptr, request->msgend) : 0;
    int storage_size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
    AuthRecord *rr;
    mDNSInterfaceID InterfaceID;
    AuthRecType artype;

    request->flags = flags;

    if (str_err) { LogMsg("ERROR: read_rr_from_ipc_msg - get_string"); return NULL; }

    if (!request->msgptr) { LogMsg("Error reading Resource Record from client"); return NULL; }

    if (validate_flags &&
        !((flags & kDNSServiceFlagsShared) == kDNSServiceFlagsShared) &&
        !((flags & kDNSServiceFlagsUnique) == kDNSServiceFlagsUnique))
    {
        LogMsg("ERROR: Bad resource record flags (must be kDNSServiceFlagsShared or kDNSServiceFlagsUnique)");
        return NULL;
    }

    rr = mallocL("AuthRecord/read_rr_from_ipc_msg", sizeof(AuthRecord) - sizeof(RDataBody) + storage_size);
    if (!rr) FatalError("ERROR: malloc");

    InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    if (InterfaceID == mDNSInterface_LocalOnly)
        artype = AuthRecordLocalOnly;
    else if (InterfaceID == mDNSInterface_P2P)
        artype = AuthRecordP2P;
    else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P))
        artype = AuthRecordAnyIncludeP2P;
    else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeAWDL))
        artype = AuthRecordAnyIncludeAWDL;
    else
        artype = AuthRecordAny;

    mDNS_SetupResourceRecord(rr, mDNSNULL, InterfaceID, type, 0,
                             (mDNSu8) ((flags & kDNSServiceFlagsShared) ? kDNSRecordTypeShared : kDNSRecordTypeUnique), artype, mDNSNULL, mDNSNULL);

    if (!MakeDomainNameFromDNSNameString(&rr->namestorage, name))
    {
        LogMsg("ERROR: bad name: %s", name);
        freeL("AuthRecord/read_rr_from_ipc_msg", rr);
        return NULL;
    }

    if (flags & kDNSServiceFlagsAllowRemoteQuery) rr->AllowRemoteQuery = mDNStrue;
    rr->resrec.rrclass = class;
    rr->resrec.rdlength = rdlen;
    rr->resrec.rdata->MaxRDLength = rdlen;
    mDNSPlatformMemCopy(rr->resrec.rdata->u.data, rdata, rdlen);
    if (GetTTL) rr->resrec.rroriginalttl = ttl;
    rr->resrec.namehash = DomainNameHashValue(rr->resrec.name);
    SetNewRData(&rr->resrec, mDNSNULL, 0);  // Sets rr->rdatahash for us
    return rr;
}

mDNSlocal int build_domainname_from_strings(domainname *srv, char *name, char *regtype, char *domain)
{
    domainlabel n;
    domainname d, t;

    if (!MakeDomainLabelFromLiteralString(&n, name)) return -1;
    if (!MakeDomainNameFromDNSNameString(&t, regtype)) return -1;
    if (!MakeDomainNameFromDNSNameString(&d, domain)) return -1;
    if (!ConstructServiceName(srv, &n, &t, &d)) return -1;
    return 0;
}

mDNSlocal void send_all(dnssd_sock_t s, const char *ptr, int len)
{
    int n = send(s, ptr, len, 0);
    // On a freshly-created Unix Domain Socket, the kernel should *never* fail to buffer a small write for us
    // (four bytes for a typical error code return, 12 bytes for DNSServiceGetProperty(DaemonVersion)).
    // If it does fail, we don't attempt to handle this failure, but we do log it so we know something is wrong.
    if (n < len)
        LogMsg("ERROR: send_all(%d) wrote %d of %d errno %d (%s)",
               s, n, len, dnssd_errno, dnssd_strerror(dnssd_errno));
}

#if 0
mDNSlocal mDNSBool AuthorizedDomain(const request_state * const request, const domainname * const d, const DNameListElem * const doms)
{
    const DNameListElem   *delem = mDNSNULL;
    int bestDelta   = -1;                           // the delta of the best match, lower is better
    int dLabels     = 0;
    mDNSBool allow       = mDNSfalse;

    if (SystemUID(request->uid)) return mDNStrue;

    dLabels = CountLabels(d);
    for (delem = doms; delem; delem = delem->next)
    {
        if (delem->uid)
        {
            int delemLabels = CountLabels(&delem->name);
            int delta       = dLabels - delemLabels;
            if ((bestDelta == -1 || delta <= bestDelta) && SameDomainName(&delem->name, SkipLeadingLabels(d, delta)))
            {
                bestDelta = delta;
                allow = (allow || (delem->uid == request->uid));
            }
        }
    }

    return bestDelta == -1 ? mDNStrue : allow;
}
#endif

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - external helpers
#endif

mDNSlocal mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags)
{
#if APPLE_OSX_mDNSResponder

    if (   ((InterfaceID == mDNSInterface_Any) && (flags & (kDNSServiceFlagsIncludeP2P | kDNSServiceFlagsIncludeAWDL)) && IsLocalDomain(domain))
        || mDNSPlatformInterfaceIsD2D(InterfaceID))
    {
        return mDNStrue;
    }
    else
        return mDNSfalse;

#else
    (void) InterfaceID;
    (void) domain;
    (void) flags;

    return mDNSfalse;
#endif  // APPLE_OSX_mDNSResponder
}

mDNSlocal void external_start_advertising_helper(service_instance *const instance)
{
    AuthRecord *st = instance->subtypes;
    ExtraResourceRecord *e;
    int i;

    if (mDNSIPPortIsZero(instance->request->u.servicereg.port))
    {
        LogInfo("external_start_advertising_helper: Not registering service with port number zero");
        return;
    }

    if (instance->external_advertise) LogMsg("external_start_advertising_helper: external_advertise already set!");

    for ( i = 0; i < instance->request->u.servicereg.num_subtypes; i++)
        external_start_advertising_service(&st[i].resrec, instance->request->flags);

    external_start_advertising_service(&instance->srs.RR_PTR.resrec, instance->request->flags);
    external_start_advertising_service(&instance->srs.RR_SRV.resrec, instance->request->flags);
    external_start_advertising_service(&instance->srs.RR_TXT.resrec, instance->request->flags);

    for (e = instance->srs.Extras; e; e = e->next)
        external_start_advertising_service(&e->r.resrec, instance->request->flags);

    instance->external_advertise = mDNStrue;
}

mDNSlocal void external_stop_advertising_helper(service_instance *const instance)
{
    AuthRecord *st = instance->subtypes;
    ExtraResourceRecord *e;
    int i;

    if (!instance->external_advertise) return;

    LogInfo("external_stop_advertising_helper: calling external_stop_advertising_service");

    for ( i = 0; i < instance->request->u.servicereg.num_subtypes; i++)
        external_stop_advertising_service(&st[i].resrec, instance->request->flags);

    external_stop_advertising_service(&instance->srs.RR_PTR.resrec, instance->request->flags);
    external_stop_advertising_service(&instance->srs.RR_SRV.resrec, instance->request->flags);
    external_stop_advertising_service(&instance->srs.RR_TXT.resrec, instance->request->flags);

    for (e = instance->srs.Extras; e; e = e->next)
        external_stop_advertising_service(&e->r.resrec, instance->request->flags);

    instance->external_advertise = mDNSfalse;
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceRegister
#endif

mDNSexport void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result)
{
    ExtraResourceRecord *extra = (ExtraResourceRecord *)rr->RecordContext;
    (void)m;  // Unused

    if (result != mStatus_MemFree) { LogMsg("Error: FreeExtraRR invoked with unexpected error %d", result); return; }

    LogInfo("     FreeExtraRR %s", RRDisplayString(m, &rr->resrec));

    if (rr->resrec.rdata != &rr->rdatastorage)
        freeL("Extra RData", rr->resrec.rdata);
    freeL("ExtraResourceRecord/FreeExtraRR", extra);
}

mDNSlocal void unlink_and_free_service_instance(service_instance *srv)
{
    ExtraResourceRecord *e = srv->srs.Extras, *tmp;

    external_stop_advertising_helper(srv);

    // clear pointers from parent struct
    if (srv->request)
    {
        service_instance **p = &srv->request->u.servicereg.instances;
        while (*p)
        {
            if (*p == srv) { *p = (*p)->next; break; }
            p = &(*p)->next;
        }
    }

    while (e)
    {
        e->r.RecordContext = e;
        tmp = e;
        e = e->next;
        FreeExtraRR(&mDNSStorage, &tmp->r, mStatus_MemFree);
    }

    if (srv->srs.RR_TXT.resrec.rdata != &srv->srs.RR_TXT.rdatastorage)
        freeL("TXT RData", srv->srs.RR_TXT.resrec.rdata);

    if (srv->subtypes) { freeL("ServiceSubTypes", srv->subtypes); srv->subtypes = NULL; }
    freeL("service_instance", srv);
}

// Count how many other service records we have locally with the same name, but different rdata.
// For auto-named services, we can have at most one per machine -- if we allowed two auto-named services of
// the same type on the same machine, we'd get into an infinite autoimmune-response loop of continuous renaming.
mDNSexport int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs)
{
    int count = 0;
    ResourceRecord *r = &srs->RR_SRV.resrec;
    AuthRecord *rr;

    for (rr = m->ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.rrtype == kDNSType_SRV && SameDomainName(rr->resrec.name, r->name) && !IdenticalSameNameRecord(&rr->resrec, r))
            count++;

    verbosedebugf("%d peer registrations for %##s", count, r->name->c);
    return(count);
}

mDNSexport int CountExistingRegistrations(domainname *srv, mDNSIPPort port)
{
    int count = 0;
    AuthRecord *rr;
    for (rr = mDNSStorage.ResourceRecords; rr; rr=rr->next)
        if (rr->resrec.rrtype == kDNSType_SRV &&
            mDNSSameIPPort(rr->resrec.rdata->u.srv.port, port) &&
            SameDomainName(rr->resrec.name, srv))
            count++;
    return(count);
}

mDNSlocal void SendServiceRemovalNotification(ServiceRecordSet *const srs)
{
    reply_state *rep;
    service_instance *instance = srs->ServiceContext;
    if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, 0, mStatus_NoError) != mStatus_NoError)
        LogMsg("%3d: SendServiceRemovalNotification: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
    else { append_reply(instance->request, rep); instance->clientnotified = mDNSfalse; }
}

// service registration callback performs three duties - frees memory for deregistered services,
// handles name conflicts, and delivers completed registration information to the client
mDNSlocal void regservice_callback(mDNS *const m, ServiceRecordSet *const srs, mStatus result)
{
    mStatus err;
    mDNSBool SuppressError = mDNSfalse;
    service_instance *instance;
    reply_state         *rep;
    (void)m; // Unused

    if (!srs)      { LogMsg("regservice_callback: srs is NULL %d",                 result); return; }

    instance = srs->ServiceContext;
    if (!instance) { LogMsg("regservice_callback: srs->ServiceContext is NULL %d", result); return; }

    // don't send errors up to client for wide-area, empty-string registrations
    if (instance->request &&
        instance->request->u.servicereg.default_domain &&
        !instance->default_local)
        SuppressError = mDNStrue;

    if (mDNS_LoggingEnabled)
    {
        const char *const fmt =
            (result == mStatus_NoError)      ? "%s DNSServiceRegister(%##s, %u) REGISTERED"    :
            (result == mStatus_MemFree)      ? "%s DNSServiceRegister(%##s, %u) DEREGISTERED"  :
            (result == mStatus_NameConflict) ? "%s DNSServiceRegister(%##s, %u) NAME CONFLICT" :
            "%s DNSServiceRegister(%##s, %u) %s %d";
        char prefix[16] = "---:";
        if (instance->request) mDNS_snprintf(prefix, sizeof(prefix), "%3d:", instance->request->sd);
        LogOperation(fmt, prefix, srs->RR_SRV.resrec.name->c, mDNSVal16(srs->RR_SRV.resrec.rdata->u.srv.port),
                     SuppressError ? "suppressed error" : "CALLBACK", result);
    }

    if (!instance->request && result != mStatus_MemFree) { LogMsg("regservice_callback: instance->request is NULL %d", result); return; }

    if (result == mStatus_NoError)
    {
        if (instance->request->u.servicereg.allowremotequery)
        {
            ExtraResourceRecord *e;
            srs->RR_ADV.AllowRemoteQuery = mDNStrue;
            srs->RR_PTR.AllowRemoteQuery = mDNStrue;
            srs->RR_SRV.AllowRemoteQuery = mDNStrue;
            srs->RR_TXT.AllowRemoteQuery = mDNStrue;
            for (e = instance->srs.Extras; e; e = e->next) e->r.AllowRemoteQuery = mDNStrue;
        }

        if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, kDNSServiceFlagsAdd, result) != mStatus_NoError)
            LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
        else { append_reply(instance->request, rep); instance->clientnotified = mDNStrue; }

        if (callExternalHelpers(instance->request->u.servicereg.InterfaceID, &instance->domain, instance->request->flags))
        {
            LogInfo("regservice_callback: calling external_start_advertising_helper()");
            external_start_advertising_helper(instance);
        }
        if (instance->request->u.servicereg.autoname && CountPeerRegistrations(m, srs) == 0)
            RecordUpdatedNiceLabel(m, 0);   // Successfully got new name, tell user immediately
    }
    else if (result == mStatus_MemFree)
    {
        if (instance->request && instance->renameonmemfree)
        {
            external_stop_advertising_helper(instance);
            instance->renameonmemfree = 0;
            err = mDNS_RenameAndReregisterService(m, srs, &instance->request->u.servicereg.name);
            if (err) LogMsg("ERROR: regservice_callback - RenameAndReregisterService returned %d", err);
            // error should never happen - safest to log and continue
        }
        else
            unlink_and_free_service_instance(instance);
    }
    else if (result == mStatus_NameConflict)
    {
        if (instance->request->u.servicereg.autorename)
        {
            external_stop_advertising_helper(instance);
            if (instance->request->u.servicereg.autoname && CountPeerRegistrations(m, srs) == 0)
            {
                // On conflict for an autoname service, rename and reregister *all* autoname services
                IncrementLabelSuffix(&m->nicelabel, mDNStrue);
                mDNS_ConfigChanged(m);  // Will call back into udsserver_handle_configchange()
            }
            else    // On conflict for a non-autoname service, rename and reregister just that one service
            {
                if (instance->clientnotified) SendServiceRemovalNotification(srs);
                mDNS_RenameAndReregisterService(m, srs, mDNSNULL);
            }
        }
        else
        {
            if (!SuppressError)
            {
                if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, kDNSServiceFlagsAdd, result) != mStatus_NoError)
                    LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
                else { append_reply(instance->request, rep); instance->clientnotified = mDNStrue; }
            }
            unlink_and_free_service_instance(instance);
        }
    }
    else        // Not mStatus_NoError, mStatus_MemFree, or mStatus_NameConflict
    {
        if (!SuppressError)
        {
            if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, kDNSServiceFlagsAdd, result) != mStatus_NoError)
                LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
            else { append_reply(instance->request, rep); instance->clientnotified = mDNStrue; }
        }
    }
}

mDNSlocal void regrecord_callback(mDNS *const m, AuthRecord *rr, mStatus result)
{
    (void)m; // Unused
    if (!rr->RecordContext)     // parent struct already freed by termination callback
    {
        if (result == mStatus_NoError)
            LogMsg("Error: regrecord_callback: successful registration of orphaned record %s", ARDisplayString(m, rr));
        else
        {
            if (result != mStatus_MemFree) LogMsg("regrecord_callback: error %d received after parent termination", result);

            // We come here when the record is being deregistered either from DNSServiceRemoveRecord or connection_termination.
            // If the record has been updated, we need to free the rdata. Everytime we call mDNS_Update, it calls update_callback
            // with the old rdata (so that we can free it) and stores the new rdata in "rr->resrec.rdata". This means, we need
            // to free the latest rdata for which the update_callback was never called with.
            if (rr->resrec.rdata != &rr->rdatastorage) freeL("RData/regrecord_callback", rr->resrec.rdata);
            freeL("AuthRecord/regrecord_callback", rr);
        }
    }
    else
    {
        registered_record_entry *re = rr->RecordContext;
        request_state *request = re->request;

        if (mDNS_LoggingEnabled)
        {
            char *fmt = (result == mStatus_NoError)      ? "%3d: DNSServiceRegisterRecord(%u %s) REGISTERED"    :
                        (result == mStatus_MemFree)      ? "%3d: DNSServiceRegisterRecord(%u %s) DEREGISTERED"  :
                        (result == mStatus_NameConflict) ? "%3d: DNSServiceRegisterRecord(%u %s) NAME CONFLICT" :
                        "%3d: DNSServiceRegisterRecord(%u %s) %d";
            LogOperation(fmt, request->sd, re->key, RRDisplayString(m, &rr->resrec), result);
        }

        if (result != mStatus_MemFree)
        {
            int len = sizeof(DNSServiceFlags) + sizeof(mDNSu32) + sizeof(DNSServiceErrorType);
            reply_state *reply = create_reply(reg_record_reply_op, len, request);
            reply->mhdr->client_context = re->regrec_client_context;
            reply->rhdr->flags = dnssd_htonl(0);
            reply->rhdr->ifi   = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, rr->resrec.InterfaceID, mDNSfalse));
            reply->rhdr->error = dnssd_htonl(result);
            append_reply(request, reply);
        }

        if (result)
        {
            // unlink from list, free memory
            registered_record_entry **ptr = &request->u.reg_recs;
            while (*ptr && (*ptr) != re) ptr = &(*ptr)->next;
            if (!*ptr) { LogMsg("regrecord_callback - record not in list!"); return; }
            *ptr = (*ptr)->next;
            freeL("registered_record_entry AuthRecord regrecord_callback", re->rr);
            freeL("registered_record_entry regrecord_callback", re);
        }
        else
        {
            if (re->external_advertise) LogMsg("regrecord_callback: external_advertise already set!");

            if (callExternalHelpers(re->origInterfaceID, &rr->namestorage, request->flags))
            {
                LogInfo("regrecord_callback: calling external_start_advertising_service");
                external_start_advertising_service(&rr->resrec, request->flags);
                re->external_advertise = mDNStrue;
            }
        }
    }
}

mDNSlocal pid_t get_peer_pid(int sock, char *pid_name_local) 
{
    pid_t           p = (pid_t) -1;
    socklen_t       len = sizeof(p);
    pid_name_local[0] = '\0';
#ifdef LOCAL_PEERPID    
    if (sock < 0) 
        return -1;
    // to extract the pid value
    if (getsockopt(sock, SOL_LOCAL, LOCAL_PEERPID, &p, &len) != 0)
        return -1;
    // to extract the process name from the pid value
    if (proc_pidinfo(p, PROC_PIDT_SHORTBSDINFO, 1, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) == 0)
        return -1;
    mDNSPlatformStrCopy(pid_name_local, proc.pbsi_comm);
    return p;	
#else   // !LOCAL_PEERPID
    len = 0;
    if (sock < 0) 
        return -1;
    LogInfo("get_peer_pid: Not Supported on this version of OS");
    return -1;
#endif  // LOCAL_PEERPID
}

mDNSlocal void connection_termination(request_state *request)
{
    // When terminating a shared connection, we need to scan the all_requests list
    // and terminate any subbordinate operations sharing this file descriptor
    request_state **req = &all_requests;

    LogOperation("%3d: DNSServiceCreateConnection STOP PID[%d](%s)", request->sd, get_peer_pid(request->sd, pid_name), pid_name);

    while (*req)
    {
        if ((*req)->primary == request)
        {
            // Since we're already doing a list traversal, we unlink the request directly instead of using AbortUnlinkAndFree()
            request_state *tmp = *req;
            if (tmp->primary == tmp) LogMsg("connection_termination ERROR (*req)->primary == *req for %p %d",                  tmp, tmp->sd);
            if (tmp->replies) LogMsg("connection_termination ERROR How can subordinate req %p %d have replies queued?", tmp, tmp->sd);
            abort_request(tmp);
            *req = tmp->next;
            freeL("request_state/connection_termination", tmp);
        }
        else
            req = &(*req)->next;
    }

    while (request->u.reg_recs)
    {
        registered_record_entry *ptr = request->u.reg_recs;
        LogOperation("%3d: DNSServiceRegisterRecord(%u %s) STOP PID[%d](%s)", request->sd, ptr->key, RRDisplayString(&mDNSStorage, &ptr->rr->resrec), get_peer_pid(request->sd, pid_name), pid_name);
		request->u.reg_recs = request->u.reg_recs->next;
        ptr->rr->RecordContext = NULL;
        if (ptr->external_advertise)
        {
            ptr->external_advertise = mDNSfalse;
            external_stop_advertising_service(&ptr->rr->resrec, request->flags);
        }
        mDNS_Deregister(&mDNSStorage, ptr->rr);     // Will free ptr->rr for us
        freeL("registered_record_entry/connection_termination", ptr);
    }
}

mDNSlocal void handle_cancel_request(request_state *request)
{
    request_state **req = &all_requests;
    LogOperation("%3d: Cancel %08X %08X", request->sd, request->hdr.client_context.u32[1], request->hdr.client_context.u32[0]);
    while (*req)
    {
        if ((*req)->primary == request &&
            (*req)->hdr.client_context.u32[0] == request->hdr.client_context.u32[0] &&
            (*req)->hdr.client_context.u32[1] == request->hdr.client_context.u32[1])
        {
            // Since we're already doing a list traversal, we unlink the request directly instead of using AbortUnlinkAndFree()
            request_state *tmp = *req;
            abort_request(tmp);
            *req = tmp->next;
            freeL("request_state/handle_cancel_request", tmp);
        }
        else
            req = &(*req)->next;
    }
}

mDNSlocal mStatus handle_regrecord_request(request_state *request)
{
    mStatus err = mStatus_BadParamErr;
    AuthRecord *rr = read_rr_from_ipc_msg(request, 1, 1);
    if (rr)
    {
        registered_record_entry *re;
        // Don't allow non-local domains to be regsitered as LocalOnly. Allowing this would permit
        // clients to register records such as www.bigbank.com A w.x.y.z to redirect Safari.
        if (rr->resrec.InterfaceID == mDNSInterface_LocalOnly && !IsLocalDomain(rr->resrec.name) &&
            rr->resrec.rrclass == kDNSClass_IN && (rr->resrec.rrtype == kDNSType_A || rr->resrec.rrtype == kDNSType_AAAA ||
                                                   rr->resrec.rrtype == kDNSType_CNAME))
        {
            freeL("AuthRecord/handle_regrecord_request", rr);
            return (mStatus_BadParamErr);
        }
        // allocate registration entry, link into list
        re = mallocL("registered_record_entry", sizeof(registered_record_entry));
        if (!re) FatalError("ERROR: malloc");
        re->key                   = request->hdr.reg_index;
        re->rr                    = rr;
        re->regrec_client_context = request->hdr.client_context;
        re->request               = request;
        re->external_advertise    = mDNSfalse;
        rr->RecordContext         = re;
        rr->RecordCallback        = regrecord_callback;

        re->origInterfaceID = rr->resrec.InterfaceID;
        if (rr->resrec.InterfaceID == mDNSInterface_P2P) rr->resrec.InterfaceID = mDNSInterface_Any;
#if 0
        if (!AuthorizedDomain(request, rr->resrec.name, AutoRegistrationDomains)) return (mStatus_NoError);
#endif
        if (rr->resrec.rroriginalttl == 0)
            rr->resrec.rroriginalttl = DefaultTTLforRRType(rr->resrec.rrtype);

        LogOperation("%3d: DNSServiceRegisterRecord(%u %s) START PID[%d](%s)", 
		request->sd, re->key, RRDisplayString(&mDNSStorage, &rr->resrec), get_peer_pid(request->sd, pid_name), pid_name);
	err = mDNS_Register(&mDNSStorage, rr);
        if (err)
        {
            LogOperation("%3d: DNSServiceRegisterRecord(%u %s) ERROR (%d)", request->sd, re->key, RRDisplayString(&mDNSStorage, &rr->resrec), err);
            freeL("registered_record_entry", re);
            freeL("registered_record_entry/AuthRecord", rr);
        }
        else
        {
            re->next = request->u.reg_recs;
            request->u.reg_recs = re;
        }
    }
    return(err);
}

mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m);

mDNSlocal void regservice_termination_callback(request_state *request)
{
    if (!request) { LogMsg("regservice_termination_callback context is NULL"); return; }
    while (request->u.servicereg.instances)
    {
        service_instance *p = request->u.servicereg.instances;
        request->u.servicereg.instances = request->u.servicereg.instances->next;
        // only safe to free memory if registration is not valid, i.e. deregister fails (which invalidates p)
        LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP PID[%d](%s)",
		request->sd, p->srs.RR_SRV.resrec.name->c, mDNSVal16(p->srs.RR_SRV.resrec.rdata->u.srv.port), get_peer_pid(request->sd, pid_name), pid_name);

        external_stop_advertising_helper(p);

        // Clear backpointer *before* calling mDNS_DeregisterService/unlink_and_free_service_instance
        // We don't need unlink_and_free_service_instance to cut its element from the list, because we're already advancing
        // request->u.servicereg.instances as we work our way through the list, implicitly cutting one element at a time
        // We can't clear p->request *after* the calling mDNS_DeregisterService/unlink_and_free_service_instance
        // because by then we might have already freed p
        p->request = NULL;
        if (mDNS_DeregisterService(&mDNSStorage, &p->srs)) unlink_and_free_service_instance(p);
        // Don't touch service_instance *p after this -- it's likely to have been freed already
    }
    if (request->u.servicereg.txtdata)
    { freeL("service_info txtdata", request->u.servicereg.txtdata); request->u.servicereg.txtdata = NULL; }
    if (request->u.servicereg.autoname)
    {
        // Clear autoname before calling UpdateDeviceInfoRecord() so it doesn't mistakenly include this in its count of active autoname registrations
        request->u.servicereg.autoname = mDNSfalse;
        UpdateDeviceInfoRecord(&mDNSStorage);
    }
}

mDNSlocal request_state *LocateSubordinateRequest(request_state *request)
{
    request_state *req;
    for (req = all_requests; req; req = req->next)
        if (req->primary == request &&
            req->hdr.client_context.u32[0] == request->hdr.client_context.u32[0] &&
            req->hdr.client_context.u32[1] == request->hdr.client_context.u32[1]) return(req);
    return(request);
}

mDNSlocal mStatus add_record_to_service(request_state *request, service_instance *instance, mDNSu16 rrtype, mDNSu16 rdlen, const char *rdata, mDNSu32 ttl)
{
    ServiceRecordSet *srs = &instance->srs;
    mStatus result;
    mDNSu32 coreFlags = 0;  // translate to corresponding mDNSCore flag definitions
    int size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
    ExtraResourceRecord *extra = mallocL("ExtraResourceRecord", sizeof(*extra) - sizeof(RDataBody) + size);
    if (!extra) { my_perror("ERROR: malloc"); return mStatus_NoMemoryErr; }

    mDNSPlatformMemZero(extra, sizeof(ExtraResourceRecord));  // OK if oversized rdata not zero'd
    extra->r.resrec.rrtype = rrtype;
    extra->r.rdatastorage.MaxRDLength = (mDNSu16) size;
    extra->r.resrec.rdlength = rdlen;
    mDNSPlatformMemCopy(&extra->r.rdatastorage.u.data, rdata, rdlen);
    // use InterfaceID value from DNSServiceRegister() call that created the original service
    extra->r.resrec.InterfaceID = request->u.servicereg.InterfaceID;

    if (request->flags & kDNSServiceFlagsIncludeP2P)
        coreFlags |= coreFlagIncludeP2P;
    if (request->flags & kDNSServiceFlagsIncludeAWDL)
        coreFlags |= coreFlagIncludeAWDL;
    
    result = mDNS_AddRecordToService(&mDNSStorage, srs, extra, &extra->r.rdatastorage, ttl, coreFlags);
    if (result) { freeL("ExtraResourceRecord/add_record_to_service", extra); return result; }

    extra->ClientID = request->hdr.reg_index;
    if (   instance->external_advertise
           && callExternalHelpers(request->u.servicereg.InterfaceID, &instance->domain, request->flags))
    {
        LogInfo("add_record_to_service: calling external_start_advertising_service");
        external_start_advertising_service(&extra->r.resrec, request->flags);
    }
    return result;
}

mDNSlocal mStatus handle_add_request(request_state *request)
{
    service_instance *i;
    mStatus result = mStatus_UnknownErr;
    DNSServiceFlags flags  = get_flags (&request->msgptr, request->msgend);
    mDNSu16 rrtype = get_uint16(&request->msgptr, request->msgend);
    mDNSu16 rdlen  = get_uint16(&request->msgptr, request->msgend);
    const char     *rdata  = get_rdata (&request->msgptr, request->msgend, rdlen);
    mDNSu32 ttl    = get_uint32(&request->msgptr, request->msgend);
    if (!ttl) ttl = DefaultTTLforRRType(rrtype);
    (void)flags; // Unused

    if (!request->msgptr) { LogMsg("%3d: DNSServiceAddRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    // If this is a shared connection, check if the operation actually applies to a subordinate request_state object
    if (request->terminate == connection_termination) request = LocateSubordinateRequest(request);

    if (request->terminate != regservice_termination_callback)
    { LogMsg("%3d: DNSServiceAddRecord(not a registered service ref)", request->sd); return(mStatus_BadParamErr); }

    // For a service registered with zero port, don't allow adding records. This mostly happens due to a bug
    // in the application. See radar://9165807.
    if (mDNSIPPortIsZero(request->u.servicereg.port))
    { LogMsg("%3d: DNSServiceAddRecord: adding record to a service registered with zero port", request->sd); return(mStatus_BadParamErr); }

    LogOperation("%3d: DNSServiceAddRecord(%X, %##s, %s, %d)", request->sd, flags,
                 (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL, DNSTypeName(rrtype), rdlen);

    for (i = request->u.servicereg.instances; i; i = i->next)
    {
        result = add_record_to_service(request, i, rrtype, rdlen, rdata, ttl);
        if (result && i->default_local) break;
        else result = mStatus_NoError;  // suppress non-local default errors
    }

    return(result);
}

mDNSlocal void update_callback(mDNS *const m, AuthRecord *const rr, RData *oldrd, mDNSu16 oldrdlen)
{
    mDNSBool external_advertise = (rr->UpdateContext) ? *((mDNSBool *)rr->UpdateContext) : mDNSfalse;
    (void)m; // Unused

    // There are three cases.
    //
    // 1. We have updated the primary TXT record of the service
    // 2. We have updated the TXT record that was added to the service using DNSServiceAddRecord
    // 3. We have updated the TXT record that was registered using DNSServiceRegisterRecord
    //
    // external_advertise is set if we have advertised at least once during the initial addition
    // of the record in all of the three cases above. We should have checked for InterfaceID/LocalDomain
    // checks during the first time and hence we don't do any checks here
    if (external_advertise)
    {
        ResourceRecord ext = rr->resrec;
        DNSServiceFlags flags = 0;

        // Since we don't have a copy of the flags value used when the record was registered,
        // we'll have to derive it from the ARType field.  
        if (rr->ARType == AuthRecordAnyIncludeP2P)
            flags |= kDNSServiceFlagsIncludeP2P;
        else if (rr->ARType == AuthRecordAnyIncludeAWDL)
            flags |= kDNSServiceFlagsIncludeAWDL;

        if (ext.rdlength == oldrdlen && mDNSPlatformMemSame(&ext.rdata->u, &oldrd->u, oldrdlen)) goto exit;
        SetNewRData(&ext, oldrd, oldrdlen);
        external_stop_advertising_service(&ext, flags);
        LogInfo("update_callback: calling external_start_advertising_service");
        external_start_advertising_service(&rr->resrec, flags);
    }
exit:
    if (oldrd != &rr->rdatastorage) freeL("RData/update_callback", oldrd);
}

mDNSlocal mStatus update_record(AuthRecord *rr, mDNSu16 rdlen, const char *rdata, mDNSu32 ttl, const mDNSBool *const external_advertise)
{
    mStatus result;
    const int rdsize = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
    RData *newrd = mallocL("RData/update_record", sizeof(RData) - sizeof(RDataBody) + rdsize);
    if (!newrd) FatalError("ERROR: malloc");
    newrd->MaxRDLength = (mDNSu16) rdsize;
    mDNSPlatformMemCopy(&newrd->u, rdata, rdlen);

    // BIND named (name daemon) doesn't allow TXT records with zero-length rdata. This is strictly speaking correct,
    // since RFC 1035 specifies a TXT record as "One or more <character-string>s", not "Zero or more <character-string>s".
    // Since some legacy apps try to create zero-length TXT records, we'll silently correct it here.
    if (rr->resrec.rrtype == kDNSType_TXT && rdlen == 0) { rdlen = 1; newrd->u.txt.c[0] = 0; }

    if (external_advertise) rr->UpdateContext = (void *)external_advertise;

    result = mDNS_Update(&mDNSStorage, rr, ttl, rdlen, newrd, update_callback);
    if (result) { LogMsg("update_record: Error %d for %s", (int)result, ARDisplayString(&mDNSStorage, rr)); freeL("RData/update_record", newrd); }
    return result;
}

mDNSlocal mStatus handle_update_request(request_state *request)
{
    const ipc_msg_hdr *const hdr = &request->hdr;
    mStatus result = mStatus_BadReferenceErr;
    service_instance *i;
    AuthRecord *rr = NULL;

    // get the message data
    DNSServiceFlags flags = get_flags (&request->msgptr, request->msgend);  // flags unused
    mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
    const char     *rdata = get_rdata (&request->msgptr, request->msgend, rdlen);
    mDNSu32 ttl   = get_uint32(&request->msgptr, request->msgend);
    (void)flags; // Unused

    if (!request->msgptr) { LogMsg("%3d: DNSServiceUpdateRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    // If this is a shared connection, check if the operation actually applies to a subordinate request_state object
    if (request->terminate == connection_termination) request = LocateSubordinateRequest(request);

    if (request->terminate == connection_termination)
    {
        // update an individually registered record
        registered_record_entry *reptr;
        for (reptr = request->u.reg_recs; reptr; reptr = reptr->next)
        {
            if (reptr->key == hdr->reg_index)
            {
                result = update_record(reptr->rr, rdlen, rdata, ttl, &reptr->external_advertise);
                LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s)",
                             request->sd, reptr->rr->resrec.name->c, reptr->rr ? DNSTypeName(reptr->rr->resrec.rrtype) : "<NONE>");
                goto end;
            }
        }
        result = mStatus_BadReferenceErr;
        goto end;
    }

    if (request->terminate != regservice_termination_callback)
    { LogMsg("%3d: DNSServiceUpdateRecord(not a registered service ref)", request->sd); return(mStatus_BadParamErr); }

    // For a service registered with zero port, only SRV record is initialized. Don't allow any updates.
    if (mDNSIPPortIsZero(request->u.servicereg.port))
    { LogMsg("%3d: DNSServiceUpdateRecord: updating the record of a service registered with zero port", request->sd); return(mStatus_BadParamErr); }

    // update the saved off TXT data for the service
    if (hdr->reg_index == TXT_RECORD_INDEX)
    {
        if (request->u.servicereg.txtdata)
        { freeL("service_info txtdata", request->u.servicereg.txtdata); request->u.servicereg.txtdata = NULL; }
        if (rdlen > 0)
        {
            request->u.servicereg.txtdata = mallocL("service_info txtdata", rdlen);
            if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_update_request - malloc");
            mDNSPlatformMemCopy(request->u.servicereg.txtdata, rdata, rdlen);
        }
        request->u.servicereg.txtlen = rdlen;
    }

    // update a record from a service record set
    for (i = request->u.servicereg.instances; i; i = i->next)
    {
        if (hdr->reg_index == TXT_RECORD_INDEX) rr = &i->srs.RR_TXT;
        else
        {
            ExtraResourceRecord *e;
            for (e = i->srs.Extras; e; e = e->next)
                if (e->ClientID == hdr->reg_index) { rr = &e->r; break; }
        }

        if (!rr) { result = mStatus_BadReferenceErr; goto end; }
        result = update_record(rr, rdlen, rdata, ttl, &i->external_advertise);
        if (result && i->default_local) goto end;
        else result = mStatus_NoError;  // suppress non-local default errors
    }

end:
    if (request->terminate == regservice_termination_callback)
        LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s)", request->sd,
                     (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL,
                     rr ? DNSTypeName(rr->resrec.rrtype) : "<NONE>");

    return(result);
}

// remove a resource record registered via DNSServiceRegisterRecord()
mDNSlocal mStatus remove_record(request_state *request)
{
    mStatus err = mStatus_UnknownErr;
    registered_record_entry *e, **ptr = &request->u.reg_recs;

    while (*ptr && (*ptr)->key != request->hdr.reg_index) ptr = &(*ptr)->next;
    if (!*ptr) { LogMsg("%3d: DNSServiceRemoveRecord(%u) not found", request->sd, request->hdr.reg_index); return mStatus_BadReferenceErr; }
    e = *ptr;
    *ptr = e->next; // unlink

    LogOperation("%3d: DNSServiceRemoveRecord(%u %s)", request->sd, e->key, RRDisplayString(&mDNSStorage, &e->rr->resrec));
    e->rr->RecordContext = NULL;
    if (e->external_advertise)
    {
        external_stop_advertising_service(&e->rr->resrec, request->flags);
        e->external_advertise = mDNSfalse;
    }
    err = mDNS_Deregister(&mDNSStorage, e->rr);     // Will free e->rr for us; we're responsible for freeing e
    if (err)
    {
        LogMsg("ERROR: remove_record, mDNS_Deregister: %d", err);
        freeL("registered_record_entry AuthRecord remove_record", e->rr);
    }

    freeL("registered_record_entry remove_record", e);
    return err;
}

mDNSlocal mStatus remove_extra(const request_state *const request, service_instance *const serv, mDNSu16 *const rrtype)
{
    mStatus err = mStatus_BadReferenceErr;
    ExtraResourceRecord *ptr;

    for (ptr = serv->srs.Extras; ptr; ptr = ptr->next)
    {
        if (ptr->ClientID == request->hdr.reg_index) // found match
        {
            *rrtype = ptr->r.resrec.rrtype;
            if (serv->external_advertise) external_stop_advertising_service(&ptr->r.resrec, request->flags);
            err = mDNS_RemoveRecordFromService(&mDNSStorage, &serv->srs, ptr, FreeExtraRR, ptr);
            break;
        }
    }
    return err;
}

mDNSlocal mStatus handle_removerecord_request(request_state *request)
{
    mStatus err = mStatus_BadReferenceErr;
    get_flags(&request->msgptr, request->msgend);   // flags unused

    if (!request->msgptr) { LogMsg("%3d: DNSServiceRemoveRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    // If this is a shared connection, check if the operation actually applies to a subordinate request_state object
    if (request->terminate == connection_termination) request = LocateSubordinateRequest(request);

    if (request->terminate == connection_termination)
        err = remove_record(request);  // remove individually registered record
    else if (request->terminate != regservice_termination_callback)
    { LogMsg("%3d: DNSServiceRemoveRecord(not a registered service ref)", request->sd); return(mStatus_BadParamErr); }
    else
    {
        service_instance *i;
        mDNSu16 rrtype = 0;
        LogOperation("%3d: DNSServiceRemoveRecord(%##s, %s)", request->sd,
                     (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL,
                     rrtype ? DNSTypeName(rrtype) : "<NONE>");
        for (i = request->u.servicereg.instances; i; i = i->next)
        {
            err = remove_extra(request, i, &rrtype);
            if (err && i->default_local) break;
            else err = mStatus_NoError;  // suppress non-local default errors
        }
    }

    return(err);
}

// If there's a comma followed by another character,
// FindFirstSubType overwrites the comma with a nul and returns the pointer to the next character.
// Otherwise, it returns a pointer to the final nul at the end of the string
mDNSlocal char *FindFirstSubType(char *p)
{
    while (*p)
    {
        if (p[0] == '\\' && p[1]) p += 2;
        else if (p[0] == ',' && p[1]) { *p++ = 0; return(p); }
        else p++;
    }
    return(p);
}

// If there's a comma followed by another character,
// FindNextSubType overwrites the comma with a nul and returns the pointer to the next character.
// If it finds an illegal unescaped dot in the subtype name, it returns mDNSNULL
// Otherwise, it returns a pointer to the final nul at the end of the string
mDNSlocal char *FindNextSubType(char *p)
{
    while (*p)
    {
        if (p[0] == '\\' && p[1])       // If escape character
            p += 2;                     // ignore following character
        else if (p[0] == ',')           // If we found a comma
        {
            if (p[1]) *p++ = 0;
            return(p);
        }
        else if (p[0] == '.')
            return(mDNSNULL);
        else p++;
    }
    return(p);
}

// Returns -1 if illegal subtype found
mDNSexport mDNSs32 ChopSubTypes(char *regtype)
{
    mDNSs32 NumSubTypes = 0;
    char *stp = FindFirstSubType(regtype);
    while (stp && *stp)                 // If we found a comma...
    {
        if (*stp == ',') return(-1);
        NumSubTypes++;
        stp = FindNextSubType(stp);
    }
    if (!stp) return(-1);
    return(NumSubTypes);
}

mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p)
{
    AuthRecord *st = mDNSNULL;
    if (NumSubTypes)
    {
        mDNSs32 i;
        st = mallocL("ServiceSubTypes", NumSubTypes * sizeof(AuthRecord));
        if (!st) return(mDNSNULL);
        for (i = 0; i < NumSubTypes; i++)
        {
            mDNS_SetupResourceRecord(&st[i], mDNSNULL, mDNSInterface_Any, kDNSQType_ANY, kStandardTTL, 0, AuthRecordAny, mDNSNULL, mDNSNULL);
            while (*p) p++;
            p++;
            if (!MakeDomainNameFromDNSNameString(&st[i].namestorage, p))
            { freeL("ServiceSubTypes", st); return(mDNSNULL); }
        }
    }
    return(st);
}

mDNSlocal mStatus register_service_instance(request_state *request, const domainname *domain)
{
    service_instance **ptr, *instance;
    const int extra_size = (request->u.servicereg.txtlen > sizeof(RDataBody)) ? (request->u.servicereg.txtlen - sizeof(RDataBody)) : 0;
    const mDNSBool DomainIsLocal = SameDomainName(domain, &localdomain);
    mStatus result;
    mDNSInterfaceID interfaceID = request->u.servicereg.InterfaceID;
    mDNSu32 coreFlags = 0;

    if (request->flags & kDNSServiceFlagsIncludeP2P)
        coreFlags |= coreFlagIncludeP2P;
    if (request->flags & kDNSServiceFlagsIncludeAWDL)
        coreFlags |= coreFlagIncludeAWDL;

    // client guarantees that record names are unique
    // we reuse this deprecated flag for his fucntion
    if (request->flags & kDNSServiceFlagsForce)
        coreFlags |= coreFlagKnownUnique;

    // If the client specified an interface, but no domain, then we honor the specified interface for the "local" (mDNS)
    // registration but for the wide-area registrations we don't (currently) have any concept of a wide-area unicast
    // registrations scoped to a specific interface, so for the automatic domains we add we must *not* specify an interface.
    // (Specifying an interface with an apparently wide-area domain (i.e. something other than "local")
    // currently forces the registration to use mDNS multicast despite the apparently wide-area domain.)
    if (request->u.servicereg.default_domain && !DomainIsLocal) interfaceID = mDNSInterface_Any;

    for (ptr = &request->u.servicereg.instances; *ptr; ptr = &(*ptr)->next)
    {
        if (SameDomainName(&(*ptr)->domain, domain))
        {
            LogMsg("register_service_instance: domain %##s already registered for %#s.%##s",
                   domain->c, &request->u.servicereg.name, &request->u.servicereg.type);
            return mStatus_AlreadyRegistered;
        }
    }

    if (mDNSStorage.KnownBugs & mDNS_KnownBug_LimitedIPv6)
    {
        // Special-case hack: On Mac OS X 10.6.x and earlier we don't advertise SMB service in AutoTunnel domains,
        // because AutoTunnel services have to support IPv6, and in Mac OS X 10.6.x the SMB server does not.
        // <rdar://problem/5482322> BTMM: Don't advertise SMB with BTMM because it doesn't support IPv6
        if (SameDomainName(&request->u.servicereg.type, (const domainname *) "\x4" "_smb" "\x4" "_tcp"))
        {
            DomainAuthInfo *AuthInfo = GetAuthInfoForName(&mDNSStorage, domain);
            if (AuthInfo && AuthInfo->AutoTunnel) return(kDNSServiceErr_Unsupported);
        }
    }

    instance = mallocL("service_instance", sizeof(*instance) + extra_size);
    if (!instance) { my_perror("ERROR: malloc"); return mStatus_NoMemoryErr; }

    instance->next                          = mDNSNULL;
    instance->request                       = request;
    instance->subtypes                      = AllocateSubTypes(request->u.servicereg.num_subtypes, request->u.servicereg.type_as_string);
    instance->renameonmemfree               = 0;
    instance->clientnotified                = mDNSfalse;
    instance->default_local                 = (request->u.servicereg.default_domain && DomainIsLocal);
    instance->external_advertise            = mDNSfalse;
    AssignDomainName(&instance->domain, domain);

    if (request->u.servicereg.num_subtypes && !instance->subtypes)
    { unlink_and_free_service_instance(instance); instance = NULL; FatalError("ERROR: malloc"); }

    result = mDNS_RegisterService(&mDNSStorage, &instance->srs,
                                  &request->u.servicereg.name, &request->u.servicereg.type, domain,
                                  request->u.servicereg.host.c[0] ? &request->u.servicereg.host : NULL,
                                  request->u.servicereg.port,
                                  request->u.servicereg.txtdata, request->u.servicereg.txtlen,
                                  instance->subtypes, request->u.servicereg.num_subtypes,
                                  interfaceID, regservice_callback, instance, coreFlags);

    if (!result)
    {
        *ptr = instance;        // Append this to the end of our request->u.servicereg.instances list
        LogOperation("%3d: DNSServiceRegister(%##s, %u) ADDED",
                     instance->request->sd, instance->srs.RR_SRV.resrec.name->c, mDNSVal16(request->u.servicereg.port));
    }
    else
    {
        LogMsg("register_service_instance %#s.%##s%##s error %d",
               &request->u.servicereg.name, &request->u.servicereg.type, domain->c, result);
        unlink_and_free_service_instance(instance);
    }

    return result;
}

mDNSlocal void udsserver_default_reg_domain_changed(const DNameListElem *const d, const mDNSBool add)
{
    request_state *request;

#if APPLE_OSX_mDNSResponder
    machserver_automatic_registration_domain_changed(&d->name, add);
#endif // APPLE_OSX_mDNSResponder

    LogMsg("%s registration domain %##s", add ? "Adding" : "Removing", d->name.c);
    for (request = all_requests; request; request = request->next)
    {
        if (request->terminate != regservice_termination_callback) continue;
        if (!request->u.servicereg.default_domain) continue;
        if (!d->uid || SystemUID(request->uid) || request->uid == d->uid)
        {
            service_instance **ptr = &request->u.servicereg.instances;
            while (*ptr && !SameDomainName(&(*ptr)->domain, &d->name)) ptr = &(*ptr)->next;
            if (add)
            {
                // If we don't already have this domain in our list for this registration, add it now
                if (!*ptr) register_service_instance(request, &d->name);
                else debugf("udsserver_default_reg_domain_changed %##s already in list, not re-adding", &d->name);
            }
            else
            {
                // Normally we should not fail to find the specified instance
                // One case where this can happen is if a uDNS update fails for some reason,
                // and regservice_callback then calls unlink_and_free_service_instance and disposes of that instance.
                if (!*ptr)
                    LogMsg("udsserver_default_reg_domain_changed domain %##s not found for service %#s type %s",
                           &d->name, request->u.servicereg.name.c, request->u.servicereg.type_as_string);
                else
                {
                    DNameListElem *p;
                    for (p = AutoRegistrationDomains; p; p=p->next)
                        if (!p->uid || SystemUID(request->uid) || request->uid == p->uid)
                            if (SameDomainName(&d->name, &p->name)) break;
                    if (p) debugf("udsserver_default_reg_domain_changed %##s still in list, not removing", &d->name);
                    else
                    {
                        mStatus err;
                        service_instance *si = *ptr;
                        *ptr = si->next;
                        if (si->clientnotified) SendServiceRemovalNotification(&si->srs); // Do this *before* clearing si->request backpointer
                        // Now that we've cut this service_instance from the list, we MUST clear the si->request backpointer.
                        // Otherwise what can happen is this: While our mDNS_DeregisterService is in the
                        // process of completing asynchronously, the client cancels the entire operation, so
                        // regservice_termination_callback then runs through the whole list deregistering each
                        // instance, clearing the backpointers, and then disposing the parent request_state object.
                        // However, because this service_instance isn't in the list any more, regservice_termination_callback
                        // has no way to find it and clear its backpointer, and then when our mDNS_DeregisterService finally
                        // completes later with a mStatus_MemFree message, it calls unlink_and_free_service_instance() with
                        // a service_instance with a stale si->request backpointer pointing to memory that's already been freed.
                        si->request = NULL;
                        err = mDNS_DeregisterService(&mDNSStorage, &si->srs);
                        if (err) { LogMsg("udsserver_default_reg_domain_changed err %d", err); unlink_and_free_service_instance(si); }
                    }
                }
            }
        }
    }
}

mDNSlocal mStatus handle_regservice_request(request_state *request)
{
    char name[256]; // Lots of spare space for extra-long names that we'll auto-truncate down to 63 bytes
    char domain[MAX_ESCAPED_DOMAIN_NAME], host[MAX_ESCAPED_DOMAIN_NAME];
    char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
    domainname d, srv;
    mStatus err;

    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    mDNSInterfaceID InterfaceID;

    // Map kDNSServiceInterfaceIndexP2P to kDNSServiceInterfaceIndexAny with the 
    // kDNSServiceFlagsIncludeP2P flag set.
    if (interfaceIndex == kDNSServiceInterfaceIndexP2P)
    {
        LogOperation("handle_regservice_request: mapping kDNSServiceInterfaceIndexP2P to kDNSServiceInterfaceIndexAny + kDNSServiceFlagsIncludeP2P");
        flags |= kDNSServiceFlagsIncludeP2P;
        interfaceIndex = kDNSServiceInterfaceIndexAny;
    }

    InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    if (interfaceIndex && !InterfaceID)
    { LogMsg("ERROR: handle_regservice_request - Couldn't find interfaceIndex %d", interfaceIndex); return(mStatus_BadParamErr); }

    if (get_string(&request->msgptr, request->msgend, name, sizeof(name)) < 0 ||
        get_string(&request->msgptr, request->msgend, type_as_string, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
        get_string(&request->msgptr, request->msgend, domain, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
        get_string(&request->msgptr, request->msgend, host, MAX_ESCAPED_DOMAIN_NAME) < 0)
    { LogMsg("ERROR: handle_regservice_request - Couldn't read name/regtype/domain"); return(mStatus_BadParamErr); }

    request->flags = flags;
    request->u.servicereg.InterfaceID = InterfaceID;
    request->u.servicereg.instances = NULL;
    request->u.servicereg.txtlen  = 0;
    request->u.servicereg.txtdata = NULL;
    mDNSPlatformStrCopy(request->u.servicereg.type_as_string, type_as_string);

    if (request->msgptr + 2 > request->msgend) request->msgptr = NULL;
    else
    {
        request->u.servicereg.port.b[0] = *request->msgptr++;
        request->u.servicereg.port.b[1] = *request->msgptr++;
    }

    request->u.servicereg.txtlen = get_uint16(&request->msgptr, request->msgend);
    if (request->u.servicereg.txtlen)
    {
        request->u.servicereg.txtdata = mallocL("service_info txtdata", request->u.servicereg.txtlen);
        if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_regservice_request - malloc");
        mDNSPlatformMemCopy(request->u.servicereg.txtdata, get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen), request->u.servicereg.txtlen);
    }

    if (!request->msgptr) { LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    // Check for sub-types after the service type
    request->u.servicereg.num_subtypes = ChopSubTypes(request->u.servicereg.type_as_string);    // Note: Modifies regtype string to remove trailing subtypes
    if (request->u.servicereg.num_subtypes < 0)
    { LogMsg("ERROR: handle_regservice_request - ChopSubTypes failed %s", request->u.servicereg.type_as_string); return(mStatus_BadParamErr); }

    // Don't try to construct "domainname t" until *after* ChopSubTypes has worked its magic
    if (!*request->u.servicereg.type_as_string || !MakeDomainNameFromDNSNameString(&request->u.servicereg.type, request->u.servicereg.type_as_string))
    { LogMsg("ERROR: handle_regservice_request - type_as_string bad %s", request->u.servicereg.type_as_string); return(mStatus_BadParamErr); }

    if (!name[0])
    {
        request->u.servicereg.name = mDNSStorage.nicelabel;
        request->u.servicereg.autoname = mDNStrue;
    }
    else
    {
        // If the client is allowing AutoRename, then truncate name to legal length before converting it to a DomainLabel
        if ((flags & kDNSServiceFlagsNoAutoRename) == 0)
        {
            int newlen = TruncateUTF8ToLength((mDNSu8*)name, mDNSPlatformStrLen(name), MAX_DOMAIN_LABEL);
            name[newlen] = 0;
        }
        if (!MakeDomainLabelFromLiteralString(&request->u.servicereg.name, name))
        { LogMsg("ERROR: handle_regservice_request - name bad %s", name); return(mStatus_BadParamErr); }
        request->u.servicereg.autoname = mDNSfalse;
    }

    if (*domain)
    {
        request->u.servicereg.default_domain = mDNSfalse;
        if (!MakeDomainNameFromDNSNameString(&d, domain))
        { LogMsg("ERROR: handle_regservice_request - domain bad %s", domain); return(mStatus_BadParamErr); }
    }
    else
    {
        request->u.servicereg.default_domain = mDNStrue;
        MakeDomainNameFromDNSNameString(&d, "local.");
    }

    if (!ConstructServiceName(&srv, &request->u.servicereg.name, &request->u.servicereg.type, &d))
    {
        LogMsg("ERROR: handle_regservice_request - Couldn't ConstructServiceName from, “%#s” “%##s” “%##s”",
               request->u.servicereg.name.c, request->u.servicereg.type.c, d.c); return(mStatus_BadParamErr);
    }

    if (!MakeDomainNameFromDNSNameString(&request->u.servicereg.host, host))
    { LogMsg("ERROR: handle_regservice_request - host bad %s", host); return(mStatus_BadParamErr); }
    request->u.servicereg.autorename       = (flags & kDNSServiceFlagsNoAutoRename    ) == 0;
    request->u.servicereg.allowremotequery = (flags & kDNSServiceFlagsAllowRemoteQuery) != 0;

    // Some clients use mDNS for lightweight copy protection, registering a pseudo-service with
    // a port number of zero. When two instances of the protected client are allowed to run on one
    // machine, we don't want to see misleading "Bogus client" messages in syslog and the console.
    if (!mDNSIPPortIsZero(request->u.servicereg.port))
    {
        int count = CountExistingRegistrations(&srv, request->u.servicereg.port);
        if (count)
            LogMsg("Client application registered %d identical instances of service %##s port %u.",
                   count+1, srv.c, mDNSVal16(request->u.servicereg.port));
    }

    LogOperation("%3d: DNSServiceRegister(%X, %d, \"%s\", \"%s\", \"%s\", \"%s\", %u) START PID[%d](%s)",
    	request->sd, flags, interfaceIndex, name, request->u.servicereg.type_as_string, domain, host, 
    mDNSVal16(request->u.servicereg.port), get_peer_pid(request->sd, pid_name), pid_name);

    // We need to unconditionally set request->terminate, because even if we didn't successfully
    // start any registrations right now, subsequent configuration changes may cause successful
    // registrations to be added, and we'll need to cancel them before freeing this memory.
    // We also need to set request->terminate first, before adding additional service instances,
    // because the uds_validatelists uses the request->terminate function pointer to determine
    // what kind of request this is, and therefore what kind of list validation is required.
    request->terminate = regservice_termination_callback;

    err = register_service_instance(request, &d);

#if 0
    err = AuthorizedDomain(request, &d, AutoRegistrationDomains) ? register_service_instance(request, &d) : mStatus_NoError;
#endif
    if (!err)
    {
        if (request->u.servicereg.autoname) UpdateDeviceInfoRecord(&mDNSStorage);

        if (!*domain)
        {
            DNameListElem *ptr;
            // Note that we don't report errors for non-local, non-explicit domains
            for (ptr = AutoRegistrationDomains; ptr; ptr = ptr->next)
                if (!ptr->uid || SystemUID(request->uid) || request->uid == ptr->uid)
                    register_service_instance(request, &ptr->name);
        }
    }

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceBrowse
#endif

mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
    const DNSServiceFlags flags = AddRecord ? kDNSServiceFlagsAdd : 0;
    request_state *req = question->QuestionContext;
    reply_state *rep;
    (void)m; // Unused

    if (answer->rrtype != kDNSType_PTR)
    { LogMsg("%3d: FoundInstance: Should not be called with rrtype %d (not a PTR record)", req->sd, answer->rrtype); return; }

    if (GenerateNTDResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError) != mStatus_NoError)
    {
        if (SameDomainName(&req->u.browser.regtype, (const domainname*)"\x09_services\x07_dns-sd\x04_udp"))
        {
            // Special support to enable the DNSServiceBrowse call made by Bonjour Browser
            // Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
            GenerateBonjourBrowserResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError);
            goto bonjourbrowserhack;
        }

        LogMsg("%3d: FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer",
               req->sd, answer->name->c, answer->rdata->u.name.c);
        return;
    }

bonjourbrowserhack:

    LogOperation("%3d: DNSServiceBrowse(%##s, %s) RESULT %s %d: %s",
                 req->sd, question->qname.c, DNSTypeName(question->qtype), AddRecord ? "Add" : "Rmv",
                 mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse), RRDisplayString(m, answer));

    append_reply(req, rep);
}

mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d)
{
    browser_t *b, *p;
    mStatus err;

    for (p = info->u.browser.browsers; p; p = p->next)
    {
        if (SameDomainName(&p->domain, d))
        { debugf("add_domain_to_browser %##s already in list", d->c); return mStatus_AlreadyRegistered; }
    }

    b = mallocL("browser_t", sizeof(*b));
    if (!b) return mStatus_NoMemoryErr;
    AssignDomainName(&b->domain, d);
    err = mDNS_StartBrowse(&mDNSStorage, &b->q,
                           &info->u.browser.regtype, d, info->u.browser.interface_id, info->flags, info->u.browser.ForceMCast, (info->flags & kDNSServiceFlagsBackgroundTrafficClass) != 0, FoundInstance, info);
    if (err)
    {
        LogMsg("mDNS_StartBrowse returned %d for type %##s domain %##s", err, info->u.browser.regtype.c, d->c);
        freeL("browser_t/add_domain_to_browser", b);
    }
    else
    {
        b->next = info->u.browser.browsers;
        info->u.browser.browsers = b;
        LogOperation("%3d: DNSServiceBrowse(%##s) START PID[%d](%s)", info->sd, b->q.qname.c, get_peer_pid(info->sd, pid_name), pid_name);

        if (callExternalHelpers(info->u.browser.interface_id, &b->domain, info->flags))
        {
            domainname tmp;
            ConstructServiceName(&tmp, NULL, &info->u.browser.regtype, &b->domain);
            LogInfo("add_domain_to_browser: calling external_start_browsing_for_service()");
            external_start_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags);
        }
    }
    return err;
}

mDNSlocal void browse_termination_callback(request_state *info)
{
    while (info->u.browser.browsers)
    {
        browser_t *ptr = info->u.browser.browsers;

        if (callExternalHelpers(info->u.browser.interface_id, &ptr->domain, info->flags))
        {
            domainname tmp;
            ConstructServiceName(&tmp, NULL, &info->u.browser.regtype, &ptr->domain);
            LogInfo("browse_termination_callback: calling external_stop_browsing_for_service()");
            external_stop_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags);
        }

        info->u.browser.browsers = ptr->next;
        LogOperation("%3d: DNSServiceBrowse(%##s) STOP PID[%d](%s)", info->sd, ptr->q.qname.c, get_peer_pid(info->sd, pid_name), pid_name);
        mDNS_StopBrowse(&mDNSStorage, &ptr->q);  // no need to error-check result
        freeL("browser_t/browse_termination_callback", ptr);
    }
}

mDNSlocal void udsserver_automatic_browse_domain_changed(const DNameListElem *const d, const mDNSBool add)
{
    request_state *request;
    debugf("udsserver_automatic_browse_domain_changed: %s default browse domain %##s", add ? "Adding" : "Removing", d->name.c);

#if APPLE_OSX_mDNSResponder
    machserver_automatic_browse_domain_changed(&d->name, add);
#endif // APPLE_OSX_mDNSResponder

    for (request = all_requests; request; request = request->next)
    {
        if (request->terminate != browse_termination_callback) continue;    // Not a browse operation
        if (!request->u.browser.default_domain) continue;                   // Not an auto-browse operation
        if (!d->uid || SystemUID(request->uid) || request->uid == d->uid)
        {
            browser_t **ptr = &request->u.browser.browsers;
            while (*ptr && !SameDomainName(&(*ptr)->domain, &d->name)) ptr = &(*ptr)->next;
            if (add)
            {
                // If we don't already have this domain in our list for this browse operation, add it now
                if (!*ptr) add_domain_to_browser(request, &d->name);
                else debugf("udsserver_automatic_browse_domain_changed %##s already in list, not re-adding", &d->name);
            }
            else
            {
                if (!*ptr) LogMsg("udsserver_automatic_browse_domain_changed ERROR %##s not found", &d->name);
                else
                {
                    DNameListElem *p;
                    for (p = AutoBrowseDomains; p; p=p->next)
                        if (!p->uid || SystemUID(request->uid) || request->uid == p->uid)
                            if (SameDomainName(&d->name, &p->name)) break;
                    if (p) debugf("udsserver_automatic_browse_domain_changed %##s still in list, not removing", &d->name);
                    else
                    {
                        browser_t *rem = *ptr;
                        *ptr = (*ptr)->next;
                        mDNS_StopQueryWithRemoves(&mDNSStorage, &rem->q);
                        freeL("browser_t/udsserver_automatic_browse_domain_changed", rem);
                    }
                }
            }
        }
    }
}

mDNSlocal void FreeARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
{
    (void)m;  // unused
    if (result == mStatus_MemFree)
    {
        // On shutdown, mDNS_Close automatically deregisters all records
        // Since in this case no one has called DeregisterLocalOnlyDomainEnumPTR to cut the record
        // from the LocalDomainEnumRecords list, we do this here before we free the memory.
        // (This should actually no longer be necessary, now that we do the proper cleanup in
        // udsserver_exit. To confirm this, we'll log an error message if we do find a record that
        // hasn't been cut from the list yet. If these messages don't appear, we can delete this code.)
        ARListElem **ptr = &LocalDomainEnumRecords;
        while (*ptr && &(*ptr)->ar != rr) ptr = &(*ptr)->next;
        if (*ptr) { *ptr = (*ptr)->next; LogMsg("FreeARElemCallback: Have to cut %s", ARDisplayString(m, rr)); }
        mDNSPlatformMemFree(rr->RecordContext);
    }
}

// RegisterLocalOnlyDomainEnumPTR and DeregisterLocalOnlyDomainEnumPTR largely duplicate code in
// "FoundDomain" in uDNS.c for creating and destroying these special mDNSInterface_LocalOnly records.
// We may want to turn the common code into a subroutine.

mDNSlocal void RegisterLocalOnlyDomainEnumPTR(mDNS *m, const domainname *d, int type)
{
    // allocate/register legacy and non-legacy _browse PTR record
    mStatus err;
    ARListElem *ptr = mDNSPlatformMemAllocate(sizeof(*ptr));

    debugf("Incrementing %s refcount for %##s",
           (type == mDNS_DomainTypeBrowse         ) ? "browse domain   " :
           (type == mDNS_DomainTypeRegistration   ) ? "registration dom" :
           (type == mDNS_DomainTypeBrowseAutomatic) ? "automatic browse" : "?", d->c);

    mDNS_SetupResourceRecord(&ptr->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, AuthRecordLocalOnly, FreeARElemCallback, ptr);
    MakeDomainNameFromDNSNameString(&ptr->ar.namestorage, mDNS_DomainTypeNames[type]);
    AppendDNSNameString            (&ptr->ar.namestorage, "local");
    AssignDomainName(&ptr->ar.resrec.rdata->u.name, d);
    err = mDNS_Register(m, &ptr->ar);
    if (err)
    {
        LogMsg("SetSCPrefsBrowseDomain: mDNS_Register returned error %d", err);
        mDNSPlatformMemFree(ptr);
    }
    else
    {
        ptr->next = LocalDomainEnumRecords;
        LocalDomainEnumRecords = ptr;
    }
}

mDNSlocal void DeregisterLocalOnlyDomainEnumPTR(mDNS *m, const domainname *d, int type)
{
    ARListElem **ptr = &LocalDomainEnumRecords;
    domainname lhs; // left-hand side of PTR, for comparison

    debugf("Decrementing %s refcount for %##s",
           (type == mDNS_DomainTypeBrowse         ) ? "browse domain   " :
           (type == mDNS_DomainTypeRegistration   ) ? "registration dom" :
           (type == mDNS_DomainTypeBrowseAutomatic) ? "automatic browse" : "?", d->c);

    MakeDomainNameFromDNSNameString(&lhs, mDNS_DomainTypeNames[type]);
    AppendDNSNameString            (&lhs, "local");

    while (*ptr)
    {
        if (SameDomainName(&(*ptr)->ar.resrec.rdata->u.name, d) && SameDomainName((*ptr)->ar.resrec.name, &lhs))
        {
            ARListElem *rem = *ptr;
            *ptr = (*ptr)->next;
            mDNS_Deregister(m, &rem->ar);
            return;
        }
        else ptr = &(*ptr)->next;
    }
}

mDNSlocal void AddAutoBrowseDomain(const mDNSu32 uid, const domainname *const name)
{
    DNameListElem *new = mDNSPlatformMemAllocate(sizeof(DNameListElem));
    if (!new) { LogMsg("ERROR: malloc"); return; }
    AssignDomainName(&new->name, name);
    new->uid = uid;
    new->next = AutoBrowseDomains;
    AutoBrowseDomains = new;
    udsserver_automatic_browse_domain_changed(new, mDNStrue);
}

mDNSlocal void RmvAutoBrowseDomain(const mDNSu32 uid, const domainname *const name)
{
    DNameListElem **p = &AutoBrowseDomains;
    while (*p && (!SameDomainName(&(*p)->name, name) || (*p)->uid != uid)) p = &(*p)->next;
    if (!*p) LogMsg("RmvAutoBrowseDomain: Got remove event for domain %##s not in list", name->c);
    else
    {
        DNameListElem *ptr = *p;
        *p = ptr->next;
        udsserver_automatic_browse_domain_changed(ptr, mDNSfalse);
        mDNSPlatformMemFree(ptr);
    }
}

mDNSlocal void SetPrefsBrowseDomains(mDNS *m, DNameListElem *browseDomains, mDNSBool add)
{
    DNameListElem *d;
    for (d = browseDomains; d; d = d->next)
    {
        if (add)
        {
            RegisterLocalOnlyDomainEnumPTR(m, &d->name, mDNS_DomainTypeBrowse);
            AddAutoBrowseDomain(d->uid, &d->name);
        }
        else
        {
            DeregisterLocalOnlyDomainEnumPTR(m, &d->name, mDNS_DomainTypeBrowse);
            RmvAutoBrowseDomain(d->uid, &d->name);
        }
    }
}

mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m)
{
    int num_autoname = 0;
    request_state *req;
    for (req = all_requests; req; req = req->next)
        if (req->terminate == regservice_termination_callback && req->u.servicereg.autoname)
            num_autoname++;

    // If DeviceInfo record is currently registered, see if we need to deregister it
    if (m->DeviceInfo.resrec.RecordType != kDNSRecordTypeUnregistered)
        if (num_autoname == 0 || !SameDomainLabelCS(m->DeviceInfo.resrec.name->c, m->nicelabel.c))
        {
            LogOperation("UpdateDeviceInfoRecord Deregister %##s", m->DeviceInfo.resrec.name);
            mDNS_Deregister(m, &m->DeviceInfo);
        }

    // If DeviceInfo record is not currently registered, see if we need to register it
    if (m->DeviceInfo.resrec.RecordType == kDNSRecordTypeUnregistered)
        if (num_autoname > 0)
        {
            mDNSu8 len = m->HIHardware.c[0] < 255 - 6 ? m->HIHardware.c[0] : 255 - 6;
            mDNS_SetupResourceRecord(&m->DeviceInfo, mDNSNULL, mDNSNULL, kDNSType_TXT, kStandardTTL, kDNSRecordTypeAdvisory, AuthRecordAny, mDNSNULL, mDNSNULL);
            ConstructServiceName(&m->DeviceInfo.namestorage, &m->nicelabel, &DeviceInfoName, &localdomain);
            mDNSPlatformMemCopy(m->DeviceInfo.resrec.rdata->u.data + 1, "model=", 6);
            mDNSPlatformMemCopy(m->DeviceInfo.resrec.rdata->u.data + 7, m->HIHardware.c + 1, len);
            m->DeviceInfo.resrec.rdata->u.data[0] = 6 + len;    // "model=" plus the device string
            m->DeviceInfo.resrec.rdlength         = 7 + len;    // One extra for the length byte at the start of the string
            LogOperation("UpdateDeviceInfoRecord   Register %##s", m->DeviceInfo.resrec.name);
            mDNS_Register(m, &m->DeviceInfo);
        }
}

mDNSexport void udsserver_handle_configchange(mDNS *const m)
{
    request_state *req;
    service_instance *ptr;
    DNameListElem *RegDomains = NULL;
    DNameListElem *BrowseDomains = NULL;
    DNameListElem *p;

    UpdateDeviceInfoRecord(m);

    // For autoname services, see if the default service name has changed, necessitating an automatic update
    for (req = all_requests; req; req = req->next)
        if (req->terminate == regservice_termination_callback)
            if (req->u.servicereg.autoname && !SameDomainLabelCS(req->u.servicereg.name.c, m->nicelabel.c))
            {
                req->u.servicereg.name = m->nicelabel;
                for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
                {
                    ptr->renameonmemfree = 1;
                    if (ptr->clientnotified) SendServiceRemovalNotification(&ptr->srs);
                    LogInfo("udsserver_handle_configchange: Calling deregister for Service %##s", ptr->srs.RR_PTR.resrec.name->c);
                    if (mDNS_DeregisterService_drt(m, &ptr->srs, mDNS_Dereg_rapid))
                        regservice_callback(m, &ptr->srs, mStatus_MemFree); // If service deregistered already, we can re-register immediately
                }
            }

    // Let the platform layer get the current DNS information
    mDNS_Lock(m);
    mDNSPlatformSetDNSConfig(m, mDNSfalse, mDNSfalse, mDNSNULL, &RegDomains, &BrowseDomains);
    mDNS_Unlock(m);

    // Any automatic registration domains are also implicitly automatic browsing domains
    if (RegDomains) SetPrefsBrowseDomains(m, RegDomains, mDNStrue);                             // Add the new list first
    if (AutoRegistrationDomains) SetPrefsBrowseDomains(m, AutoRegistrationDomains, mDNSfalse);  // Then clear the old list

    // Add any new domains not already in our AutoRegistrationDomains list
    for (p=RegDomains; p; p=p->next)
    {
        DNameListElem **pp = &AutoRegistrationDomains;
        while (*pp && ((*pp)->uid != p->uid || !SameDomainName(&(*pp)->name, &p->name))) pp = &(*pp)->next;
        if (!*pp)       // If not found in our existing list, this is a new default registration domain
        {
            RegisterLocalOnlyDomainEnumPTR(m, &p->name, mDNS_DomainTypeRegistration);
            udsserver_default_reg_domain_changed(p, mDNStrue);
        }
        else            // else found same domainname in both old and new lists, so no change, just delete old copy
        {
            DNameListElem *del = *pp;
            *pp = (*pp)->next;
            mDNSPlatformMemFree(del);
        }
    }

    // Delete any domains in our old AutoRegistrationDomains list that are now gone
    while (AutoRegistrationDomains)
    {
        DNameListElem *del = AutoRegistrationDomains;
        AutoRegistrationDomains = AutoRegistrationDomains->next;        // Cut record from list FIRST,
        DeregisterLocalOnlyDomainEnumPTR(m, &del->name, mDNS_DomainTypeRegistration);
        udsserver_default_reg_domain_changed(del, mDNSfalse);           // before calling udsserver_default_reg_domain_changed()
        mDNSPlatformMemFree(del);
    }

    // Now we have our new updated automatic registration domain list
    AutoRegistrationDomains = RegDomains;

    // Add new browse domains to internal list
    if (BrowseDomains) SetPrefsBrowseDomains(m, BrowseDomains, mDNStrue);

    // Remove old browse domains from internal list
    if (SCPrefBrowseDomains)
    {
        SetPrefsBrowseDomains(m, SCPrefBrowseDomains, mDNSfalse);
        while (SCPrefBrowseDomains)
        {
            DNameListElem *fptr = SCPrefBrowseDomains;
            SCPrefBrowseDomains = SCPrefBrowseDomains->next;
            mDNSPlatformMemFree(fptr);
        }
    }

    // Replace the old browse domains array with the new array
    SCPrefBrowseDomains = BrowseDomains;
}

mDNSlocal void AutomaticBrowseDomainChange(mDNS *const m, DNSQuestion *q, const ResourceRecord *const answer, QC_result AddRecord)
{
    (void)m; // unused;
    (void)q; // unused

    LogOperation("AutomaticBrowseDomainChange: %s automatic browse domain %##s",
                 AddRecord ? "Adding" : "Removing", answer->rdata->u.name.c);

    if (AddRecord) AddAutoBrowseDomain(0, &answer->rdata->u.name);
    else RmvAutoBrowseDomain(0, &answer->rdata->u.name);
}

mDNSlocal mStatus handle_browse_request(request_state *request)
{
    char regtype[MAX_ESCAPED_DOMAIN_NAME], domain[MAX_ESCAPED_DOMAIN_NAME];
    domainname typedn, d, temp;
    mDNSs32 NumSubTypes;
    mStatus err = mStatus_NoError;

    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);

    if (get_string(&request->msgptr, request->msgend, regtype, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
        get_string(&request->msgptr, request->msgend, domain, MAX_ESCAPED_DOMAIN_NAME) < 0) return(mStatus_BadParamErr);

    if (!request->msgptr) { LogMsg("%3d: DNSServiceBrowse(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    if (domain[0] == '\0') uDNS_SetupSearchDomains(&mDNSStorage, UDNS_START_WAB_QUERY);

    request->flags = flags;
    typedn.c[0] = 0;
    NumSubTypes = ChopSubTypes(regtype);    // Note: Modifies regtype string to remove trailing subtypes
    if (NumSubTypes < 0 || NumSubTypes > 1) return(mStatus_BadParamErr);
    if (NumSubTypes == 1 && !AppendDNSNameString(&typedn, regtype + strlen(regtype) + 1)) return(mStatus_BadParamErr);

    if (!regtype[0] || !AppendDNSNameString(&typedn, regtype)) return(mStatus_BadParamErr);

    if (!MakeDomainNameFromDNSNameString(&temp, regtype)) return(mStatus_BadParamErr);
    // For over-long service types, we only allow domain "local"
    if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrCopy(domain, "local.");

    // Set up browser info
    request->u.browser.ForceMCast = (flags & kDNSServiceFlagsForceMulticast) != 0;
    request->u.browser.interface_id = InterfaceID;
    AssignDomainName(&request->u.browser.regtype, &typedn);
    request->u.browser.default_domain = !domain[0];
    request->u.browser.browsers = NULL;

    LogOperation("%3d: DNSServiceBrowse(%X, %d, \"%##s\", \"%s\") START PID[%d](%s)", 
    request->sd, request->flags, interfaceIndex, request->u.browser.regtype.c, domain, get_peer_pid(request->sd, pid_name), pid_name);

    // We need to unconditionally set request->terminate, because even if we didn't successfully
    // start any browses right now, subsequent configuration changes may cause successful
    // browses to be added, and we'll need to cancel them before freeing this memory.
    request->terminate = browse_termination_callback;

    if (domain[0])
    {
        if (!MakeDomainNameFromDNSNameString(&d, domain)) return(mStatus_BadParamErr);
        err = add_domain_to_browser(request, &d);
    }
    else
    {
        DNameListElem *sdom;
        for (sdom = AutoBrowseDomains; sdom; sdom = sdom->next)
            if (!sdom->uid || SystemUID(request->uid) || request->uid == sdom->uid)
            {
                err = add_domain_to_browser(request, &sdom->name);
                if (err)
                {
                    if (SameDomainName(&sdom->name, &localdomain)) break;
                    else err = mStatus_NoError;  // suppress errors for non-local "default" domains
                }
            }
    }

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceResolve
#endif

mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
    size_t len = 0;
    char fullname[MAX_ESCAPED_DOMAIN_NAME], target[MAX_ESCAPED_DOMAIN_NAME];
    char *data;
    reply_state *rep;
    request_state *req = question->QuestionContext;
    (void)m; // Unused

    LogOperation("%3d: DNSServiceResolve(%##s) %s %s", req->sd, question->qname.c, AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));

    if (!AddRecord)
    {
        if (req->u.resolve.srv == answer) req->u.resolve.srv = mDNSNULL;
        if (req->u.resolve.txt == answer) req->u.resolve.txt = mDNSNULL;
        return;
    }

    if (answer->rrtype == kDNSType_SRV) req->u.resolve.srv = answer;
    if (answer->rrtype == kDNSType_TXT) req->u.resolve.txt = answer;

    if (!req->u.resolve.txt || !req->u.resolve.srv) return;     // only deliver result to client if we have both answers

    ConvertDomainNameToCString(answer->name, fullname);
    ConvertDomainNameToCString(&req->u.resolve.srv->rdata->u.srv.target, target);

    // calculate reply length
    len += sizeof(DNSServiceFlags);
    len += sizeof(mDNSu32);  // interface index
    len += sizeof(DNSServiceErrorType);
    len += strlen(fullname) + 1;
    len += strlen(target) + 1;
    len += 2 * sizeof(mDNSu16);  // port, txtLen
    len += req->u.resolve.txt->rdlength;

    // allocate/init reply header
    rep = create_reply(resolve_reply_op, len, req);
    rep->rhdr->flags = dnssd_htonl(0);
    rep->rhdr->ifi   = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse));
    rep->rhdr->error = dnssd_htonl(kDNSServiceErr_NoError);

    data = (char *)&rep->rhdr[1];

    // write reply data to message
    put_string(fullname, &data);
    put_string(target, &data);
    *data++ =  req->u.resolve.srv->rdata->u.srv.port.b[0];
    *data++ =  req->u.resolve.srv->rdata->u.srv.port.b[1];
    put_uint16(req->u.resolve.txt->rdlength, &data);
    put_rdata (req->u.resolve.txt->rdlength, req->u.resolve.txt->rdata->u.data, &data);

    LogOperation("%3d: DNSServiceResolve(%s) RESULT   %s:%d", req->sd, fullname, target, mDNSVal16(req->u.resolve.srv->rdata->u.srv.port));
    append_reply(req, rep);
}

mDNSlocal void resolve_termination_callback(request_state *request)
{
    LogOperation("%3d: DNSServiceResolve(%##s) STOP PID[%d](%s)", request->sd, request->u.resolve.qtxt.qname.c, get_peer_pid(request->sd, pid_name), pid_name);
    mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qtxt);
    mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
    if (request->u.resolve.external_advertise) external_stop_resolving_service(request->u.resolve.qsrv.InterfaceID, &request->u.resolve.qsrv.qname, request->flags);
}

mDNSlocal mStatus handle_resolve_request(request_state *request)
{
    char name[256], regtype[MAX_ESCAPED_DOMAIN_NAME], domain[MAX_ESCAPED_DOMAIN_NAME];
    domainname fqdn;
    mStatus err;

    // extract the data from the message
    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    mDNSInterfaceID InterfaceID;

    // Map kDNSServiceInterfaceIndexP2P to kDNSServiceInterfaceIndexAny with the kDNSServiceFlagsIncludeP2P
    // flag set so that the resolve will run over P2P interfaces that are not yet created.
    if (interfaceIndex == kDNSServiceInterfaceIndexP2P)
    {
        LogOperation("handle_resolve_request: mapping kDNSServiceInterfaceIndexP2P to kDNSServiceInterfaceIndexAny + kDNSServiceFlagsIncludeP2P");
        flags |= kDNSServiceFlagsIncludeP2P;
        interfaceIndex = kDNSServiceInterfaceIndexAny;
    }

    InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    if (interfaceIndex && !InterfaceID)
    { LogMsg("ERROR: handle_resolve_request bad interfaceIndex %d", interfaceIndex); return(mStatus_BadParamErr); }

    if (get_string(&request->msgptr, request->msgend, name, 256) < 0 ||
        get_string(&request->msgptr, request->msgend, regtype, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
        get_string(&request->msgptr, request->msgend, domain, MAX_ESCAPED_DOMAIN_NAME) < 0)
    { LogMsg("ERROR: handle_resolve_request - Couldn't read name/regtype/domain"); return(mStatus_BadParamErr); }

    if (!request->msgptr) { LogMsg("%3d: DNSServiceResolve(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    if (build_domainname_from_strings(&fqdn, name, regtype, domain) < 0)
    { LogMsg("ERROR: handle_resolve_request bad “%s” “%s” “%s”", name, regtype, domain); return(mStatus_BadParamErr); }

    mDNSPlatformMemZero(&request->u.resolve, sizeof(request->u.resolve));

    request->flags = flags;

    // format questions
    request->u.resolve.qsrv.InterfaceID      = InterfaceID;
    request->u.resolve.qsrv.flags            = flags;
    request->u.resolve.qsrv.Target           = zeroAddr;
    AssignDomainName(&request->u.resolve.qsrv.qname, &fqdn);
    request->u.resolve.qsrv.qtype            = kDNSType_SRV;
    request->u.resolve.qsrv.qclass           = kDNSClass_IN;
    request->u.resolve.qsrv.LongLived        = (flags & kDNSServiceFlagsLongLivedQuery     ) != 0;
    request->u.resolve.qsrv.ExpectUnique     = mDNStrue;
    request->u.resolve.qsrv.ForceMCast       = (flags & kDNSServiceFlagsForceMulticast     ) != 0;
    request->u.resolve.qsrv.ReturnIntermed   = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
    request->u.resolve.qsrv.SuppressUnusable = mDNSfalse;
    request->u.resolve.qsrv.SearchListIndex  = 0;
    request->u.resolve.qsrv.AppendSearchDomains = 0;
    request->u.resolve.qsrv.RetryWithSearchDomains = mDNSfalse;
    request->u.resolve.qsrv.TimeoutQuestion  = 0;
    request->u.resolve.qsrv.WakeOnResolve    = (flags & kDNSServiceFlagsWakeOnResolve) != 0;
    request->u.resolve.qsrv.UseBrackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
    request->u.resolve.qsrv.ValidationRequired = 0;
    request->u.resolve.qsrv.ValidatingResponse = 0;
    request->u.resolve.qsrv.qnameOrig        = mDNSNULL;
    request->u.resolve.qsrv.QuestionCallback = resolve_result_callback;
    request->u.resolve.qsrv.QuestionContext  = request;

    request->u.resolve.qtxt.InterfaceID      = InterfaceID;
    request->u.resolve.qtxt.flags            = flags;
    request->u.resolve.qtxt.Target           = zeroAddr;
    AssignDomainName(&request->u.resolve.qtxt.qname, &fqdn);
    request->u.resolve.qtxt.qtype            = kDNSType_TXT;
    request->u.resolve.qtxt.qclass           = kDNSClass_IN;
    request->u.resolve.qtxt.LongLived        = (flags & kDNSServiceFlagsLongLivedQuery     ) != 0;
    request->u.resolve.qtxt.ExpectUnique     = mDNStrue;
    request->u.resolve.qtxt.ForceMCast       = (flags & kDNSServiceFlagsForceMulticast     ) != 0;
    request->u.resolve.qtxt.ReturnIntermed   = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
    request->u.resolve.qtxt.SuppressUnusable = mDNSfalse;
    request->u.resolve.qtxt.SearchListIndex  = 0;
    request->u.resolve.qtxt.AppendSearchDomains = 0;
    request->u.resolve.qtxt.RetryWithSearchDomains = mDNSfalse;
    request->u.resolve.qtxt.TimeoutQuestion  = 0;
    request->u.resolve.qtxt.WakeOnResolve    = 0;
    request->u.resolve.qtxt.UseBrackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
    request->u.resolve.qtxt.ValidationRequired = 0;
    request->u.resolve.qtxt.ValidatingResponse = 0;
    request->u.resolve.qtxt.qnameOrig        = mDNSNULL;
    request->u.resolve.qtxt.QuestionCallback = resolve_result_callback;
    request->u.resolve.qtxt.QuestionContext  = request;

    request->u.resolve.ReportTime            = NonZeroTime(mDNS_TimeNow(&mDNSStorage) + 130 * mDNSPlatformOneSecond);

    request->u.resolve.external_advertise    = mDNSfalse;

#if 0
    if (!AuthorizedDomain(request, &fqdn, AutoBrowseDomains)) return(mStatus_NoError);
#endif

    // ask the questions
    LogOperation("%3d: DNSServiceResolve(%X %d %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex, 
    	request->u.resolve.qsrv.qname.c, get_peer_pid(request->sd, pid_name), pid_name);
    err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qsrv);
    if (!err)
    {
        err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qtxt);
        if (err) mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
        else
        {
            request->terminate = resolve_termination_callback;

            if (callExternalHelpers(InterfaceID, &fqdn, flags))
            {
                request->u.resolve.external_advertise    = mDNStrue;
                LogInfo("handle_resolve_request: calling external_start_resolving_service()");
                external_start_resolving_service(InterfaceID, &fqdn, flags);
            }
        }
    }

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceQueryRecord
#endif

// mDNS operation functions. Each operation has 3 associated functions - a request handler that parses
// the client's request and makes the appropriate mDNSCore call, a result handler (passed as a callback
// to the mDNSCore routine) that sends results back to the client, and a termination routine that aborts
// the mDNSCore operation if the client dies or closes its socket.

// Returns -1 to tell the caller that it should not try to reissue the query anymore
// Returns 1 on successfully appending a search domain and the caller should reissue the new query
// Returns 0 when there are no more search domains and the caller should reissue the query
mDNSlocal int AppendNewSearchDomain(mDNS *const m, DNSQuestion *question)
{
    domainname *sd;
    mStatus err;

    // Sanity check: The caller already checks this. We use -1 to indicate that we have searched all
    // the domains and should try the single label query directly on the wire.
    if (question->SearchListIndex == -1)
    {
        LogMsg("AppendNewSearchDomain: question %##s (%s) SearchListIndex is -1", question->qname.c, DNSTypeName(question->qtype));
        return -1;
    }

    if (!question->AppendSearchDomains)
    {
        LogMsg("AppendNewSearchDomain: question %##s (%s) AppendSearchDoamins is 0", question->qname.c, DNSTypeName(question->qtype));
        return -1;
    }

    // Save the original name, before we modify them below.
    if (!question->qnameOrig)
    {
        question->qnameOrig =  mallocL("AppendNewSearchDomain", sizeof(domainname));
        if (!question->qnameOrig) { LogMsg("AppendNewSearchDomain: ERROR!!  malloc failure"); return -1; }
        question->qnameOrig->c[0] = 0;
        AssignDomainName(question->qnameOrig, &question->qname);
        LogInfo("AppendSearchDomain: qnameOrig %##s", question->qnameOrig->c);
    }

    sd = uDNS_GetNextSearchDomain(m, question->InterfaceID, &question->SearchListIndex, !question->AppendLocalSearchDomains);
    // We use -1 to indicate that we have searched all the domains and should try the single label
    // query directly on the wire. uDNS_GetNextSearchDomain should never return a negative value
    if (question->SearchListIndex == -1)
    {
        LogMsg("AppendNewSearchDomain: ERROR!! uDNS_GetNextSearchDomain returned -1");
        return -1;
    }

    // Not a common case. Perhaps, we should try the next search domain if it exceeds ?
    if (sd && (DomainNameLength(question->qnameOrig) + DomainNameLength(sd)) > MAX_DOMAIN_NAME)
    {
        LogMsg("AppendNewSearchDomain: ERROR!! exceeding max domain length for %##s (%s) SearchDomain %##s length %d, Question name length %d", question->qnameOrig->c, DNSTypeName(question->qtype), sd->c, DomainNameLength(question->qnameOrig), DomainNameLength(sd));
        return -1;
    }

    // if there are no more search domains and we have already tried this question
    // without appending search domains, then we are done.
    if (!sd && !ApplySearchDomainsFirst(question))
    {
        LogInfo("AppnedNewSearchDomain: No more search domains for question with name %##s (%s), not trying anymore", question->qname.c, DNSTypeName(question->qtype));
        return -1;
    }

    // Stop the question before changing the name as negative cache entries could be pointing at this question.
    // Even if we don't change the question in the case of returning 0, the caller is going to restart the
    // question.
    err = mDNS_StopQuery(&mDNSStorage, question);
    if (err) { LogMsg("AppendNewSearchDomain: ERROR!! %##s %s mDNS_StopQuery: %d, while retrying with search domains", question->qname.c, DNSTypeName(question->qtype), (int)err); }

    AssignDomainName(&question->qname, question->qnameOrig);
    if (sd)
    {
        AppendDomainName(&question->qname, sd);
        LogInfo("AppnedNewSearchDomain: Returning question with name %##s, SearchListIndex %d", question->qname.c, question->SearchListIndex);
        return 1;
    }

    // Try the question as single label
    LogInfo("AppnedNewSearchDomain: No more search domains for question with name %##s (%s), trying one last time", question->qname.c, DNSTypeName(question->qtype));
    return 0;
}

#if APPLE_OSX_mDNSResponder

mDNSlocal mDNSBool DomainInSearchList(domainname *domain)
{
    const SearchListElem *s;
    for (s=SearchList; s; s=s->next)
        if (SameDomainName(&s->domain, domain)) return mDNStrue;
    return mDNSfalse;
}

// Workaround for networks using Microsoft Active Directory using "local" as a private internal
// top-level domain
mDNSlocal mStatus SendAdditionalQuery(DNSQuestion *q, request_state *request, mStatus err)
{
    extern domainname ActiveDirectoryPrimaryDomain;
    DNSQuestion **question2;
    #define VALID_MSAD_SRV_TRANSPORT(T) (SameDomainLabel((T)->c, (const mDNSu8 *)"\x4_tcp") || SameDomainLabel((T)->c, (const mDNSu8 *)"\x4_udp"))
    #define VALID_MSAD_SRV(Q) ((Q)->qtype == kDNSType_SRV && VALID_MSAD_SRV_TRANSPORT(SecondLabel(&(Q)->qname)))

    question2 = mDNSNULL;
    if (request->hdr.op == query_request)
        question2 = &request->u.queryrecord.q2;
    else if (request->hdr.op == addrinfo_request)
    {
        if (q->qtype == kDNSType_A)
            question2 = &request->u.addrinfo.q42;
        else if (q->qtype == kDNSType_AAAA)
            question2 = &request->u.addrinfo.q62;
    }
    if (!question2)
    {
        LogMsg("SendAdditionalQuery: question2 NULL for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
        return mStatus_BadParamErr;
    }

    // Sanity check: If we already sent an additonal query, we don't need to send one more.
    //
    // 1. When the application calls DNSServiceQueryRecord or DNSServiceGetAddrInfo with a .local name, this function
    // is called to see whether a unicast query should be sent or not.
    //
    // 2. As a result of appending search domains, the question may be end up with a .local suffix even though it
    // was not a .local name to start with. In that case, queryrecord_result_callback calls this function to
    // send the additional query.
    //
    // Thus, it should not be called more than once.
    if (*question2)
    {
        LogInfo("SendAdditionalQuery: question2 already sent for %##s (%s), no more q2", q->qname.c, DNSTypeName(q->qtype));
        return err;
    }

    if (!q->ForceMCast && SameDomainLabel(LastLabel(&q->qname), (const mDNSu8 *)&localdomain))
        if (q->qtype == kDNSType_A || q->qtype == kDNSType_AAAA || VALID_MSAD_SRV(q))
        {
            DNSQuestion *q2;
            int labels = CountLabels(&q->qname);
            q2 = mallocL("DNSQuestion", sizeof(DNSQuestion));
            if (!q2) FatalError("ERROR: SendAdditionalQuery malloc");
            *question2        = q2;
            *q2               = *q;
            q2->InterfaceID   = mDNSInterface_Unicast;
            q2->ExpectUnique  = mDNStrue;
            // Always set the QuestionContext to indicate that this question should be stopped
            // before freeing. Don't rely on "q".
            q2->QuestionContext = request;
            // If the query starts as a single label e.g., somehost, and we have search domains with .local,
            // queryrecord_result_callback calls this function when .local is appended to "somehost".
            // At that time, the name in "q" is pointing at somehost.local and its qnameOrig pointing at
            // "somehost". We need to copy that information so that when we retry with a different search
            // domain e.g., mycompany.local, we get "somehost.mycompany.local".
            if (q->qnameOrig)
            {
                (*question2)->qnameOrig =  mallocL("SendAdditionalQuery", DomainNameLength(q->qnameOrig));
                if (!(*question2)->qnameOrig) { LogMsg("SendAdditionalQuery: ERROR!!  malloc failure"); return mStatus_NoMemoryErr; }
                (*question2)->qnameOrig->c[0] = 0;
                AssignDomainName((*question2)->qnameOrig, q->qnameOrig);
                LogInfo("SendAdditionalQuery: qnameOrig %##s", (*question2)->qnameOrig->c);
            }
            // For names of the form "<one-or-more-labels>.bar.local." we always do a second unicast query in parallel.
            // For names of the form "<one-label>.local." it's less clear whether we should do a unicast query.
            // If the name being queried is exactly the same as the name in the DHCP "domain" option (e.g. the DHCP
            // "domain" is my-small-company.local, and the user types "my-small-company.local" into their web browser)
            // then that's a hint that it's worth doing a unicast query. Otherwise, we first check to see if the
            // site's DNS server claims there's an SOA record for "local", and if so, that's also a hint that queries
            // for names in the "local" domain will be safely answered privately before they hit the root name servers.
            // Note that in the "my-small-company.local" example above there will typically be an SOA record for
            // "my-small-company.local" but *not* for "local", which is why the "local SOA" check would fail in that case.
            // We need to check against both ActiveDirectoryPrimaryDomain and SearchList. If it matches against either
            // of those, we don't want do the SOA check for the local
            if (labels == 2 && !SameDomainName(&q->qname, &ActiveDirectoryPrimaryDomain) && !DomainInSearchList(&q->qname))
            {
                AssignDomainName(&q2->qname, &localdomain);
                q2->qtype          = kDNSType_SOA;
                q2->LongLived      = mDNSfalse;
                q2->ForceMCast     = mDNSfalse;
                q2->ReturnIntermed = mDNStrue;
                // Don't append search domains for the .local SOA query
                q2->AppendSearchDomains = 0;
                q2->AppendLocalSearchDomains = 0;
                q2->RetryWithSearchDomains = mDNSfalse;
                q2->SearchListIndex = 0;
                q2->TimeoutQuestion = 0;
            }
            LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) unicast", request->sd, q2->qname.c, DNSTypeName(q2->qtype));
            err = mDNS_StartQuery(&mDNSStorage, q2);
            if (err) LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q2->qname.c, DNSTypeName(q2->qtype), (int)err);
        }
    return(err);
}
#endif // APPLE_OSX_mDNSResponder

// This function tries to append a search domain if valid and possible. If so, returns true.
mDNSlocal mDNSBool RetryQuestionWithSearchDomains(mDNS *const m, DNSQuestion *question, request_state *req)
{
    int result;
    // RetryWithSearchDomains tells the core to call us back so that we can retry with search domains if there is no
    // answer in the cache or /etc/hosts. In the first call back from the core, we clear RetryWithSearchDomains so
    // that we don't get called back repeatedly. If we got an answer from the cache or /etc/hosts, we don't touch
    // RetryWithSearchDomains which may or may not be set.
    //
    // If we get e.g., NXDOMAIN and the query is neither suppressed nor exhausted the domain search list and
    // is a valid question for appending search domains, retry by appending domains

    if (!question->SuppressQuery && question->SearchListIndex != -1 && question->AppendSearchDomains)
    {
        question->RetryWithSearchDomains = 0;
        result = AppendNewSearchDomain(m, question);
        // As long as the result is either zero or 1, we retry the question. If we exahaust the search
        // domains (result is zero) we try the original query (as it was before appending the search
        // domains) as such on the wire as a last resort if we have not tried them before. For queries
        // with more than one label, we have already tried them before appending search domains and
        // hence don't retry again
        if (result != -1)
        {
            mStatus err;
            err = mDNS_StartQuery(m, question);
            if (!err)
            {
                LogOperation("%3d: RetryQuestionWithSearchDomains(%##s, %s), retrying after appending search domain", req->sd, question->qname.c, DNSTypeName(question->qtype));
                // If the result was zero, it meant that there are no search domains and we just retried the question
                // as a single label and we should not retry with search domains anymore.
                if (!result) question->SearchListIndex = -1;
                return mDNStrue;
            }
            else
            {
                LogMsg("%3d: ERROR: RetryQuestionWithSearchDomains %##s %s mDNS_StartQuery: %d, while retrying with search domains", req->sd, question->qname.c, DNSTypeName(question->qtype), (int)err);
                // We have already stopped the query and could not restart. Reset the appropriate pointers
                // so that we don't call stop again when the question terminates
                question->QuestionContext = mDNSNULL;
            }
        }
    }
    else
    {
        LogInfo("%3d: RetryQuestionWithSearchDomains: Not appending search domains - SuppressQuery %d, SearchListIndex %d, AppendSearchDomains %d", req->sd, question->SuppressQuery, question->SearchListIndex, question->AppendSearchDomains);
    }
    return mDNSfalse;
}

mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
    char name[MAX_ESCAPED_DOMAIN_NAME];
    request_state *req = question->QuestionContext;
    reply_state *rep;
    char *data;
    size_t len;
    DNSServiceErrorType error = kDNSServiceErr_NoError;
    DNSQuestion *q = mDNSNULL;

#if APPLE_OSX_mDNSResponder
    {
        // Sanity check: QuestionContext is set to NULL after we stop the question and hence we should not
        // get any callbacks from the core after this.
        if (!req)
        {
            LogMsg("queryrecord_result_callback: ERROR!! QuestionContext NULL for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
            return;
        }
        if (req->hdr.op == query_request && question == req->u.queryrecord.q2)
            q = &req->u.queryrecord.q;
        else if (req->hdr.op == addrinfo_request && question == req->u.addrinfo.q42)
            q = &req->u.addrinfo.q4;
        else if (req->hdr.op == addrinfo_request && question == req->u.addrinfo.q62)
            q = &req->u.addrinfo.q6;

        if (q && question->qtype != q->qtype && !SameDomainName(&question->qname, &q->qname))
        {
            mStatus err;
            domainname *orig = question->qnameOrig;

            LogInfo("queryrecord_result_callback: Stopping q2 local %##s", question->qname.c);
            mDNS_StopQuery(m, question);
            question->QuestionContext = mDNSNULL;

            // We got a negative response for the SOA record indicating that .local does not exist.
            // But we might have other search domains (that does not end in .local) that can be
            // appended to this question. In that case, we want to retry the question. Otherwise,
            // we don't want to try this question as unicast.
            if (answer->RecordType == kDNSRecordTypePacketNegative && !q->AppendSearchDomains)
            {
                LogInfo("queryrecord_result_callback: question %##s AppendSearchDomains zero", q->qname.c);
                return;
            }

            // If we got a non-negative answer for our "local SOA" test query, start an additional parallel unicast query
            //
            // Note: When we copy the original question, we copy everything including the AppendSearchDomains,
            // RetryWithSearchDomains except for qnameOrig which can be non-NULL if the original question is
            // e.g., somehost and then we appended e.g., ".local" and retried that question. See comment in
            // SendAdditionalQuery as to how qnameOrig gets initialized.
            *question              = *q;
            question->InterfaceID  = mDNSInterface_Unicast;
            question->ExpectUnique = mDNStrue;
            question->qnameOrig    = orig;

            LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) unicast, context %p", req->sd, question->qname.c, DNSTypeName(question->qtype), question->QuestionContext);

            // If the original question timed out, its QuestionContext would already be set to NULL and that's what we copied above.
            // Hence, we need to set it explicitly here.
            question->QuestionContext = req;
            err = mDNS_StartQuery(m, question);
            if (err) LogMsg("%3d: ERROR: queryrecord_result_callback %##s %s mDNS_StartQuery: %d", req->sd, question->qname.c, DNSTypeName(question->qtype), (int)err);

            // If we got a positive response to local SOA, then try the .local question as unicast
            if (answer->RecordType != kDNSRecordTypePacketNegative) return;

            // Fall through and get the next search domain. The question is pointing at .local
            // and we don't want to try that. Try the next search domain. Don't try with local
            // search domains for the unicast question anymore.
            //
            // Note: we started the question above which will be stopped immediately (never sent on the wire)
            // before we pick the next search domain below. RetryQuestionWithSearchDomains assumes that the
            // question has already started.
            question->AppendLocalSearchDomains = 0;
        }

        if (q && AddRecord && (question->InterfaceID == mDNSInterface_Unicast) && !answer->rdlength)
        {
            // If we get a negative response to the unicast query that we sent above, retry after appending search domains
            // Note: We could have appended search domains below (where do it for regular unicast questions) instead of doing it here.
            // As we ignore negative unicast answers below, we would never reach the code where the search domains are appended.
            // To keep things simple, we handle unicast ".local" separately here.
            LogInfo("queryrecord_result_callback: Retrying .local question %##s (%s) as unicast after appending search domains", question->qname.c, DNSTypeName(question->qtype));
            if (RetryQuestionWithSearchDomains(m, question, req))
                return;
            if (question->AppendSearchDomains && !question->AppendLocalSearchDomains && IsLocalDomain(&question->qname))
            {
                // If "local" is the last search domain, we need to stop the question so that we don't send the "local"
                // question on the wire as we got a negative response for the local SOA. But, we can't stop the question
                // yet as we may have to timeout the question (done by the "core") for which we need to leave the question
                // in the list. We leave it disabled so that it does not hit the wire.
                LogInfo("queryrecord_result_callback: Disabling .local question %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
                question->ThisQInterval = 0;
            }
        }
        // If we are here it means that either "question" is not "q2" OR we got a positive response for "q2" OR we have no more search
        // domains to append for "q2". In all cases, fall through and deliver the response
    }
#endif // APPLE_OSX_mDNSResponder

    if (answer->RecordType == kDNSRecordTypePacketNegative)
    {
        // If this question needs to be timed out and we have reached the stop time, mark
        // the error as timeout. It is possible that we might get a negative response from an
        // external DNS server at the same time when this question reaches its stop time. We
        // can't tell the difference as there is no indication in the callback. This should
        // be okay as we will be timing out this query anyway.
        mDNS_Lock(m);
        if (question->TimeoutQuestion)
        {
            if ((m->timenow - question->StopTime) >= 0)
            {
                LogInfo("queryrecord_result_callback:Question %##s (%s) timing out, InterfaceID %p", question->qname.c, DNSTypeName(question->qtype), question->InterfaceID);
                error = kDNSServiceErr_Timeout;
            }
        }
        mDNS_Unlock(m);
        // When we're doing parallel unicast and multicast queries for dot-local names (for supporting Microsoft
        // Active Directory sites) we need to ignore negative unicast answers. Otherwise we'll generate negative
        // answers for just about every single multicast name we ever look up, since the Microsoft Active Directory
        // server is going to assert that pretty much every single multicast name doesn't exist.
        //
        // If we are timing out this query, we need to deliver the negative answer to the application
        if (error != kDNSServiceErr_Timeout)
        {
            if (!answer->InterfaceID && IsLocalDomain(answer->name))
            {
                mDNSu16 qtype;
                // Sanity check: "q" will be set only if "question" is the .local unicast query.
                if (!q)
                {
                    LogMsg("queryrecord_result_callback: ERROR!! answering multicast question with unicast cache record");
                    return;
                }
                // Deliver negative response for A/AAAA if there was a positive response for AAAA/A respectively.
                if (question->qtype != kDNSType_A && question->qtype != kDNSType_AAAA)
                {
                    LogInfo("queryrecord_result_callback:Question %##s (%s) not answering local question with negative unicast response", question->qname.c, DNSTypeName(question->qtype));
                    return;
                }
                qtype = (question->qtype == kDNSType_A ? kDNSType_AAAA : kDNSType_A);
                if (!mDNS_CheckForCacheRecord(m, question, qtype))
                {
                    LogInfo("queryrecord_result_callback:Question %##s (%s) not answering local question with negative unicast response (can't find positive record)", question->qname.c, DNSTypeName(question->qtype));
                    return;
                }
                LogInfo("queryrecord_result_callback:Question %##s (%s) answering local with negative unicast response (found positive record)", question->qname.c, DNSTypeName(question->qtype));
            }
            error = kDNSServiceErr_NoSuchRecord;
        }
        AddRecord = mDNStrue;
    }
    // If we get a negative answer, try appending search domains. Don't append search domains
    // - if we are timing out this question
    // - if the negative response was received as a result of a multicast query
    // - if this is an additional query (q2), we already appended search domains above (indicated by "!q" below)
    if (error != kDNSServiceErr_Timeout)
    {
        if (!q && !answer->InterfaceID && !answer->rdlength && AddRecord)
        {
            // If the original question did not end in .local, we did not send an SOA query
            // to figure out whether we should send an additional unicast query or not. If we just
            // appended .local, we need to see if we need to send an additional query. This should
            // normally happen just once because after we append .local, we ignore all negative
            // responses for .local above.
            LogInfo("queryrecord_result_callback: Retrying question %##s (%s) after appending search domains", question->qname.c, DNSTypeName(question->qtype));
            if (RetryQuestionWithSearchDomains(m, question, req))
            {
                // Note: We need to call SendAdditionalQuery every time after appending a search domain as .local could
                // be anywhere in the search domain list.
#if APPLE_OSX_mDNSResponder
                mStatus err = mStatus_NoError;
                err = SendAdditionalQuery(question, req, err);
                if (err) LogMsg("queryrecord_result_callback: Sending .local SOA query failed, after appending domains");
#endif // APPLE_OSX_mDNSResponder
                return;
            }
        }
    }

    ConvertDomainNameToCString(answer->name, name);

    LogOperation("%3d: %s(%##s, %s) %s %s", req->sd,
                 req->hdr.op == query_request ? "DNSServiceQueryRecord" : "DNSServiceGetAddrInfo",
                 question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));

    len = sizeof(DNSServiceFlags);  // calculate reply data length
    len += sizeof(mDNSu32);     // interface index
    len += sizeof(DNSServiceErrorType);
    len += strlen(name) + 1;
    len += 3 * sizeof(mDNSu16); // type, class, rdlen
    len += answer->rdlength;
    len += sizeof(mDNSu32);     // TTL

    rep = create_reply(req->hdr.op == query_request ? query_reply_op : addrinfo_reply_op, len, req);

    rep->rhdr->flags = dnssd_htonl(AddRecord ? kDNSServiceFlagsAdd : 0);
    // Call mDNSPlatformInterfaceIndexfromInterfaceID, but suppressNetworkChange (last argument). Otherwise, if the
    // InterfaceID is not valid, then it simulates a "NetworkChanged" which in turn makes questions
    // to be stopped and started including  *this* one. Normally the InterfaceID is valid. But when we
    // are using the /etc/hosts entries to answer a question, the InterfaceID may not be known to the
    // mDNS core . Eventually, we should remove the calls to "NetworkChanged" in
    // mDNSPlatformInterfaceIndexfromInterfaceID when it can't find InterfaceID as ResourceRecords
    // should not have existed to answer this question if the corresponding interface is not valid.
    rep->rhdr->ifi   = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNStrue));
    rep->rhdr->error = dnssd_htonl(error);

    data = (char *)&rep->rhdr[1];

    put_string(name,             &data);
    put_uint16(answer->rrtype,   &data);
    put_uint16(answer->rrclass,  &data);
    put_uint16(answer->rdlength, &data);
    // We need to use putRData here instead of the crude put_rdata function, because the crude put_rdata
    // function just does a blind memory copy without regard to structures that may have holes in them.
    if (answer->rdlength)
        if (!putRData(mDNSNULL, (mDNSu8 *)data, (mDNSu8 *)rep->rhdr + len, answer))
            LogMsg("queryrecord_result_callback putRData failed %d", (mDNSu8 *)rep->rhdr + len - (mDNSu8 *)data);
    data += answer->rdlength;
    put_uint32(AddRecord ? answer->rroriginalttl : 0, &data);

    append_reply(req, rep);
    // Stop the question, if we just timed out
    if (error == kDNSServiceErr_Timeout)
    {
        mDNS_StopQuery(m, question);
        // Reset the pointers so that we don't call stop on termination
        question->QuestionContext = mDNSNULL;
    }
#if APPLE_OSX_mDNSResponder
#if !NO_WCF
    CHECK_WCF_FUNCTION(WCFIsServerRunning)
    {
        struct xucred x;
        socklen_t xucredlen = sizeof(x);

        if (WCFIsServerRunning((WCFConnection *)m->WCF) && answer->rdlength != 0)
        {
            if (getsockopt(req->sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 &&
                (x.cr_version == XUCRED_VERSION))
            {
                struct sockaddr_storage addr;
                const RDataBody2 *const rdb = (RDataBody2 *)answer->rdata->u.data;
                addr.ss_len = 0;
                if (answer->rrtype == kDNSType_A || answer->rrtype == kDNSType_AAAA)
                {
                    if (answer->rrtype == kDNSType_A)
                    {
                        struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
                        sin->sin_port = 0;
                        if (!putRData(mDNSNULL, (mDNSu8 *)&sin->sin_addr, (mDNSu8 *)(&sin->sin_addr + sizeof(rdb->ipv4)), answer))
                            LogMsg("queryrecord_result_callback: WCF AF_INET putRData failed");
                        else
                        {
                            addr.ss_len = sizeof (struct sockaddr_in);
                            addr.ss_family = AF_INET;
                        }
                    }
                    else if (answer->rrtype == kDNSType_AAAA)
                    {
                        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
                        sin6->sin6_port = 0;
                        if (!putRData(mDNSNULL, (mDNSu8 *)&sin6->sin6_addr, (mDNSu8 *)(&sin6->sin6_addr + sizeof(rdb->ipv6)), answer))
                            LogMsg("queryrecord_result_callback: WCF AF_INET6 putRData failed");
                        else
                        {
                            addr.ss_len = sizeof (struct sockaddr_in6);
                            addr.ss_family = AF_INET6;
                        }
                    }
                    if (addr.ss_len)
                    {
                        debugf("queryrecord_result_callback: Name %s, uid %u, addr length %d", name, x.cr_uid, addr.ss_len);
                        CHECK_WCF_FUNCTION((WCFConnection *)WCFNameResolvesToAddr)
                        {
                            WCFNameResolvesToAddr(m->WCF, name, (struct sockaddr *)&addr, x.cr_uid);
                        }
                    }
                }
                else if (answer->rrtype == kDNSType_CNAME)
                {
                    domainname cname;
                    char cname_cstr[MAX_ESCAPED_DOMAIN_NAME];
                    if (!putRData(mDNSNULL, cname.c, (mDNSu8 *)(cname.c + MAX_DOMAIN_NAME), answer))
                        LogMsg("queryrecord_result_callback: WCF CNAME putRData failed");
                    else
                    {
                        ConvertDomainNameToCString(&cname, cname_cstr);
                        CHECK_WCF_FUNCTION((WCFConnection *)WCFNameResolvesToAddr)
                        {
                            WCFNameResolvesToName(m->WCF, name, cname_cstr, x.cr_uid);
                        }
                    }
                }
            }
            else my_perror("queryrecord_result_callback: ERROR: getsockopt LOCAL_PEERCRED");
        }
    }
#endif
#endif
}

mDNSlocal void queryrecord_termination_callback(request_state *request)
{
    LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) STOP PID[%d](%s)",
		request->sd, request->u.queryrecord.q.qname.c, DNSTypeName(request->u.queryrecord.q.qtype), get_peer_pid(request->sd, pid_name), pid_name);
    if (request->u.queryrecord.q.QuestionContext)
    {
        mDNS_StopQuery(&mDNSStorage, &request->u.queryrecord.q);  // no need to error check
        request->u.queryrecord.q.QuestionContext = mDNSNULL;
    }
    else
    {
        DNSQuestion *question = &request->u.queryrecord.q;
        LogInfo("queryrecord_termination_callback: question %##s (%s) already stopped, InterfaceID %p", question->qname.c, DNSTypeName(question->qtype), question->InterfaceID);
    }

    if (request->u.queryrecord.q.qnameOrig)
    {
        freeL("QueryTermination", request->u.queryrecord.q.qnameOrig);
        request->u.queryrecord.q.qnameOrig = mDNSNULL;
    }

    if (callExternalHelpers(request->u.queryrecord.q.InterfaceID, &request->u.queryrecord.q.qname, request->flags))
    {
        LogInfo("queryrecord_termination_callback: calling external_stop_browsing_for_service()");
        external_stop_browsing_for_service(request->u.queryrecord.q.InterfaceID, &request->u.queryrecord.q.qname, request->u.queryrecord.q.qtype, request->flags);
    }
    if (request->u.queryrecord.q2)
    {
        if (request->u.queryrecord.q2->QuestionContext)
        {
            LogInfo("queryrecord_termination_callback: Stopping q2 %##s", request->u.queryrecord.q2->qname.c);
            mDNS_StopQuery(&mDNSStorage, request->u.queryrecord.q2);
        }
        else
        {
            DNSQuestion *question = request->u.queryrecord.q2;
            LogInfo("queryrecord_termination_callback: q2 %##s (%s) already stopped, InterfaceID %p", question->qname.c, DNSTypeName(question->qtype), question->InterfaceID);
        }
        if (request->u.queryrecord.q2->qnameOrig)
        {
            LogInfo("queryrecord_termination_callback: freeing q2 qnameOrig %##s", request->u.queryrecord.q2->qnameOrig->c);
            freeL("QueryTermination q2", request->u.queryrecord.q2->qnameOrig);
            request->u.queryrecord.q2->qnameOrig = mDNSNULL;
        }
        freeL("queryrecord Q2", request->u.queryrecord.q2);
        request->u.queryrecord.q2 = mDNSNULL;
    }
}

mDNSlocal mStatus handle_queryrecord_request(request_state *request)
{
    DNSQuestion *const q = &request->u.queryrecord.q;
    char name[256];
    mDNSu16 rrtype, rrclass;
    mStatus err;

    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);

    if (get_string(&request->msgptr, request->msgend, name, 256) < 0) return(mStatus_BadParamErr);
    rrtype  = get_uint16(&request->msgptr, request->msgend);
    rrclass = get_uint16(&request->msgptr, request->msgend);

    if (!request->msgptr)
    { LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    request->flags = flags;
    mDNSPlatformMemZero(&request->u.queryrecord, sizeof(request->u.queryrecord));

    q->InterfaceID      = InterfaceID;
    q->flags            = flags;
    q->Target           = zeroAddr;
    if (!MakeDomainNameFromDNSNameString(&q->qname, name)) return(mStatus_BadParamErr);
#if 0
    if (!AuthorizedDomain(request, &q->qname, AutoBrowseDomains)) return (mStatus_NoError);
#endif
    q->qtype            = rrtype;
    q->qclass           = rrclass;
    q->LongLived        = (flags & kDNSServiceFlagsLongLivedQuery     ) != 0;
    q->ExpectUnique     = mDNSfalse;
    q->ForceMCast       = (flags & kDNSServiceFlagsForceMulticast     ) != 0;
    q->ReturnIntermed   = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
    q->SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable   ) != 0;
    q->TimeoutQuestion  = (flags & kDNSServiceFlagsTimeout            ) != 0;
    q->WakeOnResolve    = 0;
    q->UseBrackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
    q->ValidationRequired = 0;
    q->ValidatingResponse = 0;
    q->QuestionCallback = queryrecord_result_callback;
    q->QuestionContext  = request;
    q->SearchListIndex  = 0;

    // Don't append search domains for fully qualified domain names including queries
    // such as e.g., "abc." that has only one label. We convert all names to FQDNs as internally
    // we only deal with FQDNs. Hence, we cannot look at qname to figure out whether we should
    // append search domains or not.  So, we record that information in AppendSearchDomains.
    //
    // We append search domains only for queries that are a single label. If overriden using
    // command line argument "AlwaysAppendSearchDomains", then we do it for any query which
    // is not fully qualified.

    if ((rrtype == kDNSType_A || rrtype == kDNSType_AAAA) && name[strlen(name) - 1] != '.' &&
        (AlwaysAppendSearchDomains || CountLabels(&q->qname) == 1))
    {
        q->AppendSearchDomains = 1;
        q->AppendLocalSearchDomains = 1;
    }
    else
    {
        q->AppendSearchDomains = 0;
        q->AppendLocalSearchDomains = 0;
    }

    // For single label queries that are not fully qualified, look at /etc/hosts, cache and try
    // search domains before trying them on the wire as a single label query. RetryWithSearchDomains
    // tell the core to call back into the UDS layer if there is no valid response in /etc/hosts or
    // the cache
    q->RetryWithSearchDomains = ApplySearchDomainsFirst(q) ? 1 : 0;
    q->qnameOrig        = mDNSNULL;

    LogOperation("%3d: DNSServiceQueryRecord(%X, %d, %##s, %s) START PID[%d](%s)", 
		request->sd, flags, interfaceIndex, q->qname.c, DNSTypeName(q->qtype), get_peer_pid(request->sd, pid_name), pid_name);
    err = mDNS_StartQuery(&mDNSStorage, q);
    if (err) LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q->qname.c, DNSTypeName(q->qtype), (int)err);
    else
    {
        request->terminate = queryrecord_termination_callback;
        if (callExternalHelpers(q->InterfaceID, &q->qname, flags))
        {
            LogInfo("handle_queryrecord_request: calling external_start_browsing_for_service()");
            external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, flags);
        }
    }

#if APPLE_OSX_mDNSResponder
    err = SendAdditionalQuery(q, request, err);
#endif // APPLE_OSX_mDNSResponder

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceEnumerateDomains
#endif

mDNSlocal reply_state *format_enumeration_reply(request_state *request,
                                                const char *domain, DNSServiceFlags flags, mDNSu32 ifi, DNSServiceErrorType err)
{
    size_t len;
    reply_state *reply;
    char *data;

    len = sizeof(DNSServiceFlags);
    len += sizeof(mDNSu32);
    len += sizeof(DNSServiceErrorType);
    len += strlen(domain) + 1;

    reply = create_reply(enumeration_reply_op, len, request);
    reply->rhdr->flags = dnssd_htonl(flags);
    reply->rhdr->ifi   = dnssd_htonl(ifi);
    reply->rhdr->error = dnssd_htonl(err);
    data = (char *)&reply->rhdr[1];
    put_string(domain, &data);
    return reply;
}

mDNSlocal void enum_termination_callback(request_state *request)
{
    mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
    mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_default);
}

mDNSlocal void enum_result_callback(mDNS *const m,
                                    DNSQuestion *const question, const ResourceRecord *const answer, QC_result AddRecord)
{
    char domain[MAX_ESCAPED_DOMAIN_NAME];
    request_state *request = question->QuestionContext;
    DNSServiceFlags flags = 0;
    reply_state *reply;
    (void)m; // Unused

    if (answer->rrtype != kDNSType_PTR) return;

#if 0
    if (!AuthorizedDomain(request, &answer->rdata->u.name, request->u.enumeration.flags ? AutoRegistrationDomains : AutoBrowseDomains)) return;
#endif

    // We only return add/remove events for the browse and registration lists
    // For the default browse and registration answers, we only give an "ADD" event
    if (question == &request->u.enumeration.q_default && !AddRecord) return;

    if (AddRecord)
    {
        flags |= kDNSServiceFlagsAdd;
        if (question == &request->u.enumeration.q_default) flags |= kDNSServiceFlagsDefault;
    }

    ConvertDomainNameToCString(&answer->rdata->u.name, domain);
    // Note that we do NOT propagate specific interface indexes to the client - for example, a domain we learn from
    // a machine's system preferences may be discovered on the LocalOnly interface, but should be browsed on the
    // network, so we just pass kDNSServiceInterfaceIndexAny
    reply = format_enumeration_reply(request, domain, flags, kDNSServiceInterfaceIndexAny, kDNSServiceErr_NoError);
    if (!reply) { LogMsg("ERROR: enum_result_callback, format_enumeration_reply"); return; }

    LogOperation("%3d: DNSServiceEnumerateDomains(%#2s) RESULT %s: %s", request->sd, question->qname.c, AddRecord ? "Add" : "Rmv", domain);

    append_reply(request, reply);
}

mDNSlocal mStatus handle_enum_request(request_state *request)
{
    mStatus err;
    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
    DNSServiceFlags reg = flags & kDNSServiceFlagsRegistrationDomains;
    mDNS_DomainType t_all     = reg ? mDNS_DomainTypeRegistration        : mDNS_DomainTypeBrowse;
    mDNS_DomainType t_default = reg ? mDNS_DomainTypeRegistrationDefault : mDNS_DomainTypeBrowseDefault;
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);

    if (!request->msgptr)
    { LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    // allocate context structures
    uDNS_SetupSearchDomains(&mDNSStorage, UDNS_START_WAB_QUERY);

#if 0
    // mark which kind of enumeration we're doing so we can (de)authorize certain domains
    request->u.enumeration.flags = reg;
#endif

    // enumeration requires multiple questions, so we must link all the context pointers so that
    // necessary context can be reached from the callbacks
    request->u.enumeration.q_all.QuestionContext = request;
    request->u.enumeration.q_default.QuestionContext = request;

    // if the caller hasn't specified an explicit interface, we use local-only to get the system-wide list.
    if (!InterfaceID) InterfaceID = mDNSInterface_LocalOnly;

    // make the calls
    LogOperation("%3d: DNSServiceEnumerateDomains(%X=%s)", request->sd, flags,
                 (flags & kDNSServiceFlagsBrowseDomains      ) ? "kDNSServiceFlagsBrowseDomains" :
                 (flags & kDNSServiceFlagsRegistrationDomains) ? "kDNSServiceFlagsRegistrationDomains" : "<<Unknown>>");
    err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_all, t_all, NULL, InterfaceID, enum_result_callback, request);
    if (!err)
    {
        err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_default, t_default, NULL, InterfaceID, enum_result_callback, request);
        if (err) mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
        else request->terminate = enum_termination_callback;
    }

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceReconfirmRecord & Misc
#endif

mDNSlocal mStatus handle_reconfirm_request(request_state *request)
{
    mStatus status = mStatus_BadParamErr;
    AuthRecord *rr = read_rr_from_ipc_msg(request, 0, 0);
    if (rr)
    {
        status = mDNS_ReconfirmByValue(&mDNSStorage, &rr->resrec);
        LogOperation(
            (status == mStatus_NoError) ?
            "%3d: DNSServiceReconfirmRecord(%s) interface %d initiated" :
            "%3d: DNSServiceReconfirmRecord(%s) interface %d failed: %d",
            request->sd, RRDisplayString(&mDNSStorage, &rr->resrec),
            mDNSPlatformInterfaceIndexfromInterfaceID(&mDNSStorage, rr->resrec.InterfaceID, mDNSfalse), status);
        freeL("AuthRecord/handle_reconfirm_request", rr);
    }
    return(status);
}

#if APPLE_OSX_mDNSResponder

mDNSlocal mStatus handle_release_request(request_state *request)
{
    mStatus err = 0;
    char name[256], regtype[MAX_ESCAPED_DOMAIN_NAME], domain[MAX_ESCAPED_DOMAIN_NAME];
    domainname instance;

    // extract the data from the message
    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);

    if (get_string(&request->msgptr, request->msgend, name, 256) < 0 ||
        get_string(&request->msgptr, request->msgend, regtype, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
        get_string(&request->msgptr, request->msgend, domain, MAX_ESCAPED_DOMAIN_NAME) < 0)
    {
        LogMsg("ERROR: handle_release_request - Couldn't read name/regtype/domain");
        return(mStatus_BadParamErr);
    }

    if (!request->msgptr)
    {
        LogMsg("%3d: PeerConnectionRelease(unreadable parameters)", request->sd);
        return(mStatus_BadParamErr);
    }

    if (build_domainname_from_strings(&instance, name, regtype, domain) < 0)
    {
        LogMsg("ERROR: handle_release_request bad “%s” “%s” “%s”", name, regtype, domain);
        return(mStatus_BadParamErr);
    }

    LogOperation("%3d: PeerConnectionRelease(%X %##s) START PID[%d](%s)",
        request->sd, flags, instance.c, get_peer_pid(request->sd, pid_name), pid_name);
    
    external_connection_release(&instance);
    return(err);
}

#else   // APPLE_OSX_mDNSResponder

mDNSlocal mStatus handle_release_request(request_state *request)
{
    (void) request; 
    return mStatus_UnsupportedErr;
}

#endif  // APPLE_OSX_mDNSResponder

mDNSlocal mStatus handle_setdomain_request(request_state *request)
{
    char domainstr[MAX_ESCAPED_DOMAIN_NAME];
    domainname domain;
    DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
    (void)flags; // Unused
    if (get_string(&request->msgptr, request->msgend, domainstr, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
        !MakeDomainNameFromDNSNameString(&domain, domainstr))
    { LogMsg("%3d: DNSServiceSetDefaultDomainForUser(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    LogOperation("%3d: DNSServiceSetDefaultDomainForUser(%##s)", request->sd, domain.c);
    return(mStatus_NoError);
}

typedef packedstruct
{
    mStatus err;
    mDNSu32 len;
    mDNSu32 vers;
} DaemonVersionReply;

mDNSlocal void handle_getproperty_request(request_state *request)
{
    const mStatus BadParamErr = dnssd_htonl((mDNSu32)mStatus_BadParamErr);
    char prop[256];
    if (get_string(&request->msgptr, request->msgend, prop, sizeof(prop)) >= 0)
    {
        LogOperation("%3d: DNSServiceGetProperty(%s)", request->sd, prop);
        if (!strcmp(prop, kDNSServiceProperty_DaemonVersion))
        {
            DaemonVersionReply x = { 0, dnssd_htonl(4), dnssd_htonl(_DNS_SD_H) };
            send_all(request->sd, (const char *)&x, sizeof(x));
            return;
        }
    }

    // If we didn't recogize the requested property name, return BadParamErr
    send_all(request->sd, (const char *)&BadParamErr, sizeof(BadParamErr));
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceNATPortMappingCreate
#endif

#define DNSServiceProtocol(X) ((X) == NATOp_AddrRequest ? 0 : (X) == NATOp_MapUDP ? kDNSServiceProtocol_UDP : kDNSServiceProtocol_TCP)

mDNSlocal void port_mapping_termination_callback(request_state *request)
{
    LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) STOP PID[%d](%s)", request->sd,
                 DNSServiceProtocol(request->u.pm.NATinfo.Protocol),
                 mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease, 
		 get_peer_pid(request->sd, pid_name), pid_name);
    mDNS_StopNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
}

// Called via function pointer when we get a NAT-PMP address request or port mapping response
mDNSlocal void port_mapping_create_request_callback(mDNS *m, NATTraversalInfo *n)
{
    request_state *request = (request_state *)n->clientContext;
    reply_state *rep;
    int replyLen;
    char *data;

    if (!request) { LogMsg("port_mapping_create_request_callback called with unknown request_state object"); return; }

    // calculate reply data length
    replyLen = sizeof(DNSServiceFlags);
    replyLen += 3 * sizeof(mDNSu32);  // if index + addr + ttl
    replyLen += sizeof(DNSServiceErrorType);
    replyLen += 2 * sizeof(mDNSu16);  // Internal Port + External Port
    replyLen += sizeof(mDNSu8);       // protocol

    rep = create_reply(port_mapping_reply_op, replyLen, request);

    rep->rhdr->flags = dnssd_htonl(0);
    rep->rhdr->ifi   = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, n->InterfaceID, mDNSfalse));
    rep->rhdr->error = dnssd_htonl(n->Result);

    data = (char *)&rep->rhdr[1];

    *data++ = request->u.pm.NATinfo.ExternalAddress.b[0];
    *data++ = request->u.pm.NATinfo.ExternalAddress.b[1];
    *data++ = request->u.pm.NATinfo.ExternalAddress.b[2];
    *data++ = request->u.pm.NATinfo.ExternalAddress.b[3];
    *data++ = DNSServiceProtocol(request->u.pm.NATinfo.Protocol);
    *data++ = request->u.pm.NATinfo.IntPort.b[0];
    *data++ = request->u.pm.NATinfo.IntPort.b[1];
    *data++ = request->u.pm.NATinfo.ExternalPort.b[0];
    *data++ = request->u.pm.NATinfo.ExternalPort.b[1];
    put_uint32(request->u.pm.NATinfo.Lifetime, &data);

    LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) RESULT %.4a:%u TTL %u", request->sd,
                 DNSServiceProtocol(request->u.pm.NATinfo.Protocol),
                 mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
                 &request->u.pm.NATinfo.ExternalAddress, mDNSVal16(request->u.pm.NATinfo.ExternalPort), request->u.pm.NATinfo.Lifetime);

    append_reply(request, rep);
}

mDNSlocal mStatus handle_port_mapping_request(request_state *request)
{
    mDNSu32 ttl = 0;
    mStatus err = mStatus_NoError;

    DNSServiceFlags flags          = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
    mDNSInterfaceID InterfaceID    = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    mDNSu8 protocol       = (mDNSu8)get_uint32(&request->msgptr, request->msgend);
    (void)flags; // Unused
    if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);
    if (request->msgptr + 8 > request->msgend) request->msgptr = NULL;
    else
    {
        request->u.pm.NATinfo.IntPort.b[0] = *request->msgptr++;
        request->u.pm.NATinfo.IntPort.b[1] = *request->msgptr++;
        request->u.pm.ReqExt.b[0]          = *request->msgptr++;
        request->u.pm.ReqExt.b[1]          = *request->msgptr++;
        ttl = get_uint32(&request->msgptr, request->msgend);
    }

    if (!request->msgptr)
    { LogMsg("%3d: DNSServiceNATPortMappingCreate(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    if (protocol == 0)  // If protocol == 0 (i.e. just request public address) then IntPort, ExtPort, ttl must be zero too
    {
        if (!mDNSIPPortIsZero(request->u.pm.NATinfo.IntPort) || !mDNSIPPortIsZero(request->u.pm.ReqExt) || ttl) return(mStatus_BadParamErr);
    }
    else
    {
        if (mDNSIPPortIsZero(request->u.pm.NATinfo.IntPort)) return(mStatus_BadParamErr);
        if (!(protocol & (kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP))) return(mStatus_BadParamErr);
    }

    request->u.pm.NATinfo.Protocol       = !protocol ? NATOp_AddrRequest : (protocol == kDNSServiceProtocol_UDP) ? NATOp_MapUDP : NATOp_MapTCP;
    //       u.pm.NATinfo.IntPort        = already set above
    request->u.pm.NATinfo.RequestedPort  = request->u.pm.ReqExt;
    request->u.pm.NATinfo.NATLease       = ttl;
    request->u.pm.NATinfo.clientCallback = port_mapping_create_request_callback;
    request->u.pm.NATinfo.clientContext  = request;

    LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) START PID[%d](%s)", request->sd,
                 protocol, mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease, 
		 get_peer_pid(request->sd, pid_name), pid_name);
    err = mDNS_StartNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
    if (err) LogMsg("ERROR: mDNS_StartNATOperation: %d", (int)err);
    else request->terminate = port_mapping_termination_callback;

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - DNSServiceGetAddrInfo
#endif

mDNSlocal void addrinfo_termination_callback(request_state *request)
{
    LogOperation("%3d: DNSServiceGetAddrInfo(%##s) STOP PID[%d](%s)", request->sd, request->u.addrinfo.q4.qname.c,
		get_peer_pid(request->sd, pid_name), pid_name);

    if (request->u.addrinfo.q4.QuestionContext)
    {
        mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q4);
        request->u.addrinfo.q4.QuestionContext = mDNSNULL;
    }
    if (request->u.addrinfo.q4.qnameOrig)
    {
        freeL("QueryTermination", request->u.addrinfo.q4.qnameOrig);
        request->u.addrinfo.q4.qnameOrig = mDNSNULL;
    }
    if (request->u.addrinfo.q42)
    {
        if (request->u.addrinfo.q42->QuestionContext)
        {
            LogInfo("addrinfo_termination_callback: Stopping q42 %##s", request->u.addrinfo.q42->qname.c);
            mDNS_StopQuery(&mDNSStorage, request->u.addrinfo.q42);
        }
        if (request->u.addrinfo.q42->qnameOrig)
        {
            LogInfo("addrinfo_termination_callback: freeing q42 qnameOrig %##s", request->u.addrinfo.q42->qnameOrig->c);
            freeL("QueryTermination q42", request->u.addrinfo.q42->qnameOrig);
            request->u.addrinfo.q42->qnameOrig = mDNSNULL;
        }
        freeL("addrinfo Q42", request->u.addrinfo.q42);
        request->u.addrinfo.q42 = mDNSNULL;
    }

    if (request->u.addrinfo.q6.QuestionContext)
    {
        mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q6);
        request->u.addrinfo.q6.QuestionContext = mDNSNULL;
    }
    if (request->u.addrinfo.q6.qnameOrig)
    {
        freeL("QueryTermination", request->u.addrinfo.q6.qnameOrig);
        request->u.addrinfo.q6.qnameOrig = mDNSNULL;
    }
    if (request->u.addrinfo.q62)
    {
        if (request->u.addrinfo.q62->QuestionContext)
        {
            LogInfo("addrinfo_termination_callback: Stopping q62 %##s", request->u.addrinfo.q62->qname.c);
            mDNS_StopQuery(&mDNSStorage, request->u.addrinfo.q62);
        }
        if (request->u.addrinfo.q62->qnameOrig)
        {
            LogInfo("addrinfo_termination_callback: freeing q62 qnameOrig %##s", request->u.addrinfo.q62->qnameOrig->c);
            freeL("QueryTermination q62", request->u.addrinfo.q62->qnameOrig);
            request->u.addrinfo.q62->qnameOrig = mDNSNULL;
        }
        freeL("addrinfo Q62", request->u.addrinfo.q62);
        request->u.addrinfo.q62 = mDNSNULL;
    }
}

mDNSlocal mStatus handle_addrinfo_request(request_state *request)
{
    char hostname[256];
    domainname d;
    mStatus err = 0;

    DNSServiceFlags flags  = get_flags(&request->msgptr, request->msgend);
    mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);

    mDNSPlatformMemZero(&request->u.addrinfo, sizeof(request->u.addrinfo));
    request->u.addrinfo.interface_id = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
    request->u.addrinfo.flags        = flags;
    request->u.addrinfo.protocol     = get_uint32(&request->msgptr, request->msgend);

    if (interfaceIndex && !request->u.addrinfo.interface_id) return(mStatus_BadParamErr);
    if (request->u.addrinfo.protocol > (kDNSServiceProtocol_IPv4|kDNSServiceProtocol_IPv6)) return(mStatus_BadParamErr);

    if (get_string(&request->msgptr, request->msgend, hostname, 256) < 0) return(mStatus_BadParamErr);

    if (!request->msgptr) { LogMsg("%3d: DNSServiceGetAddrInfo(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }

    if (!MakeDomainNameFromDNSNameString(&d, hostname))
    { LogMsg("ERROR: handle_addrinfo_request: bad hostname: %s", hostname); return(mStatus_BadParamErr); }

#if 0
    if (!AuthorizedDomain(request, &d, AutoBrowseDomains)) return (mStatus_NoError);
#endif

    if (!request->u.addrinfo.protocol)
    {
        flags |= kDNSServiceFlagsSuppressUnusable;
        request->u.addrinfo.protocol = (kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6);
    }

    request->u.addrinfo.q4.InterfaceID      = request->u.addrinfo.q6.InterfaceID      = request->u.addrinfo.interface_id;
    request->u.addrinfo.q4.flags            = request->u.addrinfo.q6.flags            = flags;
    request->u.addrinfo.q4.Target           = request->u.addrinfo.q6.Target           = zeroAddr;
    request->u.addrinfo.q4.qname            = request->u.addrinfo.q6.qname            = d;
    request->u.addrinfo.q4.qclass           = request->u.addrinfo.q6.qclass           = kDNSServiceClass_IN;
    request->u.addrinfo.q4.LongLived        = request->u.addrinfo.q6.LongLived        = (flags & kDNSServiceFlagsLongLivedQuery     ) != 0;
    request->u.addrinfo.q4.ExpectUnique     = request->u.addrinfo.q6.ExpectUnique     = mDNSfalse;
    request->u.addrinfo.q4.ForceMCast       = request->u.addrinfo.q6.ForceMCast       = (flags & kDNSServiceFlagsForceMulticast     ) != 0;
    request->u.addrinfo.q4.ReturnIntermed   = request->u.addrinfo.q6.ReturnIntermed   = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
    request->u.addrinfo.q4.SuppressUnusable = request->u.addrinfo.q6.SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable   ) != 0;
    request->u.addrinfo.q4.TimeoutQuestion  = request->u.addrinfo.q6.TimeoutQuestion  = (flags & kDNSServiceFlagsTimeout            ) != 0;
    request->u.addrinfo.q4.WakeOnResolve    = request->u.addrinfo.q6.WakeOnResolve    = 0;
    request->u.addrinfo.q4.UseBrackgroundTrafficClass = request->u.addrinfo.q6.UseBrackgroundTrafficClass  = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
    request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = 0;
    request->u.addrinfo.q4.ValidatingResponse = request->u.addrinfo.q6.ValidatingResponse = 0;
    request->u.addrinfo.q4.qnameOrig        = request->u.addrinfo.q6.qnameOrig        = mDNSNULL;

    if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv4)
    {
        request->u.addrinfo.q4.qtype            = kDNSServiceType_A;
        request->u.addrinfo.q4.SearchListIndex  = 0;

        // We append search domains only for queries that are a single label. If overriden using
        // command line argument "AlwaysAppendSearchDomains", then we do it for any query which
        // is not fully qualified.
        if (hostname[strlen(hostname) - 1] != '.' && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
        {
            request->u.addrinfo.q4.AppendSearchDomains = 1;
            request->u.addrinfo.q4.AppendLocalSearchDomains = 1;
        }
        else
        {
            request->u.addrinfo.q4.AppendSearchDomains = 0;
            request->u.addrinfo.q4.AppendLocalSearchDomains = 0;
        }
        request->u.addrinfo.q4.RetryWithSearchDomains = (ApplySearchDomainsFirst(&request->u.addrinfo.q4) ? 1 : 0);
        request->u.addrinfo.q4.QuestionCallback = queryrecord_result_callback;
        request->u.addrinfo.q4.QuestionContext  = request;
        err = mDNS_StartQuery(&mDNSStorage, &request->u.addrinfo.q4);
        if (err != mStatus_NoError)
        {
            LogMsg("ERROR: mDNS_StartQuery: %d", (int)err);
            request->u.addrinfo.q4.QuestionContext = mDNSNULL;
        }
        #if APPLE_OSX_mDNSResponder
        err = SendAdditionalQuery(&request->u.addrinfo.q4, request, err);
        #endif // APPLE_OSX_mDNSResponder
    }

    if (!err && (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv6))
    {
        request->u.addrinfo.q6.qtype            = kDNSServiceType_AAAA;
        request->u.addrinfo.q6.SearchListIndex  = 0;
        if (hostname[strlen(hostname) - 1] != '.' && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
        {
            request->u.addrinfo.q6.AppendSearchDomains = 1;
            request->u.addrinfo.q6.AppendLocalSearchDomains = 1;
        }
        else
        {
            request->u.addrinfo.q6.AppendSearchDomains = 0;
            request->u.addrinfo.q6.AppendLocalSearchDomains = 0;
        }
        request->u.addrinfo.q6.RetryWithSearchDomains = (ApplySearchDomainsFirst(&request->u.addrinfo.q6) ? 1 : 0);
        request->u.addrinfo.q6.QuestionCallback = queryrecord_result_callback;
        request->u.addrinfo.q6.QuestionContext  = request;
        err = mDNS_StartQuery(&mDNSStorage, &request->u.addrinfo.q6);
        if (err != mStatus_NoError)
        {
            LogMsg("ERROR: mDNS_StartQuery: %d", (int)err);
            request->u.addrinfo.q6.QuestionContext = mDNSNULL;
            if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv4)
            {
                // If we started a query for IPv4, we need to cancel it
                mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q4);
                request->u.addrinfo.q4.QuestionContext = mDNSNULL;
            }
        }
        #if APPLE_OSX_mDNSResponder
        err = SendAdditionalQuery(&request->u.addrinfo.q6, request, err);
        #endif // APPLE_OSX_mDNSResponder
    }

    LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)",
                 request->sd, flags, interfaceIndex, request->u.addrinfo.protocol, d.c, get_peer_pid(request->sd, pid_name), pid_name);

    if (!err) request->terminate = addrinfo_termination_callback;

    return(err);
}

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Main Request Handler etc.
#endif

mDNSlocal request_state *NewRequest(void)
{
    request_state **p = &all_requests;
    while (*p) p=&(*p)->next;
    *p = mallocL("request_state", sizeof(request_state));
    if (!*p) FatalError("ERROR: malloc");
    mDNSPlatformMemZero(*p, sizeof(request_state));
    return(*p);
}

// read_msg may be called any time when the transfer state (req->ts) is t_morecoming.
// if there is no data on the socket, the socket will be closed and t_terminated will be returned
mDNSlocal void read_msg(request_state *req)
{
    if (req->ts == t_terminated || req->ts == t_error)
    { LogMsg("%3d: ERROR: read_msg called with transfer state terminated or error", req->sd); req->ts = t_error; return; }

    if (req->ts == t_complete)  // this must be death or something is wrong
    {
        char buf[4];    // dummy for death notification
        int nread = udsSupportReadFD(req->sd, buf, 4, 0, req->platform_data);
        if (!nread) { req->ts = t_terminated; return; }
        if (nread < 0) goto rerror;
        LogMsg("%3d: ERROR: read data from a completed request", req->sd);
        req->ts = t_error;
        return;
    }

    if (req->ts != t_morecoming)
    { LogMsg("%3d: ERROR: read_msg called with invalid transfer state (%d)", req->sd, req->ts); req->ts = t_error; return; }

    if (req->hdr_bytes < sizeof(ipc_msg_hdr))
    {
        mDNSu32 nleft = sizeof(ipc_msg_hdr) - req->hdr_bytes;
        int nread = udsSupportReadFD(req->sd, (char *)&req->hdr + req->hdr_bytes, nleft, 0, req->platform_data);
        if (nread == 0) { req->ts = t_terminated; return; }
        if (nread < 0) goto rerror;
        req->hdr_bytes += nread;
        if (req->hdr_bytes > sizeof(ipc_msg_hdr))
        { LogMsg("%3d: ERROR: read_msg - read too many header bytes", req->sd); req->ts = t_error; return; }

        // only read data if header is complete
        if (req->hdr_bytes == sizeof(ipc_msg_hdr))
        {
            ConvertHeaderBytes(&req->hdr);
            if (req->hdr.version != VERSION)
            { LogMsg("%3d: ERROR: client version 0x%08X daemon version 0x%08X", req->sd, req->hdr.version, VERSION); req->ts = t_error; return; }

            // Largest conceivable single request is a DNSServiceRegisterRecord() or DNSServiceAddRecord()
            // with 64kB of rdata. Adding 1009 byte for a maximal domain name, plus a safety margin
            // for other overhead, this means any message above 70kB is definitely bogus.
            if (req->hdr.datalen > 70000)
            { LogMsg("%3d: ERROR: read_msg: hdr.datalen %u (0x%X) > 70000", req->sd, req->hdr.datalen, req->hdr.datalen); req->ts = t_error; return; }
            req->msgbuf = mallocL("request_state msgbuf", req->hdr.datalen + MSG_PAD_BYTES);
            if (!req->msgbuf) { my_perror("ERROR: malloc"); req->ts = t_error; return; }
            req->msgptr = req->msgbuf;
            req->msgend = req->msgbuf + req->hdr.datalen;
            mDNSPlatformMemZero(req->msgbuf, req->hdr.datalen + MSG_PAD_BYTES);
        }
    }

    // If our header is complete, but we're still needing more body data, then try to read it now
    // Note: For cancel_request req->hdr.datalen == 0, but there's no error return socket for cancel_request
    // Any time we need to get the error return socket we know we'll have at least one data byte
    // (even if only the one-byte empty C string placeholder for the old ctrl_path parameter)
    if (req->hdr_bytes == sizeof(ipc_msg_hdr) && req->data_bytes < req->hdr.datalen)
    {
        mDNSu32 nleft = req->hdr.datalen - req->data_bytes;
        int nread;
#if !defined(_WIN32)
        struct iovec vec = { req->msgbuf + req->data_bytes, nleft };    // Tell recvmsg where we want the bytes put
        struct msghdr msg;
        struct cmsghdr *cmsg;
        char cbuf[CMSG_SPACE(sizeof(dnssd_sock_t))];
        msg.msg_name       = 0;
        msg.msg_namelen    = 0;
        msg.msg_iov        = &vec;
        msg.msg_iovlen     = 1;
        msg.msg_control    = cbuf;
        msg.msg_controllen = sizeof(cbuf);
        msg.msg_flags      = 0;
        nread = recvmsg(req->sd, &msg, 0);
#else
        nread = udsSupportReadFD(req->sd, (char *)req->msgbuf + req->data_bytes, nleft, 0, req->platform_data);
#endif
        if (nread == 0) { req->ts = t_terminated; return; }
        if (nread < 0) goto rerror;
        req->data_bytes += nread;
        if (req->data_bytes > req->hdr.datalen)
        { LogMsg("%3d: ERROR: read_msg - read too many data bytes", req->sd); req->ts = t_error; return; }
#if !defined(_WIN32)
        cmsg = CMSG_FIRSTHDR(&msg);
#if DEBUG_64BIT_SCM_RIGHTS
        LogMsg("%3d: Expecting %d %d %d %d", req->sd, sizeof(cbuf),       sizeof(cbuf),   SOL_SOCKET,       SCM_RIGHTS);
        LogMsg("%3d: Got       %d %d %d %d", req->sd, msg.msg_controllen, cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type);
#endif // DEBUG_64BIT_SCM_RIGHTS
        if (msg.msg_controllen == sizeof(cbuf) &&
            cmsg->cmsg_len     == CMSG_LEN(sizeof(dnssd_sock_t)) &&
            cmsg->cmsg_level   == SOL_SOCKET   &&
            cmsg->cmsg_type    == SCM_RIGHTS)
        {
#if APPLE_OSX_mDNSResponder
            // Strictly speaking BPF_fd belongs solely in the platform support layer, but because
            // of privilege separation on Mac OS X we need to get BPF_fd from mDNSResponderHelper,
            // and it's convenient to repurpose the existing fd-passing code here for that task
            if (req->hdr.op == send_bpf)
            {
                dnssd_sock_t x = *(dnssd_sock_t *)CMSG_DATA(cmsg);
                LogOperation("%3d: Got BPF %d", req->sd, x);
                mDNSPlatformReceiveBPF_fd(&mDNSStorage, x);
            }
            else
#endif // APPLE_OSX_mDNSResponder
            req->errsd = *(dnssd_sock_t *)CMSG_DATA(cmsg);
#if DEBUG_64BIT_SCM_RIGHTS
            LogMsg("%3d: read req->errsd %d", req->sd, req->errsd);
#endif // DEBUG_64BIT_SCM_RIGHTS
            if (req->data_bytes < req->hdr.datalen)
            {
                LogMsg("%3d: Client(PID [%d](%s)) sent error socket %d via SCM_RIGHTS with req->data_bytes %d < req->hdr.datalen %d",
                       req->sd, get_peer_pid(req->sd, pid_name), pid_name, req->errsd, req->data_bytes, req->hdr.datalen);
                req->ts = t_error;
                return;
            }
        }
#endif
    }

    // If our header and data are both complete, see if we need to make our separate error return socket
    if (req->hdr_bytes == sizeof(ipc_msg_hdr) && req->data_bytes == req->hdr.datalen)
    {
        if (req->terminate && req->hdr.op != cancel_request)
        {
            dnssd_sockaddr_t cliaddr;
#if defined(USE_TCP_LOOPBACK)
            mDNSOpaque16 port;
            u_long opt = 1;
            port.b[0] = req->msgptr[0];
            port.b[1] = req->msgptr[1];
            req->msgptr += 2;
            cliaddr.sin_family      = AF_INET;
            cliaddr.sin_port        = port.NotAnInteger;
            cliaddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
#else
            char ctrl_path[MAX_CTLPATH];
            get_string(&req->msgptr, req->msgend, ctrl_path, MAX_CTLPATH);  // path is first element in message buffer
            mDNSPlatformMemZero(&cliaddr, sizeof(cliaddr));
            cliaddr.sun_family = AF_LOCAL;
            mDNSPlatformStrCopy(cliaddr.sun_path, ctrl_path);
            // If the error return path UDS name is empty string, that tells us
            // that this is a new version of the library that's going to pass us
            // the error return path socket via sendmsg/recvmsg
            if (ctrl_path[0] == 0)
            {
                if (req->errsd == req->sd)
                { LogMsg("%3d: read_msg: ERROR failed to get errsd via SCM_RIGHTS", req->sd); req->ts = t_error; return; }
                goto got_errfd;
            }
#endif

            req->errsd = socket(AF_DNSSD, SOCK_STREAM, 0);
            if (!dnssd_SocketValid(req->errsd)) 
            { 
                my_throttled_perror("ERROR: socket");
                req->ts = t_error;
                return;
            }

            if (connect(req->errsd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0)
            {
#if !defined(USE_TCP_LOOPBACK)
                struct stat sb;
                LogMsg("%3d: read_msg: Couldn't connect to error return path socket “%s” errno %d (%s)",
                       req->sd, cliaddr.sun_path, dnssd_errno, dnssd_strerror(dnssd_errno));
                if (stat(cliaddr.sun_path, &sb) < 0)
                    LogMsg("%3d: read_msg: stat failed “%s” errno %d (%s)", req->sd, cliaddr.sun_path, dnssd_errno, dnssd_strerror(dnssd_errno));
                else
                    LogMsg("%3d: read_msg: file “%s” mode %o (octal) uid %d gid %d", req->sd, cliaddr.sun_path, sb.st_mode, sb.st_uid, sb.st_gid);
#endif
                req->ts = t_error;
                return;
            }

#if !defined(USE_TCP_LOOPBACK)
got_errfd:
#endif
            LogOperation("%3d: Error socket %d created %08X %08X", req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0]);
#if defined(_WIN32)
            if (ioctlsocket(req->errsd, FIONBIO, &opt) != 0)
#else
            if (fcntl(req->errsd, F_SETFL, fcntl(req->errsd, F_GETFL, 0) | O_NONBLOCK) != 0)
#endif
            {
                LogMsg("%3d: ERROR: could not set control socket to non-blocking mode errno %d (%s)",
                       req->sd, dnssd_errno, dnssd_strerror(dnssd_errno));
                req->ts = t_error;
                return;
            }
        }

        req->ts = t_complete;
    }

    return;

rerror:
    if (dnssd_errno == dnssd_EWOULDBLOCK || dnssd_errno == dnssd_EINTR) return;
    LogMsg("%3d: ERROR: read_msg errno %d (%s)", req->sd, dnssd_errno, dnssd_strerror(dnssd_errno));
    req->ts = t_error;
}

#define RecordOrientedOp(X) \
    ((X) == reg_record_request || (X) == add_record_request || (X) == update_record_request || (X) == remove_record_request)

// The lightweight operations are the ones that don't need a dedicated request_state structure allocated for them
#define LightweightOp(X) (RecordOrientedOp(X) || (X) == cancel_request)

mDNSlocal void request_callback(int fd, short filter, void *info)
{
    mStatus err = 0;
    request_state *req = info;
    mDNSs32 min_size = sizeof(DNSServiceFlags);
    (void)fd; // Unused
    (void)filter; // Unused

    for (;;)
    {
        read_msg(req);
        if (req->ts == t_morecoming) return;
        if (req->ts == t_terminated || req->ts == t_error) { AbortUnlinkAndFree(req); return; }
        if (req->ts != t_complete) { LogMsg("req->ts %d != t_complete", req->ts); AbortUnlinkAndFree(req); return; }

        if (req->hdr.version != VERSION)
        {
            LogMsg("ERROR: client version %d incompatible with daemon version %d", req->hdr.version, VERSION);
            AbortUnlinkAndFree(req);
            return;
        }

        switch(req->hdr.op)            //          Interface       + other data
        {
        case connection_request:       min_size = 0;                                                                           break;
        case reg_service_request:      min_size += sizeof(mDNSu32) + 4 /* name, type, domain, host */ + 4 /* port, textlen */; break;
        case add_record_request:       min_size +=                   4 /* type, rdlen */              + 4 /* ttl */;           break;
        case update_record_request:    min_size +=                   2 /* rdlen */                    + 4 /* ttl */;           break;
        case remove_record_request:                                                                                            break;
        case browse_request:           min_size += sizeof(mDNSu32) + 2 /* type, domain */;                                     break;
        case resolve_request:          min_size += sizeof(mDNSu32) + 3 /* type, type, domain */;                               break;
        case query_request:            min_size += sizeof(mDNSu32) + 1 /* name */                     + 4 /* type, class*/;    break;
        case enumeration_request:      min_size += sizeof(mDNSu32);                                                            break;
        case reg_record_request:       min_size += sizeof(mDNSu32) + 1 /* name */ + 6 /* type, class, rdlen */ + 4 /* ttl */;  break;
        case reconfirm_record_request: min_size += sizeof(mDNSu32) + 1 /* name */ + 6 /* type, class, rdlen */;                break;
        case setdomain_request:        min_size +=                   1 /* domain */;                                           break;
        case getproperty_request:      min_size = 2;                                                                           break;
        case port_mapping_request:     min_size += sizeof(mDNSu32) + 4 /* udp/tcp */ + 4 /* int/ext port */    + 4 /* ttl */;  break;
        case addrinfo_request:         min_size += sizeof(mDNSu32) + 4 /* v4/v6 */   + 1 /* hostname */;                       break;
        case send_bpf:                     // Same as cancel_request below
        case cancel_request:           min_size = 0;                                                                           break;
        case release_request:          min_size += sizeof(mDNSu32) + 3 /* type, type, domain */;                               break;
        default: LogMsg("ERROR: validate_message - unsupported req type: %d", req->hdr.op); min_size = -1;                     break;
        }

        if ((mDNSs32)req->data_bytes < min_size)
        { LogMsg("Invalid message %d bytes; min for %d is %d", req->data_bytes, req->hdr.op, min_size); AbortUnlinkAndFree(req); return; }

        if (LightweightOp(req->hdr.op) && !req->terminate)
        { LogMsg("Reg/Add/Update/Remove %d require existing connection", req->hdr.op);                  AbortUnlinkAndFree(req); return; }

        // check if client wants silent operation
        if (req->hdr.ipc_flags & IPC_FLAGS_NOREPLY) req->no_reply = 1;

        // If req->terminate is already set, this means this operation is sharing an existing connection
        if (req->terminate && !LightweightOp(req->hdr.op))
        {
            request_state *newreq = NewRequest();
            newreq->primary = req;
            newreq->sd      = req->sd;
            newreq->errsd   = req->errsd;
            newreq->uid     = req->uid;
            newreq->hdr     = req->hdr;
            newreq->msgbuf  = req->msgbuf;
            newreq->msgptr  = req->msgptr;
            newreq->msgend  = req->msgend;
            req = newreq;
        }

        // If we're shutting down, don't allow new client requests
        // We do allow "cancel" and "getproperty" during shutdown
        if (mDNSStorage.ShutdownTime && req->hdr.op != cancel_request && req->hdr.op != getproperty_request)
        {
            err = mStatus_ServiceNotRunning;
        }
        else switch(req->hdr.op)
            {
            // These are all operations that have their own first-class request_state object
            case connection_request:           LogOperation("%3d: DNSServiceCreateConnection START PID[%d](%s)", 
							req->sd, get_peer_pid(req->sd, pid_name), pid_name);
					       req->terminate = connection_termination; break;
            case resolve_request:              err = handle_resolve_request     (req);  break;
            case query_request:                err = handle_queryrecord_request (req);  break;
            case browse_request:               err = handle_browse_request      (req);  break;
            case reg_service_request:          err = handle_regservice_request  (req);  break;
            case enumeration_request:          err = handle_enum_request        (req);  break;
            case reconfirm_record_request:     err = handle_reconfirm_request   (req);  break;
            case setdomain_request:            err = handle_setdomain_request   (req);  break;
            case getproperty_request:                handle_getproperty_request (req);  break;
            case port_mapping_request:         err = handle_port_mapping_request(req);  break;
            case addrinfo_request:             err = handle_addrinfo_request    (req);  break;
            case send_bpf: /* Do nothing for send_bpf */ break;

            // These are all operations that work with an existing request_state object
            case reg_record_request:           err = handle_regrecord_request   (req);  break;
            case add_record_request:           err = handle_add_request         (req);  break;
            case update_record_request:        err = handle_update_request      (req);  break;
            case remove_record_request:        err = handle_removerecord_request(req);  break;
            case cancel_request:                     handle_cancel_request      (req);  break;
            case release_request:              err = handle_release_request     (req);  break;
            default: LogMsg("%3d: ERROR: Unsupported UDS req: %d", req->sd, req->hdr.op);
            }

        // req->msgbuf may be NULL, e.g. for connection_request or remove_record_request
        if (req->msgbuf) freeL("request_state msgbuf", req->msgbuf);

        // There's no return data for a cancel request (DNSServiceRefDeallocate returns no result)
        // For a DNSServiceGetProperty call, the handler already generated the response, so no need to do it again here
        if (req->hdr.op != cancel_request && req->hdr.op != getproperty_request && req->hdr.op != send_bpf)
        {
            const mStatus err_netorder = dnssd_htonl(err);
            send_all(req->errsd, (const char *)&err_netorder, sizeof(err_netorder));
            if (req->errsd != req->sd)
            {
                LogOperation("%3d: Error socket %d closed  %08X %08X (%d)",
                             req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0], err);
                dnssd_close(req->errsd);
                req->errsd = req->sd;
                // Also need to reset the parent's errsd, if this is a subordinate operation
                if (req->primary) req->primary->errsd = req->primary->sd;
            }
        }

        // Reset ready to accept the next req on this pipe
        if (req->primary) req = req->primary;
        req->ts         = t_morecoming;
        req->hdr_bytes  = 0;
        req->data_bytes = 0;
        req->msgbuf     = mDNSNULL;
        req->msgptr     = mDNSNULL;
        req->msgend     = 0;
    }
}

mDNSlocal void connect_callback(int fd, short filter, void *info)
{
    dnssd_sockaddr_t cliaddr;
    dnssd_socklen_t len = (dnssd_socklen_t) sizeof(cliaddr);
    dnssd_sock_t sd = accept(fd, (struct sockaddr*) &cliaddr, &len);
#if defined(SO_NOSIGPIPE) || defined(_WIN32)
    unsigned long optval = 1;
#endif

    (void)filter; // Unused
    (void)info; // Unused

    if (!dnssd_SocketValid(sd))
    {
        if (dnssd_errno != dnssd_EWOULDBLOCK) 
            my_throttled_perror("ERROR: accept");
        return;
    }

#ifdef SO_NOSIGPIPE
    // Some environments (e.g. OS X) support turning off SIGPIPE for a socket
    if (setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) < 0)
        LogMsg("%3d: WARNING: setsockopt - SO_NOSIGPIPE %d (%s)", sd, dnssd_errno, dnssd_strerror(dnssd_errno));
#endif

#if defined(_WIN32)
    if (ioctlsocket(sd, FIONBIO, &optval) != 0)
#else
    if (fcntl(sd, F_SETFL, fcntl(sd, F_GETFL, 0) | O_NONBLOCK) != 0)
#endif
    {
        my_perror("ERROR: fcntl(sd, F_SETFL, O_NONBLOCK) - aborting client");
        dnssd_close(sd);
        return;
    }
    else
    {
        request_state *request = NewRequest();
        request->ts    = t_morecoming;
        request->sd    = sd;
        request->errsd = sd;
#if APPLE_OSX_mDNSResponder
        struct xucred x;
        socklen_t xucredlen = sizeof(x);
        if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION) request->uid = x.cr_uid;
        else my_perror("ERROR: getsockopt, LOCAL_PEERCRED");
        debugf("LOCAL_PEERCRED %d %u %u %d", xucredlen, x.cr_version, x.cr_uid, x.cr_ngroups);
#endif // APPLE_OSX_mDNSResponder
        LogOperation("%3d: Adding FD for uid %u", request->sd, request->uid);
        udsSupportAddFDToEventLoop(sd, request_callback, request, &request->platform_data);
    }
}

mDNSlocal mDNSBool uds_socket_setup(dnssd_sock_t skt)
{
#if defined(SO_NP_EXTENSIONS)
    struct      so_np_extensions sonpx;
    socklen_t optlen = sizeof(struct so_np_extensions);
    sonpx.npx_flags = SONPX_SETOPTSHUT;
    sonpx.npx_mask  = SONPX_SETOPTSHUT;
    if (setsockopt(skt, SOL_SOCKET, SO_NP_EXTENSIONS, &sonpx, optlen) < 0)
        my_perror("WARNING: could not set sockopt - SO_NP_EXTENSIONS");
#endif
#if defined(_WIN32)
    // SEH: do we even need to do this on windows?
    // This socket will be given to WSAEventSelect which will automatically set it to non-blocking
    u_long opt = 1;
    if (ioctlsocket(skt, FIONBIO, &opt) != 0)
#else
    if (fcntl(skt, F_SETFL, fcntl(skt, F_GETFL, 0) | O_NONBLOCK) != 0)
#endif
    {
        my_perror("ERROR: could not set listen socket to non-blocking mode");
        return mDNSfalse;
    }

    if (listen(skt, LISTENQ) != 0)
    {
        my_perror("ERROR: could not listen on listen socket");
        return mDNSfalse;
    }

    if (mStatus_NoError != udsSupportAddFDToEventLoop(skt, connect_callback, (void *) NULL, (void **) NULL))
    {
        my_perror("ERROR: could not add listen socket to event loop");
        return mDNSfalse;
    }
    else LogOperation("%3d: Listening for incoming Unix Domain Socket client requests", skt);

    return mDNStrue;
}

mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count)
{
    dnssd_sockaddr_t laddr;
    int ret;
    mDNSu32 i = 0;

    LogInfo("udsserver_init");

    // If a particular platform wants to opt out of having a PID file, define PID_FILE to be ""
    if (PID_FILE[0])
    {
        FILE *fp = fopen(PID_FILE, "w");
        if (fp != NULL)
        {
            fprintf(fp, "%d\n", getpid());
            fclose(fp);
        }
    }

    if (skts)
    {
        for (i = 0; i < count; i++)
            if (dnssd_SocketValid(skts[i]) && !uds_socket_setup(skts[i]))
                goto error;
    }
    else
    {
        listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
        if (!dnssd_SocketValid(listenfd))
        {
            my_perror("ERROR: socket(AF_DNSSD, SOCK_STREAM, 0); failed");
            goto error;
        }

        mDNSPlatformMemZero(&laddr, sizeof(laddr));

        #if defined(USE_TCP_LOOPBACK)
        {
            laddr.sin_family = AF_INET;
            laddr.sin_port = htons(MDNS_TCP_SERVERPORT);
            laddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
            ret = bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr));
            if (ret < 0)
            {
                my_perror("ERROR: bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr)); failed");
                goto error;
            }
        }
        #else
        {
            mode_t mask = umask(0);
            unlink(MDNS_UDS_SERVERPATH);  // OK if this fails
            laddr.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.
            laddr.sun_len = sizeof(struct sockaddr_un);
            #endif
            if (strlen(MDNS_UDS_SERVERPATH) >= sizeof(laddr.sun_path))
            {
                LogMsg("ERROR: MDNS_UDS_SERVERPATH must be < %d characters", (int)sizeof(laddr.sun_path));
                goto error;
            }
            mDNSPlatformStrCopy(laddr.sun_path, MDNS_UDS_SERVERPATH);
            ret = bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr));
            umask(mask);
            if (ret < 0)
            {
                my_perror("ERROR: bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr)); failed");
                goto error;
            }
        }
        #endif

        if (!uds_socket_setup(listenfd)) goto error;
    }

#if !defined(PLATFORM_NO_RLIMIT)
    {
        // Set maximum number of open file descriptors
    #define MIN_OPENFILES 10240
        struct rlimit maxfds, newfds;

        // Due to bugs in OS X (<rdar://problem/2941095>, <rdar://problem/3342704>, <rdar://problem/3839173>)
        // you have to get and set rlimits once before getrlimit will return sensible values
        if (getrlimit(RLIMIT_NOFILE, &maxfds) < 0) { my_perror("ERROR: Unable to get file descriptor limit"); return 0; }
        if (setrlimit(RLIMIT_NOFILE, &maxfds) < 0) my_perror("ERROR: Unable to set maximum file descriptor limit");

        if (getrlimit(RLIMIT_NOFILE, &maxfds) < 0) { my_perror("ERROR: Unable to get file descriptor limit"); return 0; }
        newfds.rlim_max = (maxfds.rlim_max > MIN_OPENFILES) ? maxfds.rlim_max : MIN_OPENFILES;
        newfds.rlim_cur = (maxfds.rlim_cur > MIN_OPENFILES) ? maxfds.rlim_cur : MIN_OPENFILES;
        if (newfds.rlim_max != maxfds.rlim_max || newfds.rlim_cur != maxfds.rlim_cur)
            if (setrlimit(RLIMIT_NOFILE, &newfds) < 0) my_perror("ERROR: Unable to set maximum file descriptor limit");

        if (getrlimit(RLIMIT_NOFILE, &maxfds) < 0) { my_perror("ERROR: Unable to get file descriptor limit"); return 0; }
        debugf("maxfds.rlim_max %d", (long)maxfds.rlim_max);
        debugf("maxfds.rlim_cur %d", (long)maxfds.rlim_cur);
    }
#endif

    // We start a "LocalOnly" query looking for Automatic Browse Domain records.
    // When Domain Enumeration in uDNS.c finds an "lb" record from the network, its "FoundDomain" routine
    // creates a "LocalOnly" record, which results in our AutomaticBrowseDomainChange callback being invoked
    mDNS_GetDomains(&mDNSStorage, &mDNSStorage.AutomaticBrowseDomainQ, mDNS_DomainTypeBrowseAutomatic,
                    mDNSNULL, mDNSInterface_LocalOnly, AutomaticBrowseDomainChange, mDNSNULL);

    // Add "local" as recommended registration domain ("dns-sd -E"), recommended browsing domain ("dns-sd -F"), and automatic browsing domain
    RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeRegistration);
    RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeBrowse);
    AddAutoBrowseDomain(0, &localdomain);

    udsserver_handle_configchange(&mDNSStorage);
    return 0;

error:

    my_perror("ERROR: udsserver_init");
    return -1;
}

mDNSexport int udsserver_exit(void)
{
    // Cancel all outstanding client requests
    while (all_requests) AbortUnlinkAndFree(all_requests);

    // Clean up any special mDNSInterface_LocalOnly records we created, both the entries for "local" we
    // created in udsserver_init, and others we created as a result of reading local configuration data
    while (LocalDomainEnumRecords)
    {
        ARListElem *rem = LocalDomainEnumRecords;
        LocalDomainEnumRecords = LocalDomainEnumRecords->next;
        mDNS_Deregister(&mDNSStorage, &rem->ar);
    }

    // If the launching environment created no listening socket,
    // that means we created it ourselves, so we should clean it up on exit
    if (dnssd_SocketValid(listenfd))
    {
        dnssd_close(listenfd);
#if !defined(USE_TCP_LOOPBACK)
        // Currently, we're unable to remove /var/run/mdnsd because we've changed to userid "nobody"
        // to give up unnecessary privilege, but we need to be root to remove this Unix Domain Socket.
        // It would be nice if we could find a solution to this problem
        if (unlink(MDNS_UDS_SERVERPATH))
            debugf("Unable to remove %s", MDNS_UDS_SERVERPATH);
#endif
    }

    if (PID_FILE[0]) unlink(PID_FILE);

    return 0;
}

mDNSlocal void LogClientInfo(mDNS *const m, const request_state *req)
{
    char prefix[16];
    if (req->primary) mDNS_snprintf(prefix, sizeof(prefix), " -> ");
    else mDNS_snprintf(prefix, sizeof(prefix), "%3d:", req->sd);

    usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);

    if (!req->terminate)
        LogMsgNoIdent("%s No operation yet on this socket", prefix);
    else if (req->terminate == connection_termination)
    {
        int num_records = 0, num_ops = 0;
        const registered_record_entry *p;
        const request_state *r;
        for (p = req->u.reg_recs; p; p=p->next) num_records++;
        for (r = req->next; r; r=r->next) if (r->primary == req) num_ops++;
        LogMsgNoIdent("%s DNSServiceCreateConnection: %d registered record%s, %d kDNSServiceFlagsShareConnection operation%s PID[%d](%s)", 
		prefix, num_records, num_records != 1 ? "s" : "", num_ops,     num_ops     != 1 ? "s" : "", get_peer_pid(req->sd, pid_name), pid_name);
        for (p = req->u.reg_recs; p; p=p->next)
            LogMsgNoIdent(" ->  DNSServiceRegisterRecord %3d %s PID[%d](%s)", p->key, ARDisplayString(m, p->rr), get_peer_pid(req->sd, pid_name), pid_name);
        for (r = req->next; r; r=r->next) if (r->primary == req) LogClientInfo(m, r);
    }
    else if (req->terminate == regservice_termination_callback)
    {
        service_instance *ptr;
        for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
            LogMsgNoIdent("%s DNSServiceRegister         %##s %u/%u PID[%d](%s)",
                          (ptr == req->u.servicereg.instances) ? prefix : "    ", ptr->srs.RR_SRV.resrec.name->c,
			   mDNSVal16(req->u.servicereg.port), SRS_PORT(&ptr->srs), get_peer_pid(req->sd, pid_name), pid_name);
    }
    else if (req->terminate == browse_termination_callback)
    {
        browser_t *blist;
        for (blist = req->u.browser.browsers; blist; blist = blist->next)
            LogMsgNoIdent("%s DNSServiceBrowse           %##s PID[%d](%s)", 
		(blist == req->u.browser.browsers) ? prefix : "    ",blist->q.qname.c, get_peer_pid(req->sd, pid_name), pid_name);
    }
    else if (req->terminate == resolve_termination_callback)
        LogMsgNoIdent("%s DNSServiceResolve          %##s PID[%d](%s)", 
		prefix, req->u.resolve.qsrv.qname.c, get_peer_pid(req->sd, pid_name), pid_name);
    else if (req->terminate == queryrecord_termination_callback)
        LogMsgNoIdent("%s DNSServiceQueryRecord      %##s (%s) PID[%d](%s)", 
		prefix, req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype), get_peer_pid(req->sd, pid_name), pid_name);
    else if (req->terminate == enum_termination_callback)
        LogMsgNoIdent("%s DNSServiceEnumerateDomains %##s PID[%d](%s)", prefix, req->u.enumeration.q_all.qname.c, get_peer_pid(req->sd, pid_name), pid_name);
    else if (req->terminate == port_mapping_termination_callback)
        LogMsgNoIdent("%s DNSServiceNATPortMapping   %.4a %s%s Int %d Req %d Ext %d Req TTL %d Granted TTL %d PID[%d](%s)",
                      prefix,
                      &req->u.pm.NATinfo.ExternalAddress,
                      req->u.pm.NATinfo.Protocol & NATOp_MapTCP ? "TCP" : "   ",
                      req->u.pm.NATinfo.Protocol & NATOp_MapUDP ? "UDP" : "   ",
                      mDNSVal16(req->u.pm.NATinfo.IntPort),
                      mDNSVal16(req->u.pm.ReqExt),
                      mDNSVal16(req->u.pm.NATinfo.ExternalPort),
                      req->u.pm.NATinfo.NATLease,
                      req->u.pm.NATinfo.Lifetime,
		      get_peer_pid(req->sd, pid_name), pid_name);
    else if (req->terminate == addrinfo_termination_callback)
        LogMsgNoIdent("%s DNSServiceGetAddrInfo      %s%s %##s PID[%d](%s)", prefix,
                      req->u.addrinfo.protocol & kDNSServiceProtocol_IPv4 ? "v4" : "  ",
                      req->u.addrinfo.protocol & kDNSServiceProtocol_IPv6 ? "v6" : "  ",
                      req->u.addrinfo.q4.qname.c, get_peer_pid(req->sd, pid_name), pid_name);
    else
        LogMsgNoIdent("%s Unrecognized operation %p", prefix, req->terminate);
}

mDNSlocal char *RecordTypeName(mDNSu8 rtype)
{
    switch (rtype)
    {
    case kDNSRecordTypeUnregistered:  return ("Unregistered ");
    case kDNSRecordTypeDeregistering: return ("Deregistering");
    case kDNSRecordTypeUnique:        return ("Unique       ");
    case kDNSRecordTypeAdvisory:      return ("Advisory     ");
    case kDNSRecordTypeShared:        return ("Shared       ");
    case kDNSRecordTypeVerified:      return ("Verified     ");
    case kDNSRecordTypeKnownUnique:   return ("KnownUnique  ");
    default: return("Unknown");
    }
}

mDNSlocal void LogEtcHosts(mDNS *const m)
{
    mDNSBool showheader = mDNStrue;
    const AuthRecord *ar;
    mDNSu32 slot;
    AuthGroup *ag;
    int count = 0;
    int authslot = 0;
    mDNSBool truncated = 0;

    for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
    {
        if (m->rrauth.rrauth_hash[slot]) authslot++;
        for (ag = m->rrauth.rrauth_hash[slot]; ag; ag = ag->next)
            for (ar = ag->members; ar; ar = ar->next)
            {
                if (ar->RecordCallback != FreeEtcHosts) continue;
                if (showheader) { showheader = mDNSfalse; LogMsgNoIdent("  State       Interface"); }

                // Print a maximum of 50 records
                if (count++ >= 50) { truncated = mDNStrue; continue; }
                if (ar->ARType == AuthRecordLocalOnly)
                {
                    if (ar->resrec.InterfaceID == mDNSInterface_LocalOnly)
                        LogMsgNoIdent(" %s   LO %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
                    else
                    {
                        mDNSu32 scopeid  = (mDNSu32)(uintptr_t)ar->resrec.InterfaceID;
                        LogMsgNoIdent(" %s   %u  %s", RecordTypeName(ar->resrec.RecordType), scopeid, ARDisplayString(m, ar));
                    }
                }
                usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
            }
    }

    if (showheader) LogMsgNoIdent("<None>");
    else if (truncated) LogMsgNoIdent("<Truncated: to 50 records, Total records %d, Total Auth Groups %d, Auth Slots %d>", count, m->rrauth.rrauth_totalused, authslot);
}

mDNSlocal void LogLocalOnlyAuthRecords(mDNS *const m)
{
    mDNSBool showheader = mDNStrue;
    const AuthRecord *ar;
    mDNSu32 slot;
    AuthGroup *ag;

    for (slot = 0; slot < AUTH_HASH_SLOTS; slot++)
    {
        for (ag = m->rrauth.rrauth_hash[slot]; ag; ag = ag->next)
            for (ar = ag->members; ar; ar = ar->next)
            {
                if (ar->RecordCallback == FreeEtcHosts) continue;
                if (showheader) { showheader = mDNSfalse; LogMsgNoIdent("  State       Interface"); }

                // Print a maximum of 400 records
                if (ar->ARType == AuthRecordLocalOnly)
                    LogMsgNoIdent(" %s   LO %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
                else if (ar->ARType == AuthRecordP2P)
                    LogMsgNoIdent(" %s   PP %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
                usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
            }
    }

    if (showheader) LogMsgNoIdent("<None>");
}

mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *ResourceRecords, int *proxy)
{
    mDNSBool showheader = mDNStrue;
    const AuthRecord *ar;
    OwnerOptData owner = zeroOwner;
    for (ar = ResourceRecords; ar; ar=ar->next)
    {
        const char *const ifname = InterfaceNameForID(m, ar->resrec.InterfaceID);
        if ((ar->WakeUp.HMAC.l[0] != 0) == (proxy != mDNSNULL))
        {
            if (showheader) { showheader = mDNSfalse; LogMsgNoIdent("    Int    Next  Expire   State"); }
            if (proxy) (*proxy)++;
            if (!mDNSPlatformMemSame(&owner, &ar->WakeUp, sizeof(owner)))
            {
                owner = ar->WakeUp;
                if (owner.password.l[0])
                    LogMsgNoIdent("Proxying for H-MAC %.6a I-MAC %.6a Password %.6a seq %d", &owner.HMAC, &owner.IMAC, &owner.password, owner.seq);
                else if (!mDNSSameEthAddress(&owner.HMAC, &owner.IMAC))
                    LogMsgNoIdent("Proxying for H-MAC %.6a I-MAC %.6a seq %d",               &owner.HMAC, &owner.IMAC,                  owner.seq);
                else
                    LogMsgNoIdent("Proxying for %.6a seq %d",                                &owner.HMAC,                               owner.seq);
            }
            if (AuthRecord_uDNS(ar))
                LogMsgNoIdent("%7d %7d %7d %7d %s",
                              ar->ThisAPInterval / mDNSPlatformOneSecond,
                              (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
                              ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
                              ar->state, ARDisplayString(m, ar));
            else if (ar->ARType == AuthRecordLocalOnly)
                LogMsgNoIdent("                             LO %s", ARDisplayString(m, ar));
            else if (ar->ARType == AuthRecordP2P)
                LogMsgNoIdent("                             PP %s", ARDisplayString(m, ar));
            else
                LogMsgNoIdent("%7d %7d %7d %7s %s",
                              ar->ThisAPInterval / mDNSPlatformOneSecond,
                              ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
                              ar->TimeExpire    ? (ar->TimeExpire                      - now) / mDNSPlatformOneSecond : 0,
                              ifname ? ifname : "ALL",
                              ARDisplayString(m, ar));
            usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
        }
    }
    if (showheader) LogMsgNoIdent("<None>");
}

mDNSexport void udsserver_info(mDNS *const m)
{
    const mDNSs32 now = mDNS_TimeNow(m);
    mDNSu32 CacheUsed = 0, CacheActive = 0, slot;
    int ProxyA = 0, ProxyD = 0;
    const CacheGroup *cg;
    const CacheRecord *cr;
    const DNSQuestion *q;
    const DNameListElem *d;
    const SearchListElem *s;

    LogMsgNoIdent("Timenow 0x%08lX (%d)", (mDNSu32)now, now);

    LogMsgNoIdent("------------ Cache -------------");
    LogMsgNoIdent("Slt Q     TTL if     U Type rdlen");
    for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
        for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
        {
            CacheUsed++;    // Count one cache entity for the CacheGroup object
            for (cr = cg->members; cr; cr=cr->next)
            {
                const mDNSs32 remain = cr->resrec.rroriginalttl - (now - cr->TimeRcvd) / mDNSPlatformOneSecond;
                const char *ifname;
                CacheRecord *nsec;
                mDNSInterfaceID InterfaceID = cr->resrec.InterfaceID;
                if (!InterfaceID && cr->resrec.rDNSServer && cr->resrec.rDNSServer->scoped)
                    InterfaceID = cr->resrec.rDNSServer->interface;
                ifname = InterfaceNameForID(m, InterfaceID);
                CacheUsed++;
                if (cr->CRActiveQuestion) CacheActive++;
                LogMsgNoIdent("%3d %s%8d %-7s%s %-6s%s",
                              slot,
                              cr->CRActiveQuestion ? "*" : " ",
                              remain,
                              ifname ? ifname : "-U-",
                              (cr->resrec.RecordType == kDNSRecordTypePacketNegative)  ? "-" :
                              (cr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? " " : "+",
                              DNSTypeName(cr->resrec.rrtype),
                              CRDisplayString(m, cr));
                nsec = cr->nsec;
                while (nsec)
                {
                    LogMsgNoIdent("%3d %s%8d %-7s%s %-6s%s",
                                  slot,
                                  nsec->CRActiveQuestion ? "*" : " ",
                                  remain,
                                  ifname ? ifname : "-U-",
                                  (nsec->resrec.RecordType == kDNSRecordTypePacketNegative)  ? "-" :
                                  (nsec->resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? " " : "+",
                                  DNSTypeName(nsec->resrec.rrtype),
                                  CRDisplayString(m, nsec));
                    CacheUsed++;
                    nsec = nsec->next;
                }
                usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
            }
        }

    if (m->rrcache_totalused != CacheUsed)
        LogMsgNoIdent("Cache use mismatch: rrcache_totalused is %lu, true count %lu", m->rrcache_totalused, CacheUsed);
    if (m->rrcache_active != CacheActive)
        LogMsgNoIdent("Cache use mismatch: rrcache_active is %lu, true count %lu", m->rrcache_active, CacheActive);
    LogMsgNoIdent("Cache currently contains %lu entities; %lu referenced by active questions", CacheUsed, CacheActive);

    LogMsgNoIdent("--------- Auth Records ---------");
    LogAuthRecords(m, now, m->ResourceRecords, mDNSNULL);

    LogMsgNoIdent("--------- LocalOnly, P2P Auth Records ---------");
    LogLocalOnlyAuthRecords(m);

    LogMsgNoIdent("--------- /etc/hosts ---------");
    LogEtcHosts(m);

    LogMsgNoIdent("------ Duplicate Records -------");
    LogAuthRecords(m, now, m->DuplicateRecords, mDNSNULL);

    LogMsgNoIdent("----- Auth Records Proxied -----");
    LogAuthRecords(m, now, m->ResourceRecords, &ProxyA);

    LogMsgNoIdent("-- Duplicate Records Proxied ---");
    LogAuthRecords(m, now, m->DuplicateRecords, &ProxyD);

    LogMsgNoIdent("---------- Questions -----------");
    if (!m->Questions) LogMsgNoIdent("<None>");
    else
    {
        CacheUsed = 0;
        CacheActive = 0;
        LogMsgNoIdent("   Int  Next if     T  NumAns VDNS    Qptr     DupOf    SU SQ Type Name");
        for (q = m->Questions; q; q=q->next)
        {
            mDNSs32 i = q->ThisQInterval / mDNSPlatformOneSecond;
            mDNSs32 n = (NextQSendTime(q) - now) / mDNSPlatformOneSecond;
            char *ifname = InterfaceNameForID(m, q->InterfaceID);
            CacheUsed++;
            if (q->ThisQInterval) CacheActive++;
            LogMsgNoIdent("%6d%6d %-7s%s%s %5d 0x%x%x 0x%p 0x%p %1d %2d %-5s%##s%s",
                          i, n,
                          ifname ? ifname : mDNSOpaque16IsZero(q->TargetQID) ? "" : "-U-",
                          mDNSOpaque16IsZero(q->TargetQID) ? (q->LongLived ? "l" : " ") : (q->LongLived ? "L" : "O"),
                          PrivateQuery(q)    ? "P" : q->ValidationRequired ? "V" : q->ValidatingResponse ? "R" : " ",
                          q->CurrentAnswers, q->validDNSServers.l[1], q->validDNSServers.l[0], q, q->DuplicateOf,
                          q->SuppressUnusable, q->SuppressQuery, DNSTypeName(q->qtype), q->qname.c, q->DuplicateOf ? " (dup)" : "");
            usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
        }
        LogMsgNoIdent("%lu question%s; %lu active", CacheUsed, CacheUsed > 1 ? "s" : "", CacheActive);
    }

    LogMsgNoIdent("----- Local-Only Questions -----");
    if (!m->LocalOnlyQuestions) LogMsgNoIdent("<None>");
    else for (q = m->LocalOnlyQuestions; q; q=q->next)
            LogMsgNoIdent("                       %5d  %-6s%##s%s",
                          q->CurrentAnswers, DNSTypeName(q->qtype), q->qname.c, q->DuplicateOf ? " (dup)" : "");

    LogMsgNoIdent("---- Active Client Requests ----");
    if (!all_requests) LogMsgNoIdent("<None>");
    else
    {
        const request_state *req, *r;
        for (req = all_requests; req; req=req->next)
        {
            if (req->primary)   // If this is a subbordinate operation, check that the parent is in the list
            {
                for (r = all_requests; r && r != req; r=r->next) if (r == req->primary) goto foundparent;
                LogMsgNoIdent("%3d: Orhpan operation %p; parent %p not found in request list", req->sd);
            }
            // For non-subbordinate operations, and subbordinate operations that have lost their parent, write out their info
            LogClientInfo(m, req);
foundparent:;
        }
    }

    LogMsgNoIdent("-------- NAT Traversals --------");
    if (!m->NATTraversals) LogMsgNoIdent("<None>");
    else
    {
        const NATTraversalInfo *nat;
        for (nat = m->NATTraversals; nat; nat=nat->next)
        {
            if (nat->Protocol)
                LogMsgNoIdent("%p %s Int %5d Ext %5d Err %d Retry %5d Interval %5d Expire %5d",
                              nat, nat->Protocol == NATOp_MapTCP ? "TCP" : "UDP",
                              mDNSVal16(nat->IntPort), mDNSVal16(nat->ExternalPort), nat->Result,
                              nat->retryPortMap ? (nat->retryPortMap - now) / mDNSPlatformOneSecond : 0,
                              nat->retryInterval / mDNSPlatformOneSecond,
                              nat->ExpiryTime ? (nat->ExpiryTime - now) / mDNSPlatformOneSecond : 0);
            else
                LogMsgNoIdent("%p Address Request               Retry %5d Interval %5d", nat,
                              (m->retryGetAddr - now) / mDNSPlatformOneSecond,
                              m->retryIntervalGetAddr / mDNSPlatformOneSecond);
            usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
        }
    }

    LogMsgNoIdent("--------- AuthInfoList ---------");
    if (!m->AuthInfoList) LogMsgNoIdent("<None>");
    else
    {
        const DomainAuthInfo *a;
        for (a = m->AuthInfoList; a; a = a->next)
        {
            LogMsgNoIdent("%##s %##s %##s %d %d %.16a%s",
                          a->domain.c, a->keyname.c,
                          a->hostname.c, (a->port.b[0] << 8 | a->port.b[1]),
                          (a->deltime ? (a->deltime - now) : 0),
                          &a->AutoTunnelInnerAddress, a->AutoTunnel ? " AutoTunnel" : "");
        }
    }

    #if APPLE_OSX_mDNSResponder
    LogMsgNoIdent("--------- TunnelClients --------");
    if (!m->TunnelClients) LogMsgNoIdent("<None>");
    else
    {
        const ClientTunnel *c;
        for (c = m->TunnelClients; c; c = c->next)
            LogMsgNoIdent("%##s local %.16a %.4a %.16a remote %.16a %.4a %5d %.16a interval %d",
                          c->dstname.c, &c->loc_inner, &c->loc_outer, &c->loc_outer6, &c->rmt_inner, &c->rmt_outer, mDNSVal16(c->rmt_outer_port), &c->rmt_outer6, c->q.ThisQInterval);
    }
    #endif // APPLE_OSX_mDNSResponder

    LogMsgNoIdent("---------- Misc State ----------");

    LogMsgNoIdent("PrimaryMAC:   %.6a", &m->PrimaryMAC);

    LogMsgNoIdent("m->SleepState %d (%s) seq %d",
                  m->SleepState,
                  m->SleepState == SleepState_Awake        ? "Awake"        :
                  m->SleepState == SleepState_Transferring ? "Transferring" :
                  m->SleepState == SleepState_Sleeping     ? "Sleeping"     : "?",
                  m->SleepSeqNum);

    LogMsgNoIdent("m->clearIgnoreNA %d", m->clearIgnoreNA);

    if (!m->SPSSocket) LogMsgNoIdent("Not offering Sleep Proxy Service");
    else LogMsgNoIdent("Offering Sleep Proxy Service: %#s", m->SPSRecords.RR_SRV.resrec.name->c);

    if (m->ProxyRecords == ProxyA + ProxyD) LogMsgNoIdent("ProxyRecords: %d + %d = %d", ProxyA, ProxyD, ProxyA + ProxyD);
    else LogMsgNoIdent("ProxyRecords: MISMATCH %d + %d = %d ≠ %d", ProxyA, ProxyD, ProxyA + ProxyD, m->ProxyRecords);

    LogMsgNoIdent("------ Auto Browse Domains -----");
    if (!AutoBrowseDomains) LogMsgNoIdent("<None>");
    else for (d=AutoBrowseDomains; d; d=d->next) LogMsgNoIdent("%##s", d->name.c);

    LogMsgNoIdent("--- Auto Registration Domains --");
    if (!AutoRegistrationDomains) LogMsgNoIdent("<None>");
    else for (d=AutoRegistrationDomains; d; d=d->next) LogMsgNoIdent("%##s", d->name.c);

    LogMsgNoIdent("--- Search Domains --");
    if (!SearchList) LogMsgNoIdent("<None>");
    else
    {
        for (s=SearchList; s; s=s->next)
        {
            char *ifname = InterfaceNameForID(m, s->InterfaceID);
            LogMsgNoIdent("%##s %s", s->domain.c, ifname ? ifname : "");
        }
    }
    LogMsgNoIdent("--- Trust Anchors --");
    if (!m->TrustAnchors) LogMsgNoIdent("<None>");
    else
    {
        TrustAnchor *ta;
        mDNSu8 fromTimeBuf[64];
        mDNSu8 untilTimeBuf[64];

        for (ta=m->TrustAnchors; ta; ta=ta->next)
        {
            mDNSPlatformFormatTime((unsigned long)ta->validFrom, fromTimeBuf, sizeof(fromTimeBuf));
            mDNSPlatformFormatTime((unsigned long)ta->validUntil, untilTimeBuf, sizeof(untilTimeBuf));
            LogMsgNoIdent("%##s %d %d %d %d %s %s", ta->zone.c, ta->rds.keyTag,
                ta->rds.alg, ta->rds.digestType, ta->digestLen, fromTimeBuf, untilTimeBuf);
        }
    }

    LogMsgNoIdent("---- Task Scheduling Timers ----");

    if (!m->NewQuestions)
        LogMsgNoIdent("NewQuestion <NONE>");
    else
        LogMsgNoIdent("NewQuestion DelayAnswering %d %d %##s (%s)",
                      m->NewQuestions->DelayAnswering, m->NewQuestions->DelayAnswering-now,
                      m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));

    if (!m->NewLocalOnlyQuestions)
        LogMsgNoIdent("NewLocalOnlyQuestions <NONE>");
    else
        LogMsgNoIdent("NewLocalOnlyQuestions %##s (%s)",
                      m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));

    if (!m->NewLocalRecords)
        LogMsgNoIdent("NewLocalRecords <NONE>");
    else
        LogMsgNoIdent("NewLocalRecords %02X %s", m->NewLocalRecords->resrec.RecordType, ARDisplayString(m, m->NewLocalRecords));

    LogMsgNoIdent("SPSProxyListChanged%s", m->SPSProxyListChanged ? "" : " <NONE>");
    LogMsgNoIdent("LocalRemoveEvents%s",   m->LocalRemoveEvents   ? "" : " <NONE>");
    LogMsgNoIdent("m->AutoTunnelRelayAddr %.16a", &m->AutoTunnelRelayAddr);

#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d  %08X %11d", (T), (T), (T)-now, (T)-now)

    LogMsgNoIdent("                         ABS (hex)  ABS (dec)  REL (hex)  REL (dec)");
    LogMsgNoIdent("m->timenow               %08X %11d", now, now);
    LogMsgNoIdent("m->timenow_adjust        %08X %11d", m->timenow_adjust, m->timenow_adjust);
    LogTimer("m->NextScheduledEvent   ", m->NextScheduledEvent);

#ifndef UNICAST_DISABLED
    LogTimer("m->NextuDNSEvent        ", m->NextuDNSEvent);
    LogTimer("m->NextSRVUpdate        ", m->NextSRVUpdate);
    LogTimer("m->NextScheduledNATOp   ", m->NextScheduledNATOp);
    LogTimer("m->retryGetAddr         ", m->retryGetAddr);
#endif

    LogTimer("m->NextCacheCheck       ", m->NextCacheCheck);
    LogTimer("m->NextScheduledSPS     ", m->NextScheduledSPS);
    LogTimer("m->NextScheduledKA      ", m->NextScheduledKA);
    LogTimer("m->NextScheduledSPRetry ", m->NextScheduledSPRetry);
    LogTimer("m->DelaySleep           ", m->DelaySleep);

    LogTimer("m->NextScheduledQuery   ", m->NextScheduledQuery);
    LogTimer("m->NextScheduledProbe   ", m->NextScheduledProbe);
    LogTimer("m->NextScheduledResponse", m->NextScheduledResponse);

    LogTimer("m->SuppressSending      ", m->SuppressSending);
    LogTimer("m->SuppressProbes       ", m->SuppressProbes);
    LogTimer("m->ProbeFailTime        ", m->ProbeFailTime);
    LogTimer("m->DelaySleep           ", m->DelaySleep);
    LogTimer("m->SleepLimit           ", m->SleepLimit);
    LogTimer("m->NextScheduledStopTime ", m->NextScheduledStopTime);
}

#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
mDNSexport void uds_validatelists(void)
{
    const request_state *req, *p;
    for (req = all_requests; req; req=req->next)
    {
        if (req->next == (request_state *)~0 || (req->sd < 0 && req->sd != -2))
            LogMemCorruption("UDS request list: %p is garbage (%d)", req, req->sd);

        if (req->primary == req)
            LogMemCorruption("UDS request list: req->primary should not point to self %p/%d", req, req->sd);

        if (req->primary && req->replies)
            LogMemCorruption("UDS request list: Subordinate request %p/%d/%p should not have replies (%p)",
                             req, req->sd, req->primary && req->replies);

        p = req->primary;
        if ((long)p & 3)
            LogMemCorruption("UDS request list: req %p primary %p is misaligned (%d)", req, p, req->sd);
        else if (p && (p->next == (request_state *)~0 || (p->sd < 0 && p->sd != -2)))
            LogMemCorruption("UDS request list: req %p primary %p is garbage (%d)", req, p, p->sd);

        reply_state *rep;
        for (rep = req->replies; rep; rep=rep->next)
            if (rep->next == (reply_state *)~0)
                LogMemCorruption("UDS req->replies: %p is garbage", rep);

        if (req->terminate == connection_termination)
        {
            registered_record_entry *r;
            for (r = req->u.reg_recs; r; r=r->next)
                if (r->next == (registered_record_entry *)~0)
                    LogMemCorruption("UDS req->u.reg_recs: %p is garbage", r);
        }
        else if (req->terminate == regservice_termination_callback)
        {
            service_instance *s;
            for (s = req->u.servicereg.instances; s; s=s->next)
                if (s->next == (service_instance *)~0)
                    LogMemCorruption("UDS req->u.servicereg.instances: %p is garbage", s);
        }
        else if (req->terminate == browse_termination_callback)
        {
            browser_t *b;
            for (b = req->u.browser.browsers; b; b=b->next)
                if (b->next == (browser_t *)~0)
                    LogMemCorruption("UDS req->u.browser.browsers: %p is garbage", b);
        }
    }

    DNameListElem *d;
    for (d = SCPrefBrowseDomains; d; d=d->next)
        if (d->next == (DNameListElem *)~0 || d->name.c[0] > 63)
            LogMemCorruption("SCPrefBrowseDomains: %p is garbage (%d)", d, d->name.c[0]);

    ARListElem *b;
    for (b = LocalDomainEnumRecords; b; b=b->next)
        if (b->next == (ARListElem *)~0 || b->ar.resrec.name->c[0] > 63)
            LogMemCorruption("LocalDomainEnumRecords: %p is garbage (%d)", b, b->ar.resrec.name->c[0]);

    for (d = AutoBrowseDomains; d; d=d->next)
        if (d->next == (DNameListElem *)~0 || d->name.c[0] > 63)
            LogMemCorruption("AutoBrowseDomains: %p is garbage (%d)", d, d->name.c[0]);

    for (d = AutoRegistrationDomains; d; d=d->next)
        if (d->next == (DNameListElem *)~0 || d->name.c[0] > 63)
            LogMemCorruption("AutoRegistrationDomains: %p is garbage (%d)", d, d->name.c[0]);
}
#endif // APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING

mDNSlocal int send_msg(request_state *const req)
{
    reply_state *const rep = req->replies;      // Send the first waiting reply
    ssize_t nwriten;
    if (req->no_reply) return(t_complete);

    ConvertHeaderBytes(rep->mhdr);
    nwriten = send(req->sd, (char *)&rep->mhdr + rep->nwriten, rep->totallen - rep->nwriten, 0);
    ConvertHeaderBytes(rep->mhdr);

    if (nwriten < 0)
    {
        if (dnssd_errno == dnssd_EINTR || dnssd_errno == dnssd_EWOULDBLOCK) nwriten = 0;
        else
        {
#if !defined(PLATFORM_NO_EPIPE)
            if (dnssd_errno == EPIPE)
                return(req->ts = t_terminated);
            else
#endif
            {
                LogMsg("send_msg ERROR: failed to write %d of %d bytes to fd %d errno %d (%s)",
                       rep->totallen - rep->nwriten, rep->totallen, req->sd, dnssd_errno, dnssd_strerror(dnssd_errno));
                return(t_error);
            }
        }
    }
    rep->nwriten += nwriten;
    return (rep->nwriten == rep->totallen) ? t_complete : t_morecoming;
}

mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
{
    mDNSs32 now = mDNS_TimeNow(&mDNSStorage);
    request_state **req = &all_requests;

    while (*req)
    {
        request_state *const r = *req;

        if (r->terminate == resolve_termination_callback)
            if (r->u.resolve.ReportTime && now - r->u.resolve.ReportTime >= 0)
            {
                r->u.resolve.ReportTime = 0;
                LogMsgNoIdent("Client application bug PID[%d](%s) : DNSServiceResolve(%##s) active for over two minutes. "
                              "This places considerable burden on the network.", get_peer_pid(r->sd, pid_name), pid_name, r->u.resolve.qsrv.qname.c);
            }

        // Note: Only primary req's have reply lists, not subordinate req's.
        while (r->replies)      // Send queued replies
        {
            transfer_state result;
            if (r->replies->next) 
                r->replies->rhdr->flags |= dnssd_htonl(kDNSServiceFlagsMoreComing);
            result = send_msg(r);   // Returns t_morecoming if buffer full because client is not reading
            if (result == t_complete)
            {
                reply_state *fptr = r->replies;
                r->replies = r->replies->next;
                freeL("reply_state/udsserver_idle", fptr);
                r->time_blocked = 0; // reset failure counter after successful send
                r->unresponsiveness_reports = 0;
                continue;
            }
            else if (result == t_terminated || result == t_error)
            {
                LogMsg("%3d: Could not write data to clientPID[%d](%s)  because of error - aborting connection", r->sd, get_peer_pid(r->sd, pid_name), pid_name);
                LogClientInfo(&mDNSStorage, r);
                abort_request(r);
            }
            break;
        }

        if (r->replies)     // If we failed to send everything, check our time_blocked timer
        {
            if (nextevent - now > mDNSPlatformOneSecond) 
                nextevent = now + mDNSPlatformOneSecond;

            if (mDNSStorage.SleepState != SleepState_Awake) 
                r->time_blocked = 0;
            else if (!r->time_blocked) 
                r->time_blocked = NonZeroTime(now);
            else if (now - r->time_blocked >= 10 * mDNSPlatformOneSecond * (r->unresponsiveness_reports+1))
            {
                int num = 0;
                struct reply_state *x = r->replies;
                while (x) 
                { 
                    num++; 
                    x=x->next; 
                }
                LogMsg("%3d: Could not write data to client PID[%d](%s) after %ld seconds, %d repl%s waiting",
                       r->sd, get_peer_pid(r->sd, pid_name), pid_name, (now - r->time_blocked) / mDNSPlatformOneSecond, num, num == 1 ? "y" : "ies");
                if (++r->unresponsiveness_reports >= 60)
                {
                    LogMsg("%3d: Client PID[%d](%s) unresponsive; aborting connection", r->sd, get_peer_pid(r->sd, pid_name), pid_name);
                    LogClientInfo(&mDNSStorage, r);
                    abort_request(r);
                }
            }
        }

        if (!dnssd_SocketValid(r->sd)) // If this request is finished, unlink it from the list and free the memory
        {
            // Since we're already doing a list traversal, we unlink the request directly instead of using AbortUnlinkAndFree()
            *req = r->next;
            freeL("request_state/udsserver_idle", r);
        }
        else
            req = &r->next;
    }
    return nextevent;
}

struct CompileTimeAssertionChecks_uds_daemon
{
    // Check our structures are reasonable sizes. Including overly-large buffers, or embedding
    // other overly-large structures instead of having a pointer to them, can inadvertently
    // cause structure sizes (and therefore memory usage) to balloon unreasonably.
    char sizecheck_request_state          [(sizeof(request_state)           <= 2000) ? 1 : -1];
    char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <=   60) ? 1 : -1];
    char sizecheck_service_instance       [(sizeof(service_instance)        <= 6552) ? 1 : -1];
    char sizecheck_browser_t              [(sizeof(browser_t)               <= 1050) ? 1 : -1];
    char sizecheck_reply_hdr              [(sizeof(reply_hdr)               <=   12) ? 1 : -1];
    char sizecheck_reply_state            [(sizeof(reply_state)             <=   64) ? 1 : -1];
};
