xref: /aosp_15_r20/external/mdnsresponder/mDNSShared/dnssd_clientshim.c (revision 48a54d368dc4fa860885eef7b70b6c53499e7c25)
1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker  *
3*48a54d36SAndroid Build Coastguard Worker  * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker  *
5*48a54d36SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker  *
9*48a54d36SAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker  *
11*48a54d36SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker  * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker 
17*48a54d36SAndroid Build Coastguard Worker  * This file defines a simple shim layer between a client calling the "/usr/include/dns_sd.h" APIs
18*48a54d36SAndroid Build Coastguard Worker  * and an implementation of mDNSCore ("mDNSEmbeddedAPI.h" APIs) in the same address space.
19*48a54d36SAndroid Build Coastguard Worker  * When the client calls a dns_sd.h function, the shim calls the corresponding mDNSEmbeddedAPI.h
20*48a54d36SAndroid Build Coastguard Worker  * function, and when mDNSCore calls the shim's callback, we call through to the client's callback.
21*48a54d36SAndroid Build Coastguard Worker  * The shim is responsible for two main things:
22*48a54d36SAndroid Build Coastguard Worker  * - converting string parameters between C string format and native DNS format,
23*48a54d36SAndroid Build Coastguard Worker  * - and for allocating and freeing memory.
24*48a54d36SAndroid Build Coastguard Worker  */
25*48a54d36SAndroid Build Coastguard Worker 
26*48a54d36SAndroid Build Coastguard Worker #include "dns_sd.h"				// Defines the interface to the client layer above
27*48a54d36SAndroid Build Coastguard Worker #include "mDNSEmbeddedAPI.h"		// The interface we're building on top of
28*48a54d36SAndroid Build Coastguard Worker #include <sys/socket.h>
29*48a54d36SAndroid Build Coastguard Worker #include <netinet/in.h>
30*48a54d36SAndroid Build Coastguard Worker 
31*48a54d36SAndroid Build Coastguard Worker extern mDNS mDNSStorage;		// We need to pass the address of this storage to the lower-layer functions
32*48a54d36SAndroid Build Coastguard Worker 
33*48a54d36SAndroid Build Coastguard Worker #if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
34*48a54d36SAndroid Build Coastguard Worker #pragma export on
35*48a54d36SAndroid Build Coastguard Worker #endif
36*48a54d36SAndroid Build Coastguard Worker 
37*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
38*48a54d36SAndroid Build Coastguard Worker // General Utility Functions
39*48a54d36SAndroid Build Coastguard Worker 
40*48a54d36SAndroid Build Coastguard Worker // All mDNS_DirectOP structures start with the pointer to the type-specific disposal function.
41*48a54d36SAndroid Build Coastguard Worker // Optional type-specific data follows these three fields
42*48a54d36SAndroid Build Coastguard Worker // When the client starts an operation, we return the address of the corresponding mDNS_DirectOP
43*48a54d36SAndroid Build Coastguard Worker // as the DNSServiceRef for the operation
44*48a54d36SAndroid Build Coastguard Worker // We stash the value in core context fields so we can get it back to recover our state in our callbacks,
45*48a54d36SAndroid Build Coastguard Worker // and pass it though to the client for it to recover its state
46*48a54d36SAndroid Build Coastguard Worker 
47*48a54d36SAndroid Build Coastguard Worker typedef struct mDNS_DirectOP_struct mDNS_DirectOP;
48*48a54d36SAndroid Build Coastguard Worker typedef void mDNS_DirectOP_Dispose(mDNS_DirectOP *op);
49*48a54d36SAndroid Build Coastguard Worker struct mDNS_DirectOP_struct
50*48a54d36SAndroid Build Coastguard Worker 	{
51*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Dispose  *disposefn;
52*48a54d36SAndroid Build Coastguard Worker 	};
53*48a54d36SAndroid Build Coastguard Worker 
54*48a54d36SAndroid Build Coastguard Worker typedef struct
55*48a54d36SAndroid Build Coastguard Worker 	{
56*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Dispose  *disposefn;
57*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRegisterReply callback;
58*48a54d36SAndroid Build Coastguard Worker 	void                   *context;
59*48a54d36SAndroid Build Coastguard Worker 	mDNSBool                autoname;		// Set if this name is tied to the Computer Name
60*48a54d36SAndroid Build Coastguard Worker 	mDNSBool                autorename;		// Set if we just got a name conflict and now need to automatically pick a new name
61*48a54d36SAndroid Build Coastguard Worker 	domainlabel             name;
62*48a54d36SAndroid Build Coastguard Worker 	domainname              host;
63*48a54d36SAndroid Build Coastguard Worker 	ServiceRecordSet        s;
64*48a54d36SAndroid Build Coastguard Worker 	} mDNS_DirectOP_Register;
65*48a54d36SAndroid Build Coastguard Worker 
66*48a54d36SAndroid Build Coastguard Worker typedef struct
67*48a54d36SAndroid Build Coastguard Worker 	{
68*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Dispose  *disposefn;
69*48a54d36SAndroid Build Coastguard Worker 	DNSServiceBrowseReply   callback;
70*48a54d36SAndroid Build Coastguard Worker 	void                   *context;
71*48a54d36SAndroid Build Coastguard Worker 	DNSQuestion             q;
72*48a54d36SAndroid Build Coastguard Worker 	} mDNS_DirectOP_Browse;
73*48a54d36SAndroid Build Coastguard Worker 
74*48a54d36SAndroid Build Coastguard Worker typedef struct
75*48a54d36SAndroid Build Coastguard Worker 	{
76*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Dispose        *disposefn;
77*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                aQuery;
78*48a54d36SAndroid Build Coastguard Worker 	DNSServiceGetAddrInfoReply   callback;
79*48a54d36SAndroid Build Coastguard Worker   	void                         *context;
80*48a54d36SAndroid Build Coastguard Worker 	} mDNS_DirectOP_GetAddrInfo;
81*48a54d36SAndroid Build Coastguard Worker 
82*48a54d36SAndroid Build Coastguard Worker typedef struct
83*48a54d36SAndroid Build Coastguard Worker 	{
84*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Dispose  *disposefn;
85*48a54d36SAndroid Build Coastguard Worker 	DNSServiceResolveReply  callback;
86*48a54d36SAndroid Build Coastguard Worker 	void                   *context;
87*48a54d36SAndroid Build Coastguard Worker 	const ResourceRecord   *SRV;
88*48a54d36SAndroid Build Coastguard Worker 	const ResourceRecord   *TXT;
89*48a54d36SAndroid Build Coastguard Worker 	DNSQuestion             qSRV;
90*48a54d36SAndroid Build Coastguard Worker 	DNSQuestion             qTXT;
91*48a54d36SAndroid Build Coastguard Worker 	} mDNS_DirectOP_Resolve;
92*48a54d36SAndroid Build Coastguard Worker 
93*48a54d36SAndroid Build Coastguard Worker typedef struct
94*48a54d36SAndroid Build Coastguard Worker 	{
95*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Dispose      *disposefn;
96*48a54d36SAndroid Build Coastguard Worker 	DNSServiceQueryRecordReply  callback;
97*48a54d36SAndroid Build Coastguard Worker 	void                       *context;
98*48a54d36SAndroid Build Coastguard Worker 	DNSQuestion                 q;
99*48a54d36SAndroid Build Coastguard Worker 	} mDNS_DirectOP_QueryRecord;
100*48a54d36SAndroid Build Coastguard Worker 
DNSServiceRefSockFD(DNSServiceRef sdRef)101*48a54d36SAndroid Build Coastguard Worker int DNSServiceRefSockFD(DNSServiceRef sdRef)
102*48a54d36SAndroid Build Coastguard Worker 	{
103*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;	// Unused
104*48a54d36SAndroid Build Coastguard Worker 	return(0);
105*48a54d36SAndroid Build Coastguard Worker 	}
106*48a54d36SAndroid Build Coastguard Worker 
DNSServiceProcessResult(DNSServiceRef sdRef)107*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceProcessResult(DNSServiceRef sdRef)
108*48a54d36SAndroid Build Coastguard Worker 	{
109*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;	// Unused
110*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_NoError);
111*48a54d36SAndroid Build Coastguard Worker 	}
112*48a54d36SAndroid Build Coastguard Worker 
DNSServiceRefDeallocate(DNSServiceRef sdRef)113*48a54d36SAndroid Build Coastguard Worker void DNSServiceRefDeallocate(DNSServiceRef sdRef)
114*48a54d36SAndroid Build Coastguard Worker 	{
115*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP *op = (mDNS_DirectOP *)sdRef;
116*48a54d36SAndroid Build Coastguard Worker 	//LogMsg("DNSServiceRefDeallocate");
117*48a54d36SAndroid Build Coastguard Worker 	op->disposefn(op);
118*48a54d36SAndroid Build Coastguard Worker 	}
119*48a54d36SAndroid Build Coastguard Worker 
120*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
121*48a54d36SAndroid Build Coastguard Worker // Domain Enumeration
122*48a54d36SAndroid Build Coastguard Worker 
123*48a54d36SAndroid Build Coastguard Worker // Not yet implemented, so don't include in stub library
124*48a54d36SAndroid Build Coastguard Worker // We DO include it in the actual Extension, so that if a later client compiled to use this
125*48a54d36SAndroid Build Coastguard Worker // is run against this Extension, it will get a reasonable error code instead of just
126*48a54d36SAndroid Build Coastguard Worker // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
127*48a54d36SAndroid Build Coastguard Worker #if !MDNS_BUILDINGSTUBLIBRARY
DNSServiceEnumerateDomains(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceDomainEnumReply callback,void * context)128*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceEnumerateDomains
129*48a54d36SAndroid Build Coastguard Worker 	(
130*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       *sdRef,
131*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
132*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            interfaceIndex,
133*48a54d36SAndroid Build Coastguard Worker 	DNSServiceDomainEnumReply           callback,
134*48a54d36SAndroid Build Coastguard Worker 	void                                *context  /* may be NULL */
135*48a54d36SAndroid Build Coastguard Worker 	)
136*48a54d36SAndroid Build Coastguard Worker 	{
137*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;			// Unused
138*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
139*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
140*48a54d36SAndroid Build Coastguard Worker 	(void)callback;			// Unused
141*48a54d36SAndroid Build Coastguard Worker 	(void)context;			// Unused
142*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
143*48a54d36SAndroid Build Coastguard Worker 	}
144*48a54d36SAndroid Build Coastguard Worker #endif
145*48a54d36SAndroid Build Coastguard Worker 
146*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
147*48a54d36SAndroid Build Coastguard Worker // Register Service
148*48a54d36SAndroid Build Coastguard Worker 
FreeDNSServiceRegistration(mDNS_DirectOP_Register * x)149*48a54d36SAndroid Build Coastguard Worker mDNSlocal void FreeDNSServiceRegistration(mDNS_DirectOP_Register *x)
150*48a54d36SAndroid Build Coastguard Worker 	{
151*48a54d36SAndroid Build Coastguard Worker 	while (x->s.Extras)
152*48a54d36SAndroid Build Coastguard Worker 		{
153*48a54d36SAndroid Build Coastguard Worker 		ExtraResourceRecord *extras = x->s.Extras;
154*48a54d36SAndroid Build Coastguard Worker 		x->s.Extras = x->s.Extras->next;
155*48a54d36SAndroid Build Coastguard Worker 		if (extras->r.resrec.rdata != &extras->r.rdatastorage)
156*48a54d36SAndroid Build Coastguard Worker 			mDNSPlatformMemFree(extras->r.resrec.rdata);
157*48a54d36SAndroid Build Coastguard Worker 		mDNSPlatformMemFree(extras);
158*48a54d36SAndroid Build Coastguard Worker 		}
159*48a54d36SAndroid Build Coastguard Worker 
160*48a54d36SAndroid Build Coastguard Worker 	if (x->s.RR_TXT.resrec.rdata != &x->s.RR_TXT.rdatastorage)
161*48a54d36SAndroid Build Coastguard Worker 			mDNSPlatformMemFree(x->s.RR_TXT.resrec.rdata);
162*48a54d36SAndroid Build Coastguard Worker 
163*48a54d36SAndroid Build Coastguard Worker 	if (x->s.SubTypes) mDNSPlatformMemFree(x->s.SubTypes);
164*48a54d36SAndroid Build Coastguard Worker 
165*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemFree(x);
166*48a54d36SAndroid Build Coastguard Worker 	}
167*48a54d36SAndroid Build Coastguard Worker 
DNSServiceRegisterDispose(mDNS_DirectOP * op)168*48a54d36SAndroid Build Coastguard Worker static void DNSServiceRegisterDispose(mDNS_DirectOP *op)
169*48a54d36SAndroid Build Coastguard Worker 	{
170*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Register *x = (mDNS_DirectOP_Register*)op;
171*48a54d36SAndroid Build Coastguard Worker 	x->autorename = mDNSfalse;
172*48a54d36SAndroid Build Coastguard Worker 	// If mDNS_DeregisterService() returns mStatus_NoError, that means that the service was found in the list,
173*48a54d36SAndroid Build Coastguard Worker 	// is sending its goodbye packet, and we'll get an mStatus_MemFree message when we can free the memory.
174*48a54d36SAndroid Build Coastguard Worker 	// If mDNS_DeregisterService() returns an error, it means that the service had already been removed from
175*48a54d36SAndroid Build Coastguard Worker 	// the list, so we should go ahead and free the memory right now
176*48a54d36SAndroid Build Coastguard Worker 	if (mDNS_DeregisterService(&mDNSStorage, &x->s) != mStatus_NoError)
177*48a54d36SAndroid Build Coastguard Worker 		FreeDNSServiceRegistration(x);
178*48a54d36SAndroid Build Coastguard Worker 	}
179*48a54d36SAndroid Build Coastguard Worker 
RegCallback(mDNS * const m,ServiceRecordSet * const sr,mStatus result)180*48a54d36SAndroid Build Coastguard Worker mDNSlocal void RegCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus result)
181*48a54d36SAndroid Build Coastguard Worker 	{
182*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Register *x = (mDNS_DirectOP_Register*)sr->ServiceContext;
183*48a54d36SAndroid Build Coastguard Worker 
184*48a54d36SAndroid Build Coastguard Worker     domainlabel name;
185*48a54d36SAndroid Build Coastguard Worker     domainname type, dom;
186*48a54d36SAndroid Build Coastguard Worker 	char namestr[MAX_DOMAIN_LABEL+1];		// Unescaped name: up to 63 bytes plus C-string terminating NULL.
187*48a54d36SAndroid Build Coastguard Worker 	char typestr[MAX_ESCAPED_DOMAIN_NAME];
188*48a54d36SAndroid Build Coastguard Worker 	char domstr [MAX_ESCAPED_DOMAIN_NAME];
189*48a54d36SAndroid Build Coastguard Worker     if (!DeconstructServiceName(sr->RR_SRV.resrec.name, &name, &type, &dom)) return;
190*48a54d36SAndroid Build Coastguard Worker     if (!ConvertDomainLabelToCString_unescaped(&name, namestr)) return;
191*48a54d36SAndroid Build Coastguard Worker     if (!ConvertDomainNameToCString(&type, typestr)) return;
192*48a54d36SAndroid Build Coastguard Worker     if (!ConvertDomainNameToCString(&dom, domstr)) return;
193*48a54d36SAndroid Build Coastguard Worker 
194*48a54d36SAndroid Build Coastguard Worker 	if (result == mStatus_NoError)
195*48a54d36SAndroid Build Coastguard Worker 		{
196*48a54d36SAndroid Build Coastguard Worker 		if (x->callback)
197*48a54d36SAndroid Build Coastguard Worker 			x->callback((DNSServiceRef)x, 0, result, namestr, typestr, domstr, x->context);
198*48a54d36SAndroid Build Coastguard Worker 		}
199*48a54d36SAndroid Build Coastguard Worker 	else if (result == mStatus_NameConflict)
200*48a54d36SAndroid Build Coastguard Worker 		{
201*48a54d36SAndroid Build Coastguard Worker 			if (x->autoname) mDNS_RenameAndReregisterService(m, sr, mDNSNULL);
202*48a54d36SAndroid Build Coastguard Worker 			else if (x->autorename) {
203*48a54d36SAndroid Build Coastguard Worker 				IncrementLabelSuffix(&x->name, mDNStrue);
204*48a54d36SAndroid Build Coastguard Worker 				mDNS_RenameAndReregisterService(m, &x->s, &x->name);
205*48a54d36SAndroid Build Coastguard Worker 			}
206*48a54d36SAndroid Build Coastguard Worker 			else if (x->callback)
207*48a54d36SAndroid Build Coastguard Worker 				x->callback((DNSServiceRef)x, 0, result, namestr, typestr, domstr, x->context);
208*48a54d36SAndroid Build Coastguard Worker 		}
209*48a54d36SAndroid Build Coastguard Worker 	else if (result == mStatus_MemFree)
210*48a54d36SAndroid Build Coastguard Worker 		{
211*48a54d36SAndroid Build Coastguard Worker 		if (x->autorename)
212*48a54d36SAndroid Build Coastguard Worker 			{
213*48a54d36SAndroid Build Coastguard Worker 			x->autorename = mDNSfalse;
214*48a54d36SAndroid Build Coastguard Worker 			x->name = mDNSStorage.nicelabel;
215*48a54d36SAndroid Build Coastguard Worker 			mDNS_RenameAndReregisterService(m, &x->s, &x->name);
216*48a54d36SAndroid Build Coastguard Worker 			}
217*48a54d36SAndroid Build Coastguard Worker 		else
218*48a54d36SAndroid Build Coastguard Worker 			FreeDNSServiceRegistration(x);
219*48a54d36SAndroid Build Coastguard Worker 		}
220*48a54d36SAndroid Build Coastguard Worker 	}
221*48a54d36SAndroid Build Coastguard Worker 
DNSServiceRegister(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * name,const char * regtype,const char * domain,const char * host,uint16_t notAnIntPort,uint16_t txtLen,const void * txtRecord,DNSServiceRegisterReply callback,void * context)222*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceRegister
223*48a54d36SAndroid Build Coastguard Worker 	(
224*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       *sdRef,
225*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
226*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            interfaceIndex,
227*48a54d36SAndroid Build Coastguard Worker 	const char                          *name,         /* may be NULL */
228*48a54d36SAndroid Build Coastguard Worker 	const char                          *regtype,
229*48a54d36SAndroid Build Coastguard Worker 	const char                          *domain,       /* may be NULL */
230*48a54d36SAndroid Build Coastguard Worker 	const char                          *host,         /* may be NULL */
231*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            notAnIntPort,
232*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            txtLen,
233*48a54d36SAndroid Build Coastguard Worker 	const void                          *txtRecord,    /* may be NULL */
234*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRegisterReply             callback,      /* may be NULL */
235*48a54d36SAndroid Build Coastguard Worker 	void                                *context       /* may be NULL */
236*48a54d36SAndroid Build Coastguard Worker 	)
237*48a54d36SAndroid Build Coastguard Worker 	{
238*48a54d36SAndroid Build Coastguard Worker 	mStatus err = mStatus_NoError;
239*48a54d36SAndroid Build Coastguard Worker 	const char *errormsg = "Unknown";
240*48a54d36SAndroid Build Coastguard Worker 	domainlabel n;
241*48a54d36SAndroid Build Coastguard Worker 	domainname t, d, h, srv;
242*48a54d36SAndroid Build Coastguard Worker 	mDNSIPPort port;
243*48a54d36SAndroid Build Coastguard Worker 	unsigned int size = sizeof(RDataBody);
244*48a54d36SAndroid Build Coastguard Worker 	AuthRecord *SubTypes = mDNSNULL;
245*48a54d36SAndroid Build Coastguard Worker 	mDNSu32 NumSubTypes = 0;
246*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Register *x;
247*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
248*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
249*48a54d36SAndroid Build Coastguard Worker 
250*48a54d36SAndroid Build Coastguard Worker 	// Check parameters
251*48a54d36SAndroid Build Coastguard Worker 	if (!name) name = "";
252*48a54d36SAndroid Build Coastguard Worker 	if (!name[0]) n = mDNSStorage.nicelabel;
253*48a54d36SAndroid Build Coastguard Worker 	else if (!MakeDomainLabelFromLiteralString(&n, name))                              { errormsg = "Bad Instance Name"; goto badparam; }
254*48a54d36SAndroid Build Coastguard Worker 	if (!regtype || !*regtype || !MakeDomainNameFromDNSNameString(&t, regtype))        { errormsg = "Bad Service Type";  goto badparam; }
255*48a54d36SAndroid Build Coastguard Worker 	if (!MakeDomainNameFromDNSNameString(&d, (domain && *domain) ? domain : "local.")) { errormsg = "Bad Domain";        goto badparam; }
256*48a54d36SAndroid Build Coastguard Worker 	if (!MakeDomainNameFromDNSNameString(&h, (host   && *host  ) ? host   : ""))       { errormsg = "Bad Target Host";   goto badparam; }
257*48a54d36SAndroid Build Coastguard Worker 	if (!ConstructServiceName(&srv, &n, &t, &d))                                       { errormsg = "Bad Name";          goto badparam; }
258*48a54d36SAndroid Build Coastguard Worker 	port.NotAnInteger = notAnIntPort;
259*48a54d36SAndroid Build Coastguard Worker 
260*48a54d36SAndroid Build Coastguard Worker 	// Allocate memory, and handle failure
261*48a54d36SAndroid Build Coastguard Worker 	if (size < txtLen)
262*48a54d36SAndroid Build Coastguard Worker 		size = txtLen;
263*48a54d36SAndroid Build Coastguard Worker 	x = (mDNS_DirectOP_Register *)mDNSPlatformMemAllocate(sizeof(*x) - sizeof(RDataBody) + size);
264*48a54d36SAndroid Build Coastguard Worker 	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
265*48a54d36SAndroid Build Coastguard Worker 
266*48a54d36SAndroid Build Coastguard Worker 	// Set up object
267*48a54d36SAndroid Build Coastguard Worker 	x->disposefn = DNSServiceRegisterDispose;
268*48a54d36SAndroid Build Coastguard Worker 	x->callback  = callback;
269*48a54d36SAndroid Build Coastguard Worker 	x->context   = context;
270*48a54d36SAndroid Build Coastguard Worker 	x->autoname = (!name[0]);
271*48a54d36SAndroid Build Coastguard Worker 	x->autorename = !(flags & kDNSServiceFlagsNoAutoRename);
272*48a54d36SAndroid Build Coastguard Worker 	x->name = n;
273*48a54d36SAndroid Build Coastguard Worker 	x->host = h;
274*48a54d36SAndroid Build Coastguard Worker 
275*48a54d36SAndroid Build Coastguard Worker 	// Do the operation
276*48a54d36SAndroid Build Coastguard Worker 	err = mDNS_RegisterService(&mDNSStorage, &x->s,
277*48a54d36SAndroid Build Coastguard Worker 		&x->name, &t, &d,		// Name, type, domain
278*48a54d36SAndroid Build Coastguard Worker 		&x->host, port,			// Host and port
279*48a54d36SAndroid Build Coastguard Worker 		txtRecord, txtLen,		// TXT data, length
280*48a54d36SAndroid Build Coastguard Worker 		SubTypes, NumSubTypes,	// Subtypes
281*48a54d36SAndroid Build Coastguard Worker 		mDNSInterface_Any,		// Interface ID
282*48a54d36SAndroid Build Coastguard Worker 		RegCallback, x, 0);		// Callback, context, flags
283*48a54d36SAndroid Build Coastguard Worker 	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_RegisterService"; goto fail; }
284*48a54d36SAndroid Build Coastguard Worker 
285*48a54d36SAndroid Build Coastguard Worker 	// Succeeded: Wrap up and return
286*48a54d36SAndroid Build Coastguard Worker 	*sdRef = (DNSServiceRef)x;
287*48a54d36SAndroid Build Coastguard Worker 	return(mStatus_NoError);
288*48a54d36SAndroid Build Coastguard Worker 
289*48a54d36SAndroid Build Coastguard Worker badparam:
290*48a54d36SAndroid Build Coastguard Worker 	err = mStatus_BadParamErr;
291*48a54d36SAndroid Build Coastguard Worker fail:
292*48a54d36SAndroid Build Coastguard Worker 	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
293*48a54d36SAndroid Build Coastguard Worker 	return(err);
294*48a54d36SAndroid Build Coastguard Worker 	}
295*48a54d36SAndroid Build Coastguard Worker 
296*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
297*48a54d36SAndroid Build Coastguard Worker // Add / Update / Remove records from existing Registration
298*48a54d36SAndroid Build Coastguard Worker 
299*48a54d36SAndroid Build Coastguard Worker // Not yet implemented, so don't include in stub library
300*48a54d36SAndroid Build Coastguard Worker // We DO include it in the actual Extension, so that if a later client compiled to use this
301*48a54d36SAndroid Build Coastguard Worker // is run against this Extension, it will get a reasonable error code instead of just
302*48a54d36SAndroid Build Coastguard Worker // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
303*48a54d36SAndroid Build Coastguard Worker #if !MDNS_BUILDINGSTUBLIBRARY
DNSServiceAddRecord(DNSServiceRef sdRef,DNSRecordRef * RecordRef,DNSServiceFlags flags,uint16_t rrtype,uint16_t rdlen,const void * rdata,uint32_t ttl)304*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceAddRecord
305*48a54d36SAndroid Build Coastguard Worker 	(
306*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       sdRef,
307*48a54d36SAndroid Build Coastguard Worker 	DNSRecordRef                        *RecordRef,
308*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
309*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rrtype,
310*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rdlen,
311*48a54d36SAndroid Build Coastguard Worker 	const void                          *rdata,
312*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            ttl
313*48a54d36SAndroid Build Coastguard Worker 	)
314*48a54d36SAndroid Build Coastguard Worker 	{
315*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;		// Unused
316*48a54d36SAndroid Build Coastguard Worker 	(void)RecordRef;	// Unused
317*48a54d36SAndroid Build Coastguard Worker 	(void)flags;		// Unused
318*48a54d36SAndroid Build Coastguard Worker 	(void)rrtype;		// Unused
319*48a54d36SAndroid Build Coastguard Worker 	(void)rdlen;		// Unused
320*48a54d36SAndroid Build Coastguard Worker 	(void)rdata;		// Unused
321*48a54d36SAndroid Build Coastguard Worker 	(void)ttl;			// Unused
322*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
323*48a54d36SAndroid Build Coastguard Worker 	}
324*48a54d36SAndroid Build Coastguard Worker 
DNSServiceUpdateRecord(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags,uint16_t rdlen,const void * rdata,uint32_t ttl)325*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceUpdateRecord
326*48a54d36SAndroid Build Coastguard Worker 	(
327*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       sdRef,
328*48a54d36SAndroid Build Coastguard Worker 	DNSRecordRef                        RecordRef,     /* may be NULL */
329*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
330*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rdlen,
331*48a54d36SAndroid Build Coastguard Worker 	const void                          *rdata,
332*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            ttl
333*48a54d36SAndroid Build Coastguard Worker 	)
334*48a54d36SAndroid Build Coastguard Worker 	{
335*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;		// Unused
336*48a54d36SAndroid Build Coastguard Worker 	(void)RecordRef;	// Unused
337*48a54d36SAndroid Build Coastguard Worker 	(void)flags;		// Unused
338*48a54d36SAndroid Build Coastguard Worker 	(void)rdlen;		// Unused
339*48a54d36SAndroid Build Coastguard Worker 	(void)rdata;		// Unused
340*48a54d36SAndroid Build Coastguard Worker 	(void)ttl;			// Unused
341*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
342*48a54d36SAndroid Build Coastguard Worker 	}
343*48a54d36SAndroid Build Coastguard Worker 
DNSServiceRemoveRecord(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags)344*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceRemoveRecord
345*48a54d36SAndroid Build Coastguard Worker 	(
346*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                 sdRef,
347*48a54d36SAndroid Build Coastguard Worker 	DNSRecordRef                  RecordRef,
348*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags               flags
349*48a54d36SAndroid Build Coastguard Worker 	)
350*48a54d36SAndroid Build Coastguard Worker 	{
351*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;		// Unused
352*48a54d36SAndroid Build Coastguard Worker 	(void)RecordRef;	// Unused
353*48a54d36SAndroid Build Coastguard Worker 	(void)flags;		// Unused
354*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
355*48a54d36SAndroid Build Coastguard Worker 	}
356*48a54d36SAndroid Build Coastguard Worker #endif
357*48a54d36SAndroid Build Coastguard Worker 
358*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
359*48a54d36SAndroid Build Coastguard Worker // Browse for services
360*48a54d36SAndroid Build Coastguard Worker 
DNSServiceBrowseDispose(mDNS_DirectOP * op)361*48a54d36SAndroid Build Coastguard Worker static void DNSServiceBrowseDispose(mDNS_DirectOP *op)
362*48a54d36SAndroid Build Coastguard Worker 	{
363*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Browse *x = (mDNS_DirectOP_Browse*)op;
364*48a54d36SAndroid Build Coastguard Worker 	//LogMsg("DNSServiceBrowseDispose");
365*48a54d36SAndroid Build Coastguard Worker 	mDNS_StopBrowse(&mDNSStorage, &x->q);
366*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemFree(x);
367*48a54d36SAndroid Build Coastguard Worker 	}
368*48a54d36SAndroid Build Coastguard Worker 
FoundInstance(mDNS * const m,DNSQuestion * question,const ResourceRecord * const answer,QC_result AddRecord)369*48a54d36SAndroid Build Coastguard Worker mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
370*48a54d36SAndroid Build Coastguard Worker 	{
371*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags flags = AddRecord ? kDNSServiceFlagsAdd : (DNSServiceFlags)0;
372*48a54d36SAndroid Build Coastguard Worker 	domainlabel name;
373*48a54d36SAndroid Build Coastguard Worker 	domainname type, domain;
374*48a54d36SAndroid Build Coastguard Worker 	char cname[MAX_DOMAIN_LABEL+1];			// Unescaped name: up to 63 bytes plus C-string terminating NULL.
375*48a54d36SAndroid Build Coastguard Worker 	char ctype[MAX_ESCAPED_DOMAIN_NAME];
376*48a54d36SAndroid Build Coastguard Worker 	char cdom [MAX_ESCAPED_DOMAIN_NAME];
377*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Browse *x = (mDNS_DirectOP_Browse*)question->QuestionContext;
378*48a54d36SAndroid Build Coastguard Worker 	(void)m;		// Unused
379*48a54d36SAndroid Build Coastguard Worker 
380*48a54d36SAndroid Build Coastguard Worker 	if (answer->rrtype != kDNSType_PTR)
381*48a54d36SAndroid Build Coastguard Worker 		{ LogMsg("FoundInstance: Should not be called with rrtype %d (not a PTR record)", answer->rrtype); return; }
382*48a54d36SAndroid Build Coastguard Worker 
383*48a54d36SAndroid Build Coastguard Worker 	if (!DeconstructServiceName(&answer->rdata->u.name, &name, &type, &domain))
384*48a54d36SAndroid Build Coastguard Worker 		{
385*48a54d36SAndroid Build Coastguard Worker 		LogMsg("FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer",
386*48a54d36SAndroid Build Coastguard Worker 			answer->name->c, answer->rdata->u.name.c);
387*48a54d36SAndroid Build Coastguard Worker 		return;
388*48a54d36SAndroid Build Coastguard Worker 		}
389*48a54d36SAndroid Build Coastguard Worker 
390*48a54d36SAndroid Build Coastguard Worker 	ConvertDomainLabelToCString_unescaped(&name, cname);
391*48a54d36SAndroid Build Coastguard Worker 	ConvertDomainNameToCString(&type, ctype);
392*48a54d36SAndroid Build Coastguard Worker 	ConvertDomainNameToCString(&domain, cdom);
393*48a54d36SAndroid Build Coastguard Worker 	if (x->callback)
394*48a54d36SAndroid Build Coastguard Worker 		x->callback((DNSServiceRef)x, flags, 0, 0, cname, ctype, cdom, x->context);
395*48a54d36SAndroid Build Coastguard Worker 	}
396*48a54d36SAndroid Build Coastguard Worker 
DNSServiceBrowse(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * regtype,const char * domain,DNSServiceBrowseReply callback,void * context)397*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceBrowse
398*48a54d36SAndroid Build Coastguard Worker 	(
399*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       *sdRef,
400*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
401*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            interfaceIndex,
402*48a54d36SAndroid Build Coastguard Worker 	const char                          *regtype,
403*48a54d36SAndroid Build Coastguard Worker 	const char                          *domain,    /* may be NULL */
404*48a54d36SAndroid Build Coastguard Worker 	DNSServiceBrowseReply               callback,
405*48a54d36SAndroid Build Coastguard Worker 	void                                *context    /* may be NULL */
406*48a54d36SAndroid Build Coastguard Worker 	)
407*48a54d36SAndroid Build Coastguard Worker 	{
408*48a54d36SAndroid Build Coastguard Worker 	mStatus err = mStatus_NoError;
409*48a54d36SAndroid Build Coastguard Worker 	const char *errormsg = "Unknown";
410*48a54d36SAndroid Build Coastguard Worker 	domainname t, d;
411*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Browse *x;
412*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
413*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
414*48a54d36SAndroid Build Coastguard Worker 
415*48a54d36SAndroid Build Coastguard Worker 	// Check parameters
416*48a54d36SAndroid Build Coastguard Worker 	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype))      { errormsg = "Illegal regtype"; goto badparam; }
417*48a54d36SAndroid Build Coastguard Worker 	if (!MakeDomainNameFromDNSNameString(&d, *domain ? domain : "local.")) { errormsg = "Illegal domain";  goto badparam; }
418*48a54d36SAndroid Build Coastguard Worker 
419*48a54d36SAndroid Build Coastguard Worker 	// Allocate memory, and handle failure
420*48a54d36SAndroid Build Coastguard Worker 	x = (mDNS_DirectOP_Browse *)mDNSPlatformMemAllocate(sizeof(*x));
421*48a54d36SAndroid Build Coastguard Worker 	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
422*48a54d36SAndroid Build Coastguard Worker 
423*48a54d36SAndroid Build Coastguard Worker 	// Set up object
424*48a54d36SAndroid Build Coastguard Worker 	x->disposefn = DNSServiceBrowseDispose;
425*48a54d36SAndroid Build Coastguard Worker 	x->callback  = callback;
426*48a54d36SAndroid Build Coastguard Worker 	x->context   = context;
427*48a54d36SAndroid Build Coastguard Worker 	x->q.QuestionContext = x;
428*48a54d36SAndroid Build Coastguard Worker 
429*48a54d36SAndroid Build Coastguard Worker 	// Do the operation
430*48a54d36SAndroid Build Coastguard Worker 	err = mDNS_StartBrowse(&mDNSStorage, &x->q, &t, &d, mDNSInterface_Any, (flags & kDNSServiceFlagsForceMulticast) != 0, FoundInstance, x);
431*48a54d36SAndroid Build Coastguard Worker 	if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_StartBrowse"; goto fail; }
432*48a54d36SAndroid Build Coastguard Worker 
433*48a54d36SAndroid Build Coastguard Worker 	// Succeeded: Wrap up and return
434*48a54d36SAndroid Build Coastguard Worker 	*sdRef = (DNSServiceRef)x;
435*48a54d36SAndroid Build Coastguard Worker 	return(mStatus_NoError);
436*48a54d36SAndroid Build Coastguard Worker 
437*48a54d36SAndroid Build Coastguard Worker badparam:
438*48a54d36SAndroid Build Coastguard Worker 	err = mStatus_BadParamErr;
439*48a54d36SAndroid Build Coastguard Worker fail:
440*48a54d36SAndroid Build Coastguard Worker 	LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err);
441*48a54d36SAndroid Build Coastguard Worker 	return(err);
442*48a54d36SAndroid Build Coastguard Worker 	}
443*48a54d36SAndroid Build Coastguard Worker 
444*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
445*48a54d36SAndroid Build Coastguard Worker // Resolve Service Info
446*48a54d36SAndroid Build Coastguard Worker 
DNSServiceResolveDispose(mDNS_DirectOP * op)447*48a54d36SAndroid Build Coastguard Worker static void DNSServiceResolveDispose(mDNS_DirectOP *op)
448*48a54d36SAndroid Build Coastguard Worker 	{
449*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Resolve *x = (mDNS_DirectOP_Resolve*)op;
450*48a54d36SAndroid Build Coastguard Worker 	if (x->qSRV.ThisQInterval >= 0) mDNS_StopQuery(&mDNSStorage, &x->qSRV);
451*48a54d36SAndroid Build Coastguard Worker 	if (x->qTXT.ThisQInterval >= 0) mDNS_StopQuery(&mDNSStorage, &x->qTXT);
452*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemFree(x);
453*48a54d36SAndroid Build Coastguard Worker 	}
454*48a54d36SAndroid Build Coastguard Worker 
FoundServiceInfo(mDNS * const m,DNSQuestion * question,const ResourceRecord * const answer,QC_result AddRecord)455*48a54d36SAndroid Build Coastguard Worker mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
456*48a54d36SAndroid Build Coastguard Worker 	{
457*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Resolve *x = (mDNS_DirectOP_Resolve*)question->QuestionContext;
458*48a54d36SAndroid Build Coastguard Worker 	(void)m;	// Unused
459*48a54d36SAndroid Build Coastguard Worker 	if (!AddRecord)
460*48a54d36SAndroid Build Coastguard Worker 		{
461*48a54d36SAndroid Build Coastguard Worker 		if (answer->rrtype == kDNSType_SRV && x->SRV == answer) x->SRV = mDNSNULL;
462*48a54d36SAndroid Build Coastguard Worker 		if (answer->rrtype == kDNSType_TXT && x->TXT == answer) x->TXT = mDNSNULL;
463*48a54d36SAndroid Build Coastguard Worker 		}
464*48a54d36SAndroid Build Coastguard Worker 	else
465*48a54d36SAndroid Build Coastguard Worker 		{
466*48a54d36SAndroid Build Coastguard Worker 		if (answer->rrtype == kDNSType_SRV) x->SRV = answer;
467*48a54d36SAndroid Build Coastguard Worker 		if (answer->rrtype == kDNSType_TXT) x->TXT = answer;
468*48a54d36SAndroid Build Coastguard Worker 		if (x->SRV && x->TXT && x->callback)
469*48a54d36SAndroid Build Coastguard Worker 			{
470*48a54d36SAndroid Build Coastguard Worker 			char fullname[MAX_ESCAPED_DOMAIN_NAME], targethost[MAX_ESCAPED_DOMAIN_NAME];
471*48a54d36SAndroid Build Coastguard Worker 		    ConvertDomainNameToCString(answer->name, fullname);
472*48a54d36SAndroid Build Coastguard Worker 		    ConvertDomainNameToCString(&x->SRV->rdata->u.srv.target, targethost);
473*48a54d36SAndroid Build Coastguard Worker 			x->callback((DNSServiceRef)x, 0, 0, kDNSServiceErr_NoError, fullname, targethost,
474*48a54d36SAndroid Build Coastguard Worker 				x->SRV->rdata->u.srv.port.NotAnInteger, x->TXT->rdlength, (unsigned char*)x->TXT->rdata->u.txt.c, x->context);
475*48a54d36SAndroid Build Coastguard Worker 			}
476*48a54d36SAndroid Build Coastguard Worker 		}
477*48a54d36SAndroid Build Coastguard Worker 	}
478*48a54d36SAndroid Build Coastguard Worker 
DNSServiceResolve(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * name,const char * regtype,const char * domain,DNSServiceResolveReply callback,void * context)479*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceResolve
480*48a54d36SAndroid Build Coastguard Worker 	(
481*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       *sdRef,
482*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
483*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            interfaceIndex,
484*48a54d36SAndroid Build Coastguard Worker 	const char                          *name,
485*48a54d36SAndroid Build Coastguard Worker 	const char                          *regtype,
486*48a54d36SAndroid Build Coastguard Worker 	const char                          *domain,
487*48a54d36SAndroid Build Coastguard Worker 	DNSServiceResolveReply              callback,
488*48a54d36SAndroid Build Coastguard Worker 	void                                *context  /* may be NULL */
489*48a54d36SAndroid Build Coastguard Worker 	)
490*48a54d36SAndroid Build Coastguard Worker 	{
491*48a54d36SAndroid Build Coastguard Worker 	mStatus err = mStatus_NoError;
492*48a54d36SAndroid Build Coastguard Worker 	const char *errormsg = "Unknown";
493*48a54d36SAndroid Build Coastguard Worker 	domainlabel n;
494*48a54d36SAndroid Build Coastguard Worker 	domainname t, d, srv;
495*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_Resolve *x;
496*48a54d36SAndroid Build Coastguard Worker 
497*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
498*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
499*48a54d36SAndroid Build Coastguard Worker 
500*48a54d36SAndroid Build Coastguard Worker 	// Check parameters
501*48a54d36SAndroid Build Coastguard Worker 	if (!name[0]    || !MakeDomainLabelFromLiteralString(&n, name  )) { errormsg = "Bad Instance Name"; goto badparam; }
502*48a54d36SAndroid Build Coastguard Worker 	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Bad Service Type";  goto badparam; }
503*48a54d36SAndroid Build Coastguard Worker 	if (!domain[0]  || !MakeDomainNameFromDNSNameString(&d, domain )) { errormsg = "Bad Domain";        goto badparam; }
504*48a54d36SAndroid Build Coastguard Worker 	if (!ConstructServiceName(&srv, &n, &t, &d))                      { errormsg = "Bad Name";          goto badparam; }
505*48a54d36SAndroid Build Coastguard Worker 
506*48a54d36SAndroid Build Coastguard Worker 	// Allocate memory, and handle failure
507*48a54d36SAndroid Build Coastguard Worker 	x = (mDNS_DirectOP_Resolve *)mDNSPlatformMemAllocate(sizeof(*x));
508*48a54d36SAndroid Build Coastguard Worker 	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
509*48a54d36SAndroid Build Coastguard Worker 
510*48a54d36SAndroid Build Coastguard Worker 	// Set up object
511*48a54d36SAndroid Build Coastguard Worker 	x->disposefn = DNSServiceResolveDispose;
512*48a54d36SAndroid Build Coastguard Worker 	x->callback  = callback;
513*48a54d36SAndroid Build Coastguard Worker 	x->context   = context;
514*48a54d36SAndroid Build Coastguard Worker 	x->SRV       = mDNSNULL;
515*48a54d36SAndroid Build Coastguard Worker 	x->TXT       = mDNSNULL;
516*48a54d36SAndroid Build Coastguard Worker 
517*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
518*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.InterfaceID         = mDNSInterface_Any;
519*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.Target              = zeroAddr;
520*48a54d36SAndroid Build Coastguard Worker 	AssignDomainName(&x->qSRV.qname, &srv);
521*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.qtype               = kDNSType_SRV;
522*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.qclass              = kDNSClass_IN;
523*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.LongLived           = mDNSfalse;
524*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.ExpectUnique        = mDNStrue;
525*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.ForceMCast          = mDNSfalse;
526*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.ReturnIntermed      = mDNSfalse;
527*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.SuppressUnusable    = mDNSfalse;
528*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.SearchListIndex     = 0;
529*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.AppendSearchDomains = 0;
530*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.RetryWithSearchDomains = mDNSfalse;
531*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.TimeoutQuestion     = 0;
532*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.WakeOnResolve       = 0;
533*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.qnameOrig           = mDNSNULL;
534*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.QuestionCallback    = FoundServiceInfo;
535*48a54d36SAndroid Build Coastguard Worker 	x->qSRV.QuestionContext     = x;
536*48a54d36SAndroid Build Coastguard Worker 
537*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
538*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.InterfaceID         = mDNSInterface_Any;
539*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.Target              = zeroAddr;
540*48a54d36SAndroid Build Coastguard Worker 	AssignDomainName(&x->qTXT.qname, &srv);
541*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.qtype               = kDNSType_TXT;
542*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.qclass              = kDNSClass_IN;
543*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.LongLived           = mDNSfalse;
544*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.ExpectUnique        = mDNStrue;
545*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.ForceMCast          = mDNSfalse;
546*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.ReturnIntermed      = mDNSfalse;
547*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.SuppressUnusable    = mDNSfalse;
548*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.SearchListIndex     = 0;
549*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.AppendSearchDomains = 0;
550*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.RetryWithSearchDomains = mDNSfalse;
551*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.TimeoutQuestion     = 0;
552*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.WakeOnResolve       = 0;
553*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.qnameOrig           = mDNSNULL;
554*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.QuestionCallback    = FoundServiceInfo;
555*48a54d36SAndroid Build Coastguard Worker 	x->qTXT.QuestionContext     = x;
556*48a54d36SAndroid Build Coastguard Worker 
557*48a54d36SAndroid Build Coastguard Worker 	err = mDNS_StartQuery(&mDNSStorage, &x->qSRV);
558*48a54d36SAndroid Build Coastguard Worker 	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qSRV"; goto fail; }
559*48a54d36SAndroid Build Coastguard Worker 	err = mDNS_StartQuery(&mDNSStorage, &x->qTXT);
560*48a54d36SAndroid Build Coastguard Worker 	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qTXT"; goto fail; }
561*48a54d36SAndroid Build Coastguard Worker 
562*48a54d36SAndroid Build Coastguard Worker 	// Succeeded: Wrap up and return
563*48a54d36SAndroid Build Coastguard Worker 	*sdRef = (DNSServiceRef)x;
564*48a54d36SAndroid Build Coastguard Worker 	return(mStatus_NoError);
565*48a54d36SAndroid Build Coastguard Worker 
566*48a54d36SAndroid Build Coastguard Worker badparam:
567*48a54d36SAndroid Build Coastguard Worker 	err = mStatus_BadParamErr;
568*48a54d36SAndroid Build Coastguard Worker fail:
569*48a54d36SAndroid Build Coastguard Worker 	LogMsg("DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%ld)", name, regtype, domain, errormsg, err);
570*48a54d36SAndroid Build Coastguard Worker 	return(err);
571*48a54d36SAndroid Build Coastguard Worker 	}
572*48a54d36SAndroid Build Coastguard Worker 
573*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
574*48a54d36SAndroid Build Coastguard Worker // Connection-oriented calls
575*48a54d36SAndroid Build Coastguard Worker 
576*48a54d36SAndroid Build Coastguard Worker // Not yet implemented, so don't include in stub library
577*48a54d36SAndroid Build Coastguard Worker // We DO include it in the actual Extension, so that if a later client compiled to use this
578*48a54d36SAndroid Build Coastguard Worker // is run against this Extension, it will get a reasonable error code instead of just
579*48a54d36SAndroid Build Coastguard Worker // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
580*48a54d36SAndroid Build Coastguard Worker #if !MDNS_BUILDINGSTUBLIBRARY
DNSServiceCreateConnection(DNSServiceRef * sdRef)581*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef)
582*48a54d36SAndroid Build Coastguard Worker 	{
583*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;	// Unused
584*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
585*48a54d36SAndroid Build Coastguard Worker 	}
586*48a54d36SAndroid Build Coastguard Worker 
DNSServiceRegisterRecord(DNSServiceRef sdRef,DNSRecordRef * RecordRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * fullname,uint16_t rrtype,uint16_t rrclass,uint16_t rdlen,const void * rdata,uint32_t ttl,DNSServiceRegisterRecordReply callback,void * context)587*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceRegisterRecord
588*48a54d36SAndroid Build Coastguard Worker 	(
589*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       sdRef,
590*48a54d36SAndroid Build Coastguard Worker 	DNSRecordRef                        *RecordRef,
591*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
592*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            interfaceIndex,
593*48a54d36SAndroid Build Coastguard Worker 	const char                          *fullname,
594*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rrtype,
595*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rrclass,
596*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rdlen,
597*48a54d36SAndroid Build Coastguard Worker 	const void                          *rdata,
598*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            ttl,
599*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRegisterRecordReply       callback,
600*48a54d36SAndroid Build Coastguard Worker 	void                                *context    /* may be NULL */
601*48a54d36SAndroid Build Coastguard Worker 	)
602*48a54d36SAndroid Build Coastguard Worker 	{
603*48a54d36SAndroid Build Coastguard Worker 	(void)sdRef;			// Unused
604*48a54d36SAndroid Build Coastguard Worker 	(void)RecordRef;		// Unused
605*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
606*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
607*48a54d36SAndroid Build Coastguard Worker 	(void)fullname;			// Unused
608*48a54d36SAndroid Build Coastguard Worker 	(void)rrtype;			// Unused
609*48a54d36SAndroid Build Coastguard Worker 	(void)rrclass;			// Unused
610*48a54d36SAndroid Build Coastguard Worker 	(void)rdlen;			// Unused
611*48a54d36SAndroid Build Coastguard Worker 	(void)rdata;			// Unused
612*48a54d36SAndroid Build Coastguard Worker 	(void)ttl;				// Unused
613*48a54d36SAndroid Build Coastguard Worker 	(void)callback;			// Unused
614*48a54d36SAndroid Build Coastguard Worker 	(void)context;			// Unused
615*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
616*48a54d36SAndroid Build Coastguard Worker 	}
617*48a54d36SAndroid Build Coastguard Worker #endif
618*48a54d36SAndroid Build Coastguard Worker 
619*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
620*48a54d36SAndroid Build Coastguard Worker // DNSServiceQueryRecord
621*48a54d36SAndroid Build Coastguard Worker 
DNSServiceQueryRecordDispose(mDNS_DirectOP * op)622*48a54d36SAndroid Build Coastguard Worker static void DNSServiceQueryRecordDispose(mDNS_DirectOP *op)
623*48a54d36SAndroid Build Coastguard Worker 	{
624*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_QueryRecord *x = (mDNS_DirectOP_QueryRecord*)op;
625*48a54d36SAndroid Build Coastguard Worker 	if (x->q.ThisQInterval >= 0) mDNS_StopQuery(&mDNSStorage, &x->q);
626*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemFree(x);
627*48a54d36SAndroid Build Coastguard Worker 	}
628*48a54d36SAndroid Build Coastguard Worker 
DNSServiceQueryRecordResponse(mDNS * const m,DNSQuestion * question,const ResourceRecord * const answer,QC_result AddRecord)629*48a54d36SAndroid Build Coastguard Worker mDNSlocal void DNSServiceQueryRecordResponse(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
630*48a54d36SAndroid Build Coastguard Worker 	{
631*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_QueryRecord *x = (mDNS_DirectOP_QueryRecord*)question->QuestionContext;
632*48a54d36SAndroid Build Coastguard Worker 	char fullname[MAX_ESCAPED_DOMAIN_NAME];
633*48a54d36SAndroid Build Coastguard Worker 	(void)m;	// Unused
634*48a54d36SAndroid Build Coastguard Worker 	ConvertDomainNameToCString(answer->name, fullname);
635*48a54d36SAndroid Build Coastguard Worker 	x->callback((DNSServiceRef)x, AddRecord ? kDNSServiceFlagsAdd : (DNSServiceFlags)0, 0, kDNSServiceErr_NoError,
636*48a54d36SAndroid Build Coastguard Worker 		fullname, answer->rrtype, answer->rrclass, answer->rdlength, answer->rdata->u.data, answer->rroriginalttl, x->context);
637*48a54d36SAndroid Build Coastguard Worker 	}
638*48a54d36SAndroid Build Coastguard Worker 
DNSServiceQueryRecord(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * fullname,uint16_t rrtype,uint16_t rrclass,DNSServiceQueryRecordReply callback,void * context)639*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSServiceQueryRecord
640*48a54d36SAndroid Build Coastguard Worker 	(
641*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef                       *sdRef,
642*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                     flags,
643*48a54d36SAndroid Build Coastguard Worker 	uint32_t                            interfaceIndex,
644*48a54d36SAndroid Build Coastguard Worker 	const char                          *fullname,
645*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rrtype,
646*48a54d36SAndroid Build Coastguard Worker 	uint16_t                            rrclass,
647*48a54d36SAndroid Build Coastguard Worker 	DNSServiceQueryRecordReply          callback,
648*48a54d36SAndroid Build Coastguard Worker 	void                                *context  /* may be NULL */
649*48a54d36SAndroid Build Coastguard Worker 	)
650*48a54d36SAndroid Build Coastguard Worker 	{
651*48a54d36SAndroid Build Coastguard Worker 	mStatus err = mStatus_NoError;
652*48a54d36SAndroid Build Coastguard Worker 	const char *errormsg = "Unknown";
653*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_QueryRecord *x;
654*48a54d36SAndroid Build Coastguard Worker 
655*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
656*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
657*48a54d36SAndroid Build Coastguard Worker 
658*48a54d36SAndroid Build Coastguard Worker 	// Allocate memory, and handle failure
659*48a54d36SAndroid Build Coastguard Worker 	x = (mDNS_DirectOP_QueryRecord *)mDNSPlatformMemAllocate(sizeof(*x));
660*48a54d36SAndroid Build Coastguard Worker 	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
661*48a54d36SAndroid Build Coastguard Worker 
662*48a54d36SAndroid Build Coastguard Worker 	// Set up object
663*48a54d36SAndroid Build Coastguard Worker 	x->disposefn = DNSServiceQueryRecordDispose;
664*48a54d36SAndroid Build Coastguard Worker 	x->callback  = callback;
665*48a54d36SAndroid Build Coastguard Worker 	x->context   = context;
666*48a54d36SAndroid Build Coastguard Worker 
667*48a54d36SAndroid Build Coastguard Worker 	x->q.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
668*48a54d36SAndroid Build Coastguard Worker 	x->q.InterfaceID         = mDNSInterface_Any;
669*48a54d36SAndroid Build Coastguard Worker 	x->q.Target              = zeroAddr;
670*48a54d36SAndroid Build Coastguard Worker 	MakeDomainNameFromDNSNameString(&x->q.qname, fullname);
671*48a54d36SAndroid Build Coastguard Worker 	x->q.qtype               = rrtype;
672*48a54d36SAndroid Build Coastguard Worker 	x->q.qclass              = rrclass;
673*48a54d36SAndroid Build Coastguard Worker 	x->q.LongLived           = (flags & kDNSServiceFlagsLongLivedQuery) != 0;
674*48a54d36SAndroid Build Coastguard Worker 	x->q.ExpectUnique        = mDNSfalse;
675*48a54d36SAndroid Build Coastguard Worker 	x->q.ForceMCast          = (flags & kDNSServiceFlagsForceMulticast) != 0;
676*48a54d36SAndroid Build Coastguard Worker 	x->q.ReturnIntermed      = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
677*48a54d36SAndroid Build Coastguard Worker 	x->q.SuppressUnusable     = (flags & kDNSServiceFlagsSuppressUnusable) != 0;
678*48a54d36SAndroid Build Coastguard Worker 	x->q.SearchListIndex     = 0;
679*48a54d36SAndroid Build Coastguard Worker 	x->q.AppendSearchDomains = 0;
680*48a54d36SAndroid Build Coastguard Worker 	x->q.RetryWithSearchDomains = mDNSfalse;
681*48a54d36SAndroid Build Coastguard Worker 	x->q.WakeOnResolve       = 0;
682*48a54d36SAndroid Build Coastguard Worker 	x->q.qnameOrig           = mDNSNULL;
683*48a54d36SAndroid Build Coastguard Worker 	x->q.QuestionCallback    = DNSServiceQueryRecordResponse;
684*48a54d36SAndroid Build Coastguard Worker 	x->q.QuestionContext     = x;
685*48a54d36SAndroid Build Coastguard Worker 
686*48a54d36SAndroid Build Coastguard Worker 	err = mDNS_StartQuery(&mDNSStorage, &x->q);
687*48a54d36SAndroid Build Coastguard Worker 	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery"; goto fail; }
688*48a54d36SAndroid Build Coastguard Worker 
689*48a54d36SAndroid Build Coastguard Worker 	// Succeeded: Wrap up and return
690*48a54d36SAndroid Build Coastguard Worker 	*sdRef = (DNSServiceRef)x;
691*48a54d36SAndroid Build Coastguard Worker 	return(mStatus_NoError);
692*48a54d36SAndroid Build Coastguard Worker 
693*48a54d36SAndroid Build Coastguard Worker fail:
694*48a54d36SAndroid Build Coastguard Worker 	LogMsg("DNSServiceQueryRecord(\"%s\", %d, %d) failed: %s (%ld)", fullname, rrtype, rrclass, errormsg, err);
695*48a54d36SAndroid Build Coastguard Worker 	return(err);
696*48a54d36SAndroid Build Coastguard Worker 	}
697*48a54d36SAndroid Build Coastguard Worker 
698*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
699*48a54d36SAndroid Build Coastguard Worker // DNSServiceGetAddrInfo
700*48a54d36SAndroid Build Coastguard Worker 
DNSServiceGetAddrInfoDispose(mDNS_DirectOP * op)701*48a54d36SAndroid Build Coastguard Worker static void DNSServiceGetAddrInfoDispose(mDNS_DirectOP *op)
702*48a54d36SAndroid Build Coastguard Worker 	{
703*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_GetAddrInfo *x = (mDNS_DirectOP_GetAddrInfo*)op;
704*48a54d36SAndroid Build Coastguard Worker 	if (x->aQuery) DNSServiceRefDeallocate(x->aQuery);
705*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemFree(x);
706*48a54d36SAndroid Build Coastguard Worker 	}
707*48a54d36SAndroid Build Coastguard Worker 
DNSServiceGetAddrInfoResponse(DNSServiceRef inRef,DNSServiceFlags inFlags,uint32_t inInterfaceIndex,DNSServiceErrorType inErrorCode,const char * inFullName,uint16_t inRRType,uint16_t inRRClass,uint16_t inRDLen,const void * inRData,uint32_t inTTL,void * inContext)708*48a54d36SAndroid Build Coastguard Worker static void DNSSD_API DNSServiceGetAddrInfoResponse(
709*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef		inRef,
710*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags		inFlags,
711*48a54d36SAndroid Build Coastguard Worker 	uint32_t			inInterfaceIndex,
712*48a54d36SAndroid Build Coastguard Worker 	DNSServiceErrorType	inErrorCode,
713*48a54d36SAndroid Build Coastguard Worker 	const char *		inFullName,
714*48a54d36SAndroid Build Coastguard Worker 	uint16_t			inRRType,
715*48a54d36SAndroid Build Coastguard Worker 	uint16_t			inRRClass,
716*48a54d36SAndroid Build Coastguard Worker 	uint16_t			inRDLen,
717*48a54d36SAndroid Build Coastguard Worker 	const void *		inRData,
718*48a54d36SAndroid Build Coastguard Worker 	uint32_t			inTTL,
719*48a54d36SAndroid Build Coastguard Worker 	void *				inContext )
720*48a54d36SAndroid Build Coastguard Worker 	{
721*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_GetAddrInfo *		x = (mDNS_DirectOP_GetAddrInfo*)inContext;
722*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in				sa4;
723*48a54d36SAndroid Build Coastguard Worker 
724*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero(&sa4, sizeof(sa4));
725*48a54d36SAndroid Build Coastguard Worker 	if (inErrorCode == kDNSServiceErr_NoError && inRRType == kDNSServiceType_A)
726*48a54d36SAndroid Build Coastguard Worker 		{
727*48a54d36SAndroid Build Coastguard Worker 		sa4.sin_family = AF_INET;
728*48a54d36SAndroid Build Coastguard Worker 		mDNSPlatformMemCopy(&sa4.sin_addr.s_addr, inRData, 4);
729*48a54d36SAndroid Build Coastguard Worker 		}
730*48a54d36SAndroid Build Coastguard Worker 
731*48a54d36SAndroid Build Coastguard Worker 	x->callback((DNSServiceRef)x, inFlags, inInterfaceIndex, inErrorCode, inFullName,
732*48a54d36SAndroid Build Coastguard Worker 		(const struct sockaddr *) &sa4, inTTL, x->context);
733*48a54d36SAndroid Build Coastguard Worker 	}
734*48a54d36SAndroid Build Coastguard Worker 
DNSServiceGetAddrInfo(DNSServiceRef * outRef,DNSServiceFlags inFlags,uint32_t inInterfaceIndex,DNSServiceProtocol inProtocol,const char * inHostName,DNSServiceGetAddrInfoReply inCallback,void * inContext)735*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo(
736*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef *				outRef,
737*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags				inFlags,
738*48a54d36SAndroid Build Coastguard Worker 	uint32_t					inInterfaceIndex,
739*48a54d36SAndroid Build Coastguard Worker 	DNSServiceProtocol			inProtocol,
740*48a54d36SAndroid Build Coastguard Worker 	const char *				inHostName,
741*48a54d36SAndroid Build Coastguard Worker 	DNSServiceGetAddrInfoReply	inCallback,
742*48a54d36SAndroid Build Coastguard Worker 	void *						inContext )
743*48a54d36SAndroid Build Coastguard Worker 	{
744*48a54d36SAndroid Build Coastguard Worker 	const char *					errormsg = "Unknown";
745*48a54d36SAndroid Build Coastguard Worker 	DNSServiceErrorType				err;
746*48a54d36SAndroid Build Coastguard Worker 	mDNS_DirectOP_GetAddrInfo *		x;
747*48a54d36SAndroid Build Coastguard Worker 
748*48a54d36SAndroid Build Coastguard Worker 	// Allocate memory, and handle failure
749*48a54d36SAndroid Build Coastguard Worker 	x = (mDNS_DirectOP_GetAddrInfo *)mDNSPlatformMemAllocate(sizeof(*x));
750*48a54d36SAndroid Build Coastguard Worker 	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
751*48a54d36SAndroid Build Coastguard Worker 
752*48a54d36SAndroid Build Coastguard Worker 	// Set up object
753*48a54d36SAndroid Build Coastguard Worker 	x->disposefn = DNSServiceGetAddrInfoDispose;
754*48a54d36SAndroid Build Coastguard Worker 	x->callback  = inCallback;
755*48a54d36SAndroid Build Coastguard Worker 	x->context   = inContext;
756*48a54d36SAndroid Build Coastguard Worker 	x->aQuery    = mDNSNULL;
757*48a54d36SAndroid Build Coastguard Worker 
758*48a54d36SAndroid Build Coastguard Worker 	// Start the query.
759*48a54d36SAndroid Build Coastguard Worker 	// (It would probably be more efficient to code this using mDNS_StartQuery directly,
760*48a54d36SAndroid Build Coastguard Worker 	// instead of wrapping DNSServiceQueryRecord, which then unnecessarily allocates
761*48a54d36SAndroid Build Coastguard Worker 	// more memory and then just calls through to mDNS_StartQuery. -- SC June 2010)
762*48a54d36SAndroid Build Coastguard Worker 	err = DNSServiceQueryRecord(&x->aQuery, inFlags, inInterfaceIndex, inHostName, kDNSServiceType_A,
763*48a54d36SAndroid Build Coastguard Worker 		kDNSServiceClass_IN, DNSServiceGetAddrInfoResponse, x);
764*48a54d36SAndroid Build Coastguard Worker 	if (err) { DNSServiceGetAddrInfoDispose((mDNS_DirectOP*)x); errormsg = "DNSServiceQueryRecord"; goto fail; }
765*48a54d36SAndroid Build Coastguard Worker 
766*48a54d36SAndroid Build Coastguard Worker 	*outRef = (DNSServiceRef)x;
767*48a54d36SAndroid Build Coastguard Worker 	return(mStatus_NoError);
768*48a54d36SAndroid Build Coastguard Worker 
769*48a54d36SAndroid Build Coastguard Worker fail:
770*48a54d36SAndroid Build Coastguard Worker 	LogMsg("DNSServiceGetAddrInfo(\"%s\", %d) failed: %s (%ld)", inHostName, inProtocol, errormsg, err);
771*48a54d36SAndroid Build Coastguard Worker 	return(err);
772*48a54d36SAndroid Build Coastguard Worker 	}
773*48a54d36SAndroid Build Coastguard Worker 
774*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
775*48a54d36SAndroid Build Coastguard Worker // DNSServiceReconfirmRecord
776*48a54d36SAndroid Build Coastguard Worker 
777*48a54d36SAndroid Build Coastguard Worker // Not yet implemented, so don't include in stub library
778*48a54d36SAndroid Build Coastguard Worker // We DO include it in the actual Extension, so that if a later client compiled to use this
779*48a54d36SAndroid Build Coastguard Worker // is run against this Extension, it will get a reasonable error code instead of just
780*48a54d36SAndroid Build Coastguard Worker // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link)
781*48a54d36SAndroid Build Coastguard Worker #if !MDNS_BUILDINGSTUBLIBRARY
DNSServiceReconfirmRecord(DNSServiceFlags flags,uint32_t interfaceIndex,const char * fullname,uint16_t rrtype,uint16_t rrclass,uint16_t rdlen,const void * rdata)782*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
783*48a54d36SAndroid Build Coastguard Worker 	(
784*48a54d36SAndroid Build Coastguard Worker 	DNSServiceFlags                    flags,
785*48a54d36SAndroid Build Coastguard Worker 	uint32_t                           interfaceIndex,
786*48a54d36SAndroid Build Coastguard Worker 	const char                         *fullname,
787*48a54d36SAndroid Build Coastguard Worker 	uint16_t                           rrtype,
788*48a54d36SAndroid Build Coastguard Worker 	uint16_t                           rrclass,
789*48a54d36SAndroid Build Coastguard Worker 	uint16_t                           rdlen,
790*48a54d36SAndroid Build Coastguard Worker 	const void                         *rdata
791*48a54d36SAndroid Build Coastguard Worker 	)
792*48a54d36SAndroid Build Coastguard Worker 	{
793*48a54d36SAndroid Build Coastguard Worker 	(void)flags;			// Unused
794*48a54d36SAndroid Build Coastguard Worker 	(void)interfaceIndex;	// Unused
795*48a54d36SAndroid Build Coastguard Worker 	(void)fullname;			// Unused
796*48a54d36SAndroid Build Coastguard Worker 	(void)rrtype;			// Unused
797*48a54d36SAndroid Build Coastguard Worker 	(void)rrclass;			// Unused
798*48a54d36SAndroid Build Coastguard Worker 	(void)rdlen;			// Unused
799*48a54d36SAndroid Build Coastguard Worker 	(void)rdata;			// Unused
800*48a54d36SAndroid Build Coastguard Worker 	return(kDNSServiceErr_Unsupported);
801*48a54d36SAndroid Build Coastguard Worker 	}
802*48a54d36SAndroid Build Coastguard Worker #endif
803