147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* -*- Mode: C; tab-width: 4 -*-
247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License");
647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * you may not use this file except in compliance with the License.
747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * You may obtain a copy of the License at
847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *     http://www.apache.org/licenses/LICENSE-2.0
1047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
1147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Unless required by applicable law or agreed to in writing, software
1247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS,
1347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * See the License for the specific language governing permissions and
1547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * limitations under the License.
1647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
1747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This file defines a simple shim layer between a client calling the "/usr/include/dns_sd.h" APIs
1847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * and an implementation of mDNSCore ("mDNSEmbeddedAPI.h" APIs) in the same address space.
1947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * When the client calls a dns_sd.h function, the shim calls the corresponding mDNSEmbeddedAPI.h
2047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * function, and when mDNSCore calls the shim's callback, we call through to the client's callback.
2147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * The shim is responsible for two main things:
2247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * - converting string parameters between C string format and native DNS format,
2347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * - and for allocating and freeing memory.
2447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
2547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
2647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "dns_sd.h"				// Defines the interface to the client layer above
2747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "mDNSEmbeddedAPI.h"		// The interface we're building on top of
280b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon#include <sys/socket.h>
290b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon#include <netinet/in.h>
300b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon
3147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltextern mDNS mDNSStorage;		// We need to pass the address of this storage to the lower-layer functions
3247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
3347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
3447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#pragma export on
3547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
3647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
3747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
3847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// General Utility Functions
3947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// All mDNS_DirectOP structures start with the pointer to the type-specific disposal function.
4147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Optional type-specific data follows these three fields
4247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// When the client starts an operation, we return the address of the corresponding mDNS_DirectOP
4347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// as the DNSServiceRef for the operation
4447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// We stash the value in core context fields so we can get it back to recover our state in our callbacks,
4547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// and pass it though to the client for it to recover its state
4647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct mDNS_DirectOP_struct mDNS_DirectOP;
4847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef void mDNS_DirectOP_Dispose(mDNS_DirectOP *op);
4947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct mDNS_DirectOP_struct
5047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
5147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Dispose  *disposefn;
5247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	};
5347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
5447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct
5547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
5647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Dispose  *disposefn;
5747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRegisterReply callback;
5847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                   *context;
5947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSBool                autoname;		// Set if this name is tied to the Computer Name
6047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSBool                autorename;		// Set if we just got a name conflict and now need to automatically pick a new name
6147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainlabel             name;
6247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainname              host;
6347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ServiceRecordSet        s;
6447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	} mDNS_DirectOP_Register;
6547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
6647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct
6747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
6847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Dispose  *disposefn;
6947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceBrowseReply   callback;
7047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                   *context;
7147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSQuestion             q;
7247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	} mDNS_DirectOP_Browse;
7347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
7447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct
7547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
760b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	mDNS_DirectOP_Dispose        *disposefn;
770b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	DNSServiceRef                aQuery;
780b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	DNSServiceGetAddrInfoReply   callback;
790b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon  	void                         *context;
800b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	} mDNS_DirectOP_GetAddrInfo;
810b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon
820b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcontypedef struct
830b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	{
8447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Dispose  *disposefn;
8547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceResolveReply  callback;
8647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                   *context;
8747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const ResourceRecord   *SRV;
8847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const ResourceRecord   *TXT;
8947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSQuestion             qSRV;
9047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSQuestion             qTXT;
9147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	} mDNS_DirectOP_Resolve;
9247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
9347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct
9447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
9547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Dispose      *disposefn;
9647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceQueryRecordReply  callback;
9747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                       *context;
9847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSQuestion                 q;
9947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	} mDNS_DirectOP_QueryRecord;
10047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
10147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint DNSServiceRefSockFD(DNSServiceRef sdRef)
10247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
10347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;	// Unused
10447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(0);
10547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
10647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
10747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceProcessResult(DNSServiceRef sdRef)
10847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
10947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;	// Unused
11047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_NoError);
11147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
11247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
11347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid DNSServiceRefDeallocate(DNSServiceRef sdRef)
11447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
11547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP *op = (mDNS_DirectOP *)sdRef;
11647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	//LogMsg("DNSServiceRefDeallocate");
11747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	op->disposefn(op);
11847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
11947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
12047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
12147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Domain Enumeration
12247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
12347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Not yet implemented, so don't include in stub library
12447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// We DO include it in the actual Extension, so that if a later client compiled to use this
12547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// is run against this Extension, it will get a reasonable error code instead of just
12647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
12747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !MDNS_BUILDINGSTUBLIBRARY
12847e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceEnumerateDomains
12947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
13047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       *sdRef,
13147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
13247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            interfaceIndex,
13347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceDomainEnumReply           callback,
13447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                                *context  /* may be NULL */
13547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
13647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
13747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;			// Unused
13847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
13947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
14047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)callback;			// Unused
14147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)context;			// Unused
14247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
14347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
14447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
14547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
14647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
14747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Register Service
14847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
14947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void FreeDNSServiceRegistration(mDNS_DirectOP_Register *x)
15047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
15147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	while (x->s.Extras)
15247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
15347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ExtraResourceRecord *extras = x->s.Extras;
15447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		x->s.Extras = x->s.Extras->next;
15547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (extras->r.resrec.rdata != &extras->r.rdatastorage)
15647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			mDNSPlatformMemFree(extras->r.resrec.rdata);
15747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		mDNSPlatformMemFree(extras);
15847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
15947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
16047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->s.RR_TXT.resrec.rdata != &x->s.RR_TXT.rdatastorage)
16147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			mDNSPlatformMemFree(x->s.RR_TXT.resrec.rdata);
16247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
16347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->s.SubTypes) mDNSPlatformMemFree(x->s.SubTypes);
16447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
16547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemFree(x);
16647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
16747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
16847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void DNSServiceRegisterDispose(mDNS_DirectOP *op)
16947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
17047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Register *x = (mDNS_DirectOP_Register*)op;
17147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->autorename = mDNSfalse;
17247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// If mDNS_DeregisterService() returns mStatus_NoError, that means that the service was found in the list,
17347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// is sending its goodbye packet, and we'll get an mStatus_MemFree message when we can free the memory.
17447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// If mDNS_DeregisterService() returns an error, it means that the service had already been removed from
17547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// the list, so we should go ahead and free the memory right now
17647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (mDNS_DeregisterService(&mDNSStorage, &x->s) != mStatus_NoError)
17747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		FreeDNSServiceRegistration(x);
17847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
17947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void RegCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus result)
18147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
18247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Register *x = (mDNS_DirectOP_Register*)sr->ServiceContext;
18347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    domainlabel name;
18547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    domainname type, dom;
18647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char namestr[MAX_DOMAIN_LABEL+1];		// Unescaped name: up to 63 bytes plus C-string terminating NULL.
18747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char typestr[MAX_ESCAPED_DOMAIN_NAME];
18847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char domstr [MAX_ESCAPED_DOMAIN_NAME];
18947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    if (!DeconstructServiceName(sr->RR_SRV.resrec.name, &name, &type, &dom)) return;
19047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    if (!ConvertDomainLabelToCString_unescaped(&name, namestr)) return;
19147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    if (!ConvertDomainNameToCString(&type, typestr)) return;
19247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    if (!ConvertDomainNameToCString(&dom, domstr)) return;
19347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
19447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (result == mStatus_NoError)
19547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
19647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (x->callback)
19747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			x->callback((DNSServiceRef)x, 0, result, namestr, typestr, domstr, x->context);
19847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
19947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	else if (result == mStatus_NameConflict)
20047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
2010b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon			if (x->autoname) mDNS_RenameAndReregisterService(m, sr, mDNSNULL);
2020b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon			else if (x->autorename) {
2030b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon				IncrementLabelSuffix(&x->name, mDNStrue);
2040b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon				mDNS_RenameAndReregisterService(m, &x->s, &x->name);
2050b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon			}
2060b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon			else if (x->callback)
20747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				x->callback((DNSServiceRef)x, 0, result, namestr, typestr, domstr, x->context);
20847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
20947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	else if (result == mStatus_MemFree)
21047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
21147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (x->autorename)
21247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
21347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			x->autorename = mDNSfalse;
21447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			x->name = mDNSStorage.nicelabel;
21547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			mDNS_RenameAndReregisterService(m, &x->s, &x->name);
21647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
21747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		else
21847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			FreeDNSServiceRegistration(x);
21947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
22047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
22147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
22247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceRegister
22347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
22447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       *sdRef,
22547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
22647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            interfaceIndex,
22747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *name,         /* may be NULL */
22847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *regtype,
22947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *domain,       /* may be NULL */
23047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *host,         /* may be NULL */
23147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            notAnIntPort,
23247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            txtLen,
23347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const void                          *txtRecord,    /* may be NULL */
23447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRegisterReply             callback,      /* may be NULL */
23547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                                *context       /* may be NULL */
23647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
23747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
23847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mStatus err = mStatus_NoError;
23947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *errormsg = "Unknown";
24047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainlabel n;
24147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainname t, d, h, srv;
24247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSIPPort port;
24347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	unsigned int size = sizeof(RDataBody);
24447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	AuthRecord *SubTypes = mDNSNULL;
24547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 NumSubTypes = 0;
24647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Register *x;
24747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
24847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
24947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
25047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Check parameters
25147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!name) name = "";
25247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!name[0]) n = mDNSStorage.nicelabel;
25347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	else if (!MakeDomainLabelFromLiteralString(&n, name))                              { errormsg = "Bad Instance Name"; goto badparam; }
25447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!regtype || !*regtype || !MakeDomainNameFromDNSNameString(&t, regtype))        { errormsg = "Bad Service Type";  goto badparam; }
25547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!MakeDomainNameFromDNSNameString(&d, (domain && *domain) ? domain : "local.")) { errormsg = "Bad Domain";        goto badparam; }
25647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!MakeDomainNameFromDNSNameString(&h, (host   && *host  ) ? host   : ""))       { errormsg = "Bad Target Host";   goto badparam; }
25747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!ConstructServiceName(&srv, &n, &t, &d))                                       { errormsg = "Bad Name";          goto badparam; }
25847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	port.NotAnInteger = notAnIntPort;
25947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
26047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Allocate memory, and handle failure
26147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (size < txtLen)
26247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		size = txtLen;
26347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x = (mDNS_DirectOP_Register *)mDNSPlatformMemAllocate(sizeof(*x) - sizeof(RDataBody) + size);
26447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
26547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
26647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Set up object
26747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->disposefn = DNSServiceRegisterDispose;
26847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback  = callback;
26947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->context   = context;
27047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->autoname = (!name[0]);
2710b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	x->autorename = !(flags & kDNSServiceFlagsNoAutoRename);
27247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->name = n;
27347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->host = h;
27447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
27547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Do the operation
27647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mDNS_RegisterService(&mDNSStorage, &x->s,
27747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		&x->name, &t, &d,		// Name, type, domain
27847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		&x->host, port,			// Host and port
27947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		txtRecord, txtLen,		// TXT data, length
28047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		SubTypes, NumSubTypes,	// Subtypes
28147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		mDNSInterface_Any,		// Interface ID
28247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		RegCallback, x, 0);		// Callback, context, flags
28347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_RegisterService"; goto fail; }
28447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
28547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Succeeded: Wrap up and return
28647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	*sdRef = (DNSServiceRef)x;
28747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(mStatus_NoError);
28847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
28947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltbadparam:
29047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mStatus_BadParamErr;
29147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfail:
29247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
29347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(err);
29447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
29547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
29647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
29747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Add / Update / Remove records from existing Registration
29847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
29947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Not yet implemented, so don't include in stub library
30047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// We DO include it in the actual Extension, so that if a later client compiled to use this
30147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// is run against this Extension, it will get a reasonable error code instead of just
30247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
30347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !MDNS_BUILDINGSTUBLIBRARY
30447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceAddRecord
30547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
30647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       sdRef,
30747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSRecordRef                        *RecordRef,
30847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
30947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rrtype,
31047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rdlen,
31147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const void                          *rdata,
31247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            ttl
31347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
31447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
31547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;		// Unused
31647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)RecordRef;	// Unused
31747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;		// Unused
31847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rrtype;		// Unused
31947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdlen;		// Unused
32047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdata;		// Unused
32147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)ttl;			// Unused
32247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
32347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
32447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
32547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceUpdateRecord
32647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
32747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       sdRef,
32847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSRecordRef                        RecordRef,     /* may be NULL */
32947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
33047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rdlen,
33147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const void                          *rdata,
33247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            ttl
33347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
33447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
33547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;		// Unused
33647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)RecordRef;	// Unused
33747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;		// Unused
33847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdlen;		// Unused
33947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdata;		// Unused
34047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)ttl;			// Unused
34147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
34247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
34347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
34447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceRemoveRecord
34547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
34647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                 sdRef,
34747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSRecordRef                  RecordRef,
34847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags               flags
34947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
35047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
35147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;		// Unused
35247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)RecordRef;	// Unused
35347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;		// Unused
35447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
35547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
35647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
35747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
35847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
35947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Browse for services
36047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
36147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void DNSServiceBrowseDispose(mDNS_DirectOP *op)
36247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
36347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Browse *x = (mDNS_DirectOP_Browse*)op;
36447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	//LogMsg("DNSServiceBrowseDispose");
36547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_StopBrowse(&mDNSStorage, &x->q);
36647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemFree(x);
36747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
36847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
36947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
37047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
37147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags flags = AddRecord ? kDNSServiceFlagsAdd : (DNSServiceFlags)0;
37247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainlabel name;
37347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainname type, domain;
37447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char cname[MAX_DOMAIN_LABEL+1];			// Unescaped name: up to 63 bytes plus C-string terminating NULL.
37547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char ctype[MAX_ESCAPED_DOMAIN_NAME];
37647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char cdom [MAX_ESCAPED_DOMAIN_NAME];
37747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Browse *x = (mDNS_DirectOP_Browse*)question->QuestionContext;
37847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)m;		// Unused
37947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
38047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (answer->rrtype != kDNSType_PTR)
38147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{ LogMsg("FoundInstance: Should not be called with rrtype %d (not a PTR record)", answer->rrtype); return; }
38247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
38347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!DeconstructServiceName(&answer->rdata->u.name, &name, &type, &domain))
38447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
38547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		LogMsg("FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer",
38647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			answer->name->c, answer->rdata->u.name.c);
38747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		return;
38847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
38947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
39047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ConvertDomainLabelToCString_unescaped(&name, cname);
39147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ConvertDomainNameToCString(&type, ctype);
39247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ConvertDomainNameToCString(&domain, cdom);
39347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->callback)
39447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		x->callback((DNSServiceRef)x, flags, 0, 0, cname, ctype, cdom, x->context);
39547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
39647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
39747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceBrowse
39847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
39947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       *sdRef,
40047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
40147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            interfaceIndex,
40247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *regtype,
40347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *domain,    /* may be NULL */
40447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceBrowseReply               callback,
40547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                                *context    /* may be NULL */
40647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
40747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
40847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mStatus err = mStatus_NoError;
40947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *errormsg = "Unknown";
41047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainname t, d;
41147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Browse *x;
41247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
41347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
41447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
41547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Check parameters
41647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype))      { errormsg = "Illegal regtype"; goto badparam; }
41747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!MakeDomainNameFromDNSNameString(&d, *domain ? domain : "local.")) { errormsg = "Illegal domain";  goto badparam; }
41847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
41947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Allocate memory, and handle failure
42047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x = (mDNS_DirectOP_Browse *)mDNSPlatformMemAllocate(sizeof(*x));
42147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
42247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
42347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Set up object
42447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->disposefn = DNSServiceBrowseDispose;
42547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback  = callback;
42647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->context   = context;
42747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.QuestionContext = x;
42847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
42947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Do the operation
43047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mDNS_StartBrowse(&mDNSStorage, &x->q, &t, &d, mDNSInterface_Any, (flags & kDNSServiceFlagsForceMulticast) != 0, FoundInstance, x);
43147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_StartBrowse"; goto fail; }
43247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
43347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Succeeded: Wrap up and return
43447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	*sdRef = (DNSServiceRef)x;
43547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(mStatus_NoError);
43647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
43747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltbadparam:
43847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mStatus_BadParamErr;
43947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfail:
44047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
44147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(err);
44247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
44347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
44447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
44547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Resolve Service Info
44647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
44747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void DNSServiceResolveDispose(mDNS_DirectOP *op)
44847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
44947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Resolve *x = (mDNS_DirectOP_Resolve*)op;
45047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->qSRV.ThisQInterval >= 0) mDNS_StopQuery(&mDNSStorage, &x->qSRV);
45147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->qTXT.ThisQInterval >= 0) mDNS_StopQuery(&mDNSStorage, &x->qTXT);
45247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemFree(x);
45347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
45447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
45547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
45647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
45747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Resolve *x = (mDNS_DirectOP_Resolve*)question->QuestionContext;
45847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)m;	// Unused
45947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!AddRecord)
46047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
46147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (answer->rrtype == kDNSType_SRV && x->SRV == answer) x->SRV = mDNSNULL;
46247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (answer->rrtype == kDNSType_TXT && x->TXT == answer) x->TXT = mDNSNULL;
46347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
46447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	else
46547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
46647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (answer->rrtype == kDNSType_SRV) x->SRV = answer;
46747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (answer->rrtype == kDNSType_TXT) x->TXT = answer;
46847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (x->SRV && x->TXT && x->callback)
46947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
47047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			char fullname[MAX_ESCAPED_DOMAIN_NAME], targethost[MAX_ESCAPED_DOMAIN_NAME];
47147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		    ConvertDomainNameToCString(answer->name, fullname);
47247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		    ConvertDomainNameToCString(&x->SRV->rdata->u.srv.target, targethost);
47347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			x->callback((DNSServiceRef)x, 0, 0, kDNSServiceErr_NoError, fullname, targethost,
47447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				x->SRV->rdata->u.srv.port.NotAnInteger, x->TXT->rdlength, (unsigned char*)x->TXT->rdata->u.txt.c, x->context);
47547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
47647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
47747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
47847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
47947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceResolve
48047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
48147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       *sdRef,
48247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
48347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            interfaceIndex,
48447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *name,
48547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *regtype,
48647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *domain,
48747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceResolveReply              callback,
48847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                                *context  /* may be NULL */
48947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
49047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
49147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mStatus err = mStatus_NoError;
49247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *errormsg = "Unknown";
49347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainlabel n;
49447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainname t, d, srv;
49547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_Resolve *x;
49647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
49747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
49847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
49947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
50047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Check parameters
50147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!name[0]    || !MakeDomainLabelFromLiteralString(&n, name  )) { errormsg = "Bad Instance Name"; goto badparam; }
50247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Bad Service Type";  goto badparam; }
50347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!domain[0]  || !MakeDomainNameFromDNSNameString(&d, domain )) { errormsg = "Bad Domain";        goto badparam; }
50447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!ConstructServiceName(&srv, &n, &t, &d))                      { errormsg = "Bad Name";          goto badparam; }
50547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
50647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Allocate memory, and handle failure
50747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x = (mDNS_DirectOP_Resolve *)mDNSPlatformMemAllocate(sizeof(*x));
50847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
50947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
51047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Set up object
51147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->disposefn = DNSServiceResolveDispose;
51247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback  = callback;
51347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->context   = context;
51447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->SRV       = mDNSNULL;
51547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->TXT       = mDNSNULL;
51647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
51747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
51847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.InterfaceID         = mDNSInterface_Any;
51947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.Target              = zeroAddr;
52047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	AssignDomainName(&x->qSRV.qname, &srv);
52147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.qtype               = kDNSType_SRV;
52247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.qclass              = kDNSClass_IN;
52347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.LongLived           = mDNSfalse;
52447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.ExpectUnique        = mDNStrue;
52547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.ForceMCast          = mDNSfalse;
52647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.ReturnIntermed      = mDNSfalse;
52747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.SuppressUnusable    = mDNSfalse;
52847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.SearchListIndex     = 0;
52947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.AppendSearchDomains = 0;
53047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.RetryWithSearchDomains = mDNSfalse;
53147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.TimeoutQuestion     = 0;
53247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.WakeOnResolve       = 0;
53347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.qnameOrig           = mDNSNULL;
53447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.QuestionCallback    = FoundServiceInfo;
53547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qSRV.QuestionContext     = x;
53647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
53747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
53847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.InterfaceID         = mDNSInterface_Any;
53947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.Target              = zeroAddr;
54047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	AssignDomainName(&x->qTXT.qname, &srv);
54147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.qtype               = kDNSType_TXT;
54247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.qclass              = kDNSClass_IN;
54347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.LongLived           = mDNSfalse;
54447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.ExpectUnique        = mDNStrue;
54547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.ForceMCast          = mDNSfalse;
54647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.ReturnIntermed      = mDNSfalse;
54747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.SuppressUnusable    = mDNSfalse;
54847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.SearchListIndex     = 0;
54947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.AppendSearchDomains = 0;
55047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.RetryWithSearchDomains = mDNSfalse;
55147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.TimeoutQuestion     = 0;
55247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.WakeOnResolve       = 0;
55347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.qnameOrig           = mDNSNULL;
55447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.QuestionCallback    = FoundServiceInfo;
55547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->qTXT.QuestionContext     = x;
55647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
55747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mDNS_StartQuery(&mDNSStorage, &x->qSRV);
55847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qSRV"; goto fail; }
55947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mDNS_StartQuery(&mDNSStorage, &x->qTXT);
56047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qTXT"; goto fail; }
56147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
56247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Succeeded: Wrap up and return
56347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	*sdRef = (DNSServiceRef)x;
56447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(mStatus_NoError);
56547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
56647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltbadparam:
56747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mStatus_BadParamErr;
56847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfail:
56947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	LogMsg("DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%ld)", name, regtype, domain, errormsg, err);
57047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(err);
57147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
57247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
57347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
57447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Connection-oriented calls
57547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
57647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Not yet implemented, so don't include in stub library
57747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// We DO include it in the actual Extension, so that if a later client compiled to use this
57847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// is run against this Extension, it will get a reasonable error code instead of just
57947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
58047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !MDNS_BUILDINGSTUBLIBRARY
58147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef)
58247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
58347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;	// Unused
58447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
58547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
58647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
58747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceRegisterRecord
58847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
58947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       sdRef,
59047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSRecordRef                        *RecordRef,
59147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
59247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            interfaceIndex,
59347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *fullname,
59447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rrtype,
59547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rrclass,
59647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rdlen,
59747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const void                          *rdata,
59847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            ttl,
59947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRegisterRecordReply       callback,
60047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                                *context    /* may be NULL */
60147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
60247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
60347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)sdRef;			// Unused
60447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)RecordRef;		// Unused
60547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
60647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
60747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)fullname;			// Unused
60847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rrtype;			// Unused
60947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rrclass;			// Unused
61047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdlen;			// Unused
61147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdata;			// Unused
61247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)ttl;				// Unused
61347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)callback;			// Unused
61447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)context;			// Unused
61547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
61647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
61747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
61847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
61947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
62047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// DNSServiceQueryRecord
62147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
62247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void DNSServiceQueryRecordDispose(mDNS_DirectOP *op)
62347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
62447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_QueryRecord *x = (mDNS_DirectOP_QueryRecord*)op;
62547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->q.ThisQInterval >= 0) mDNS_StopQuery(&mDNSStorage, &x->q);
62647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemFree(x);
62747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
62847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
62947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DNSServiceQueryRecordResponse(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
63047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
63147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_QueryRecord *x = (mDNS_DirectOP_QueryRecord*)question->QuestionContext;
63247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	char fullname[MAX_ESCAPED_DOMAIN_NAME];
63347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)m;	// Unused
63447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ConvertDomainNameToCString(answer->name, fullname);
63547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback((DNSServiceRef)x, AddRecord ? kDNSServiceFlagsAdd : (DNSServiceFlags)0, 0, kDNSServiceErr_NoError,
63647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		fullname, answer->rrtype, answer->rrclass, answer->rdlength, answer->rdata->u.data, answer->rroriginalttl, x->context);
63747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
63847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
63947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSServiceQueryRecord
64047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
64147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef                       *sdRef,
64247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                     flags,
64347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                            interfaceIndex,
64447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                          *fullname,
64547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rrtype,
64647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                            rrclass,
64747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceQueryRecordReply          callback,
64847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void                                *context  /* may be NULL */
64947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
65047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
65147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mStatus err = mStatus_NoError;
65247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *errormsg = "Unknown";
65347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_QueryRecord *x;
65447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
65547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
65647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
65747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
65847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Allocate memory, and handle failure
65947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x = (mDNS_DirectOP_QueryRecord *)mDNSPlatformMemAllocate(sizeof(*x));
66047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
66147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
66247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Set up object
66347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->disposefn = DNSServiceQueryRecordDispose;
66447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback  = callback;
66547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->context   = context;
66647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
66747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
66847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.InterfaceID         = mDNSInterface_Any;
66947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.Target              = zeroAddr;
67047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MakeDomainNameFromDNSNameString(&x->q.qname, fullname);
67147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.qtype               = rrtype;
67247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.qclass              = rrclass;
67347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.LongLived           = (flags & kDNSServiceFlagsLongLivedQuery) != 0;
67447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.ExpectUnique        = mDNSfalse;
67547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.ForceMCast          = (flags & kDNSServiceFlagsForceMulticast) != 0;
67647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.ReturnIntermed      = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
6770b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon	x->q.SuppressUnusable     = (flags & kDNSServiceFlagsSuppressUnusable) != 0;
67847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.SearchListIndex     = 0;
67947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.AppendSearchDomains = 0;
68047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.RetryWithSearchDomains = mDNSfalse;
68147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.WakeOnResolve       = 0;
68247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.qnameOrig           = mDNSNULL;
68347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.QuestionCallback    = DNSServiceQueryRecordResponse;
68447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->q.QuestionContext     = x;
68547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
68647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = mDNS_StartQuery(&mDNSStorage, &x->q);
68747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery"; goto fail; }
68847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
68947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Succeeded: Wrap up and return
69047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	*sdRef = (DNSServiceRef)x;
69147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(mStatus_NoError);
69247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
69347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfail:
69447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	LogMsg("DNSServiceQueryRecord(\"%s\", %d, %d) failed: %s (%ld)", fullname, rrtype, rrclass, errormsg, err);
69547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(err);
69647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
69747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
69847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
69947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// DNSServiceGetAddrInfo
70047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
70147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void DNSServiceGetAddrInfoDispose(mDNS_DirectOP *op)
70247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
70347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_GetAddrInfo *x = (mDNS_DirectOP_GetAddrInfo*)op;
70447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (x->aQuery) DNSServiceRefDeallocate(x->aQuery);
70547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemFree(x);
70647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
70747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
70847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void DNSSD_API DNSServiceGetAddrInfoResponse(
70947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef		inRef,
71047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags		inFlags,
71147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t			inInterfaceIndex,
71247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceErrorType	inErrorCode,
71347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *		inFullName,
71447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t			inRRType,
71547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t			inRRClass,
71647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t			inRDLen,
71747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const void *		inRData,
71847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t			inTTL,
71947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void *				inContext )
72047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
72147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_GetAddrInfo *		x = (mDNS_DirectOP_GetAddrInfo*)inContext;
72247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	struct sockaddr_in				sa4;
7230b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon
72447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemZero(&sa4, sizeof(sa4));
72547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (inErrorCode == kDNSServiceErr_NoError && inRRType == kDNSServiceType_A)
72647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
72747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		sa4.sin_family = AF_INET;
72847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		mDNSPlatformMemCopy(&sa4.sin_addr.s_addr, inRData, 4);
72947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
73047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
73147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback((DNSServiceRef)x, inFlags, inInterfaceIndex, inErrorCode, inFullName,
73247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		(const struct sockaddr *) &sa4, inTTL, x->context);
73347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
73447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
73547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo(
73647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceRef *				outRef,
73747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags				inFlags,
73847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t					inInterfaceIndex,
73947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceProtocol			inProtocol,
74047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *				inHostName,
74147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceGetAddrInfoReply	inCallback,
74247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	void *						inContext )
74347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
74447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *					errormsg = "Unknown";
74547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceErrorType				err;
74647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_DirectOP_GetAddrInfo *		x;
74747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
74847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Allocate memory, and handle failure
74947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x = (mDNS_DirectOP_GetAddrInfo *)mDNSPlatformMemAllocate(sizeof(*x));
75047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
75147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
75247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Set up object
75347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->disposefn = DNSServiceGetAddrInfoDispose;
75447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->callback  = inCallback;
75547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->context   = inContext;
75647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	x->aQuery    = mDNSNULL;
75747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
75847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Start the query.
75947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// (It would probably be more efficient to code this using mDNS_StartQuery directly,
76047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// instead of wrapping DNSServiceQueryRecord, which then unnecessarily allocates
76147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// more memory and then just calls through to mDNS_StartQuery. -- SC June 2010)
76247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	err = DNSServiceQueryRecord(&x->aQuery, inFlags, inInterfaceIndex, inHostName, kDNSServiceType_A,
76347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		kDNSServiceClass_IN, DNSServiceGetAddrInfoResponse, x);
76447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (err) { DNSServiceGetAddrInfoDispose((mDNS_DirectOP*)x); errormsg = "DNSServiceQueryRecord"; goto fail; }
76547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
76647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	*outRef = (DNSServiceRef)x;
76747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(mStatus_NoError);
76847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
76947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfail:
77047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	LogMsg("DNSServiceGetAddrInfo(\"%s\", %d) failed: %s (%ld)", inHostName, inProtocol, errormsg, err);
77147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(err);
77247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
77347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
77447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//*************************************************************************************************************
77547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// DNSServiceReconfirmRecord
77647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
77747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Not yet implemented, so don't include in stub library
77847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// We DO include it in the actual Extension, so that if a later client compiled to use this
77947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// is run against this Extension, it will get a reasonable error code instead of just
78047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
78147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !MDNS_BUILDINGSTUBLIBRARY
78247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltDNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
78347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(
78447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSServiceFlags                    flags,
78547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint32_t                           interfaceIndex,
78647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char                         *fullname,
78747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                           rrtype,
78847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                           rrclass,
78947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	uint16_t                           rdlen,
79047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const void                         *rdata
79147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	)
79247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
79347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)flags;			// Unused
79447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)interfaceIndex;	// Unused
79547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)fullname;			// Unused
79647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rrtype;			// Unused
79747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rrclass;			// Unused
79847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdlen;			// Unused
79947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	(void)rdata;			// Unused
80047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(kDNSServiceErr_Unsupported);
80147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
80247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
803