xref: /aosp_15_r20/external/mdnsresponder/mDNSWindows/mDNSWin32.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) 2002-2004 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 	To Do:
18*48a54d36SAndroid Build Coastguard Worker 
19*48a54d36SAndroid Build Coastguard Worker 	- Get unicode name of machine for nice name instead of just the host name.
20*48a54d36SAndroid Build Coastguard Worker 	- Use the IPv6 Internet Connection Firewall API to allow IPv6 mDNS without manually changing the firewall.
21*48a54d36SAndroid Build Coastguard Worker 	- Get DNS server address(es) from Windows and provide them to the uDNS layer.
22*48a54d36SAndroid Build Coastguard Worker 	- Implement TCP support for truncated packets (only stubs now).
23*48a54d36SAndroid Build Coastguard Worker 
24*48a54d36SAndroid Build Coastguard Worker */
25*48a54d36SAndroid Build Coastguard Worker 
26*48a54d36SAndroid Build Coastguard Worker #include	<stdarg.h>
27*48a54d36SAndroid Build Coastguard Worker #include	<stddef.h>
28*48a54d36SAndroid Build Coastguard Worker #include	<stdio.h>
29*48a54d36SAndroid Build Coastguard Worker #include	<stdlib.h>
30*48a54d36SAndroid Build Coastguard Worker #include	<crtdbg.h>
31*48a54d36SAndroid Build Coastguard Worker #include	<string.h>
32*48a54d36SAndroid Build Coastguard Worker 
33*48a54d36SAndroid Build Coastguard Worker #include	"CommonServices.h"
34*48a54d36SAndroid Build Coastguard Worker #include	"DebugServices.h"
35*48a54d36SAndroid Build Coastguard Worker #include	"Firewall.h"
36*48a54d36SAndroid Build Coastguard Worker #include	"RegNames.h"
37*48a54d36SAndroid Build Coastguard Worker #include	"Secret.h"
38*48a54d36SAndroid Build Coastguard Worker #include	<dns_sd.h>
39*48a54d36SAndroid Build Coastguard Worker 
40*48a54d36SAndroid Build Coastguard Worker #include	<Iphlpapi.h>
41*48a54d36SAndroid Build Coastguard Worker #include	<mswsock.h>
42*48a54d36SAndroid Build Coastguard Worker #include	<process.h>
43*48a54d36SAndroid Build Coastguard Worker #include	<ntsecapi.h>
44*48a54d36SAndroid Build Coastguard Worker #include	<lm.h>
45*48a54d36SAndroid Build Coastguard Worker #include	<winioctl.h>
46*48a54d36SAndroid Build Coastguard Worker #include	<ntddndis.h>        // This defines the IOCTL constants.
47*48a54d36SAndroid Build Coastguard Worker 
48*48a54d36SAndroid Build Coastguard Worker #include	"mDNSEmbeddedAPI.h"
49*48a54d36SAndroid Build Coastguard Worker #include	"GenLinkedList.h"
50*48a54d36SAndroid Build Coastguard Worker #include	"DNSCommon.h"
51*48a54d36SAndroid Build Coastguard Worker #include	"mDNSWin32.h"
52*48a54d36SAndroid Build Coastguard Worker 
53*48a54d36SAndroid Build Coastguard Worker #if 0
54*48a54d36SAndroid Build Coastguard Worker #pragma mark == Constants ==
55*48a54d36SAndroid Build Coastguard Worker #endif
56*48a54d36SAndroid Build Coastguard Worker 
57*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
58*48a54d36SAndroid Build Coastguard Worker //	Constants
59*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
60*48a54d36SAndroid Build Coastguard Worker 
61*48a54d36SAndroid Build Coastguard Worker #define	DEBUG_NAME									"[mDNSWin32] "
62*48a54d36SAndroid Build Coastguard Worker 
63*48a54d36SAndroid Build Coastguard Worker #define	MDNS_WINDOWS_USE_IPV6_IF_ADDRS				1
64*48a54d36SAndroid Build Coastguard Worker #define	MDNS_WINDOWS_ENABLE_IPV4					1
65*48a54d36SAndroid Build Coastguard Worker #define	MDNS_WINDOWS_ENABLE_IPV6					1
66*48a54d36SAndroid Build Coastguard Worker #define	MDNS_FIX_IPHLPAPI_PREFIX_BUG				1
67*48a54d36SAndroid Build Coastguard Worker #define MDNS_SET_HINFO_STRINGS						0
68*48a54d36SAndroid Build Coastguard Worker 
69*48a54d36SAndroid Build Coastguard Worker #define	kMDNSDefaultName							"My Computer"
70*48a54d36SAndroid Build Coastguard Worker 
71*48a54d36SAndroid Build Coastguard Worker #define	kWinSockMajorMin							2
72*48a54d36SAndroid Build Coastguard Worker #define	kWinSockMinorMin							2
73*48a54d36SAndroid Build Coastguard Worker 
74*48a54d36SAndroid Build Coastguard Worker #define kRegistryMaxKeyLength						255
75*48a54d36SAndroid Build Coastguard Worker #define kRegistryMaxValueName						16383
76*48a54d36SAndroid Build Coastguard Worker 
77*48a54d36SAndroid Build Coastguard Worker static GUID											kWSARecvMsgGUID = WSAID_WSARECVMSG;
78*48a54d36SAndroid Build Coastguard Worker 
79*48a54d36SAndroid Build Coastguard Worker #define kIPv6IfIndexBase							(10000000L)
80*48a54d36SAndroid Build Coastguard Worker #define SMBPortAsNumber								445
81*48a54d36SAndroid Build Coastguard Worker #define DEVICE_PREFIX								"\\\\.\\"
82*48a54d36SAndroid Build Coastguard Worker 
83*48a54d36SAndroid Build Coastguard Worker #if 0
84*48a54d36SAndroid Build Coastguard Worker #pragma mark == Prototypes ==
85*48a54d36SAndroid Build Coastguard Worker #endif
86*48a54d36SAndroid Build Coastguard Worker 
87*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
88*48a54d36SAndroid Build Coastguard Worker //	Prototypes
89*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
90*48a54d36SAndroid Build Coastguard Worker 
91*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			SetupNiceName( mDNS * const inMDNS );
92*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			SetupHostName( mDNS * const inMDNS );
93*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			SetupName( mDNS * const inMDNS );
94*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inIFA, mDNSInterfaceData **outIFD );
95*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			TearDownInterface( mDNS * const inMDNS, mDNSInterfaceData *inIFD );
96*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK		FreeInterface( mDNSInterfaceData *inIFD );
97*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAddr, mDNSIPPort port, SocketRef *outSocketRef  );
98*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort );
99*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus			GetWindowsVersionString( char *inBuffer, size_t inBufferSize );
100*48a54d36SAndroid Build Coastguard Worker mDNSlocal int				getifaddrs( struct ifaddrs **outAddrs );
101*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				freeifaddrs( struct ifaddrs *inAddrs );
102*48a54d36SAndroid Build Coastguard Worker 
103*48a54d36SAndroid Build Coastguard Worker 
104*48a54d36SAndroid Build Coastguard Worker 
105*48a54d36SAndroid Build Coastguard Worker // Platform Accessors
106*48a54d36SAndroid Build Coastguard Worker 
107*48a54d36SAndroid Build Coastguard Worker #ifdef	__cplusplus
108*48a54d36SAndroid Build Coastguard Worker 	extern "C" {
109*48a54d36SAndroid Build Coastguard Worker #endif
110*48a54d36SAndroid Build Coastguard Worker 
111*48a54d36SAndroid Build Coastguard Worker typedef struct mDNSPlatformInterfaceInfo	mDNSPlatformInterfaceInfo;
112*48a54d36SAndroid Build Coastguard Worker struct	mDNSPlatformInterfaceInfo
113*48a54d36SAndroid Build Coastguard Worker {
114*48a54d36SAndroid Build Coastguard Worker 	const char *		name;
115*48a54d36SAndroid Build Coastguard Worker 	mDNSAddr			ip;
116*48a54d36SAndroid Build Coastguard Worker };
117*48a54d36SAndroid Build Coastguard Worker 
118*48a54d36SAndroid Build Coastguard Worker 
119*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus	mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID );
120*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus	mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo );
121*48a54d36SAndroid Build Coastguard Worker 
122*48a54d36SAndroid Build Coastguard Worker // Utilities
123*48a54d36SAndroid Build Coastguard Worker 
124*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
125*48a54d36SAndroid Build Coastguard Worker 	mDNSlocal int	getifaddrs_ipv6( struct ifaddrs **outAddrs );
126*48a54d36SAndroid Build Coastguard Worker #endif
127*48a54d36SAndroid Build Coastguard Worker 
128*48a54d36SAndroid Build Coastguard Worker mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs );
129*48a54d36SAndroid Build Coastguard Worker 
130*48a54d36SAndroid Build Coastguard Worker 
131*48a54d36SAndroid Build Coastguard Worker mDNSlocal DWORD				GetPrimaryInterface();
132*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			AddressToIndexAndMask( struct sockaddr * address, uint32_t * index, struct sockaddr * mask );
133*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNSBool			CanReceiveUnicast( void );
134*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNSBool			IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr );
135*48a54d36SAndroid Build Coastguard Worker 
136*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			StringToAddress( mDNSAddr * ip, LPSTR string );
137*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			RegQueryString( HKEY key, LPCSTR param, LPSTR * string, DWORD * stringLen, DWORD * enabled );
138*48a54d36SAndroid Build Coastguard Worker mDNSlocal struct ifaddrs*	myGetIfAddrs(int refresh);
139*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus			TCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize );
140*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus			WindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize );
141*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				TCPDidConnect( mDNS * const inMDNS, HANDLE event, void * context );
142*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				TCPCanRead( TCPSocket * sock );
143*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus			TCPBeginRecv( TCPSocket * sock );
144*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK		TCPEndRecv( DWORD error, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags );
145*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				TCPCloseSocket( TCPSocket * socket );
146*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK		TCPFreeSocket( TCPSocket *sock );
147*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus			UDPBeginRecv( UDPSocket * socket );
148*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK		UDPEndRecv( DWORD err, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags );
149*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				UDPCloseSocket( UDPSocket * sock );
150*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK		UDPFreeSocket( UDPSocket * sock );
151*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus           SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa);
152*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				GetDDNSFQDN( domainname *const fqdn );
153*48a54d36SAndroid Build Coastguard Worker #ifdef UNICODE
154*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey );
155*48a54d36SAndroid Build Coastguard Worker #else
156*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				GetDDNSDomains( DNameListElem ** domains, LPCSTR lpSubKey );
157*48a54d36SAndroid Build Coastguard Worker #endif
158*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				SetDomainSecrets( mDNS * const inMDNS );
159*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				SetDomainSecret( mDNS * const m, const domainname * inDomain );
160*48a54d36SAndroid Build Coastguard Worker mDNSlocal VOID CALLBACK		CheckFileSharesProc( LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue );
161*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				CheckFileShares( mDNS * const inMDNS );
162*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				SMBCallback(mDNS *const m, ServiceRecordSet *const srs, mStatus result);
163*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNSu8			IsWOMPEnabledForAdapter( const char * adapterName );
164*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				DispatchUDPEvent( mDNS * const m, UDPSocket * sock );
165*48a54d36SAndroid Build Coastguard Worker mDNSlocal void				DispatchTCPEvent( mDNS * const m, TCPSocket * sock );
166*48a54d36SAndroid Build Coastguard Worker 
167*48a54d36SAndroid Build Coastguard Worker #ifdef	__cplusplus
168*48a54d36SAndroid Build Coastguard Worker 	}
169*48a54d36SAndroid Build Coastguard Worker #endif
170*48a54d36SAndroid Build Coastguard Worker 
171*48a54d36SAndroid Build Coastguard Worker #if 0
172*48a54d36SAndroid Build Coastguard Worker #pragma mark == Globals ==
173*48a54d36SAndroid Build Coastguard Worker #endif
174*48a54d36SAndroid Build Coastguard Worker 
175*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
176*48a54d36SAndroid Build Coastguard Worker //	Globals
177*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
178*48a54d36SAndroid Build Coastguard Worker 
179*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNS_PlatformSupport	gMDNSPlatformSupport;
180*48a54d36SAndroid Build Coastguard Worker mDNSs32							mDNSPlatformOneSecond	= 0;
181*48a54d36SAndroid Build Coastguard Worker mDNSlocal UDPSocket		*		gUDPSockets				= NULL;
182*48a54d36SAndroid Build Coastguard Worker mDNSlocal int					gUDPNumSockets			= 0;
183*48a54d36SAndroid Build Coastguard Worker mDNSlocal GenLinkedList			gUDPDispatchableSockets;
184*48a54d36SAndroid Build Coastguard Worker mDNSlocal GenLinkedList			gTCPDispatchableSockets;
185*48a54d36SAndroid Build Coastguard Worker 
186*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
187*48a54d36SAndroid Build Coastguard Worker 
188*48a54d36SAndroid Build Coastguard Worker 	typedef DWORD
189*48a54d36SAndroid Build Coastguard Worker 		( WINAPI * GetAdaptersAddressesFunctionPtr )(
190*48a54d36SAndroid Build Coastguard Worker 			ULONG 					inFamily,
191*48a54d36SAndroid Build Coastguard Worker 			DWORD 					inFlags,
192*48a54d36SAndroid Build Coastguard Worker 			PVOID 					inReserved,
193*48a54d36SAndroid Build Coastguard Worker 			PIP_ADAPTER_ADDRESSES 	inAdapter,
194*48a54d36SAndroid Build Coastguard Worker 			PULONG					outBufferSize );
195*48a54d36SAndroid Build Coastguard Worker 
196*48a54d36SAndroid Build Coastguard Worker 	mDNSlocal HMODULE								gIPHelperLibraryInstance			= NULL;
197*48a54d36SAndroid Build Coastguard Worker 	mDNSlocal GetAdaptersAddressesFunctionPtr		gGetAdaptersAddressesFunctionPtr	= NULL;
198*48a54d36SAndroid Build Coastguard Worker 
199*48a54d36SAndroid Build Coastguard Worker #endif
200*48a54d36SAndroid Build Coastguard Worker 
201*48a54d36SAndroid Build Coastguard Worker 
202*48a54d36SAndroid Build Coastguard Worker #ifndef HCRYPTPROV
203*48a54d36SAndroid Build Coastguard Worker    typedef ULONG_PTR HCRYPTPROV;    // WinCrypt.h, line 249
204*48a54d36SAndroid Build Coastguard Worker #endif
205*48a54d36SAndroid Build Coastguard Worker 
206*48a54d36SAndroid Build Coastguard Worker 
207*48a54d36SAndroid Build Coastguard Worker #ifndef CRYPT_MACHINE_KEYSET
208*48a54d36SAndroid Build Coastguard Worker #	define CRYPT_MACHINE_KEYSET    0x00000020
209*48a54d36SAndroid Build Coastguard Worker #endif
210*48a54d36SAndroid Build Coastguard Worker 
211*48a54d36SAndroid Build Coastguard Worker #ifndef CRYPT_NEWKEYSET
212*48a54d36SAndroid Build Coastguard Worker #	define CRYPT_NEWKEYSET         0x00000008
213*48a54d36SAndroid Build Coastguard Worker #endif
214*48a54d36SAndroid Build Coastguard Worker 
215*48a54d36SAndroid Build Coastguard Worker #ifndef PROV_RSA_FULL
216*48a54d36SAndroid Build Coastguard Worker #  define PROV_RSA_FULL 1
217*48a54d36SAndroid Build Coastguard Worker #endif
218*48a54d36SAndroid Build Coastguard Worker 
219*48a54d36SAndroid Build Coastguard Worker typedef BOOL (__stdcall *fnCryptGenRandom)( HCRYPTPROV, DWORD, BYTE* );
220*48a54d36SAndroid Build Coastguard Worker typedef BOOL (__stdcall *fnCryptAcquireContext)( HCRYPTPROV*, LPCTSTR, LPCTSTR, DWORD, DWORD);
221*48a54d36SAndroid Build Coastguard Worker typedef BOOL (__stdcall *fnCryptReleaseContext)(HCRYPTPROV, DWORD);
222*48a54d36SAndroid Build Coastguard Worker 
223*48a54d36SAndroid Build Coastguard Worker static fnCryptAcquireContext g_lpCryptAcquireContext 	= NULL;
224*48a54d36SAndroid Build Coastguard Worker static fnCryptReleaseContext g_lpCryptReleaseContext 	= NULL;
225*48a54d36SAndroid Build Coastguard Worker static fnCryptGenRandom		 g_lpCryptGenRandom 		= NULL;
226*48a54d36SAndroid Build Coastguard Worker static HINSTANCE			 g_hAAPI32 					= NULL;
227*48a54d36SAndroid Build Coastguard Worker static HCRYPTPROV			 g_hProvider 				= ( ULONG_PTR ) NULL;
228*48a54d36SAndroid Build Coastguard Worker 
229*48a54d36SAndroid Build Coastguard Worker 
230*48a54d36SAndroid Build Coastguard Worker typedef DNSServiceErrorType ( DNSSD_API *DNSServiceRegisterFunc )
231*48a54d36SAndroid Build Coastguard Worker     (
232*48a54d36SAndroid Build Coastguard Worker     DNSServiceRef                       *sdRef,
233*48a54d36SAndroid Build Coastguard Worker     DNSServiceFlags                     flags,
234*48a54d36SAndroid Build Coastguard Worker     uint32_t                            interfaceIndex,
235*48a54d36SAndroid Build Coastguard Worker     const char                          *name,         /* may be NULL */
236*48a54d36SAndroid Build Coastguard Worker     const char                          *regtype,
237*48a54d36SAndroid Build Coastguard Worker     const char                          *domain,       /* may be NULL */
238*48a54d36SAndroid Build Coastguard Worker     const char                          *host,         /* may be NULL */
239*48a54d36SAndroid Build Coastguard Worker     uint16_t                            port,
240*48a54d36SAndroid Build Coastguard Worker     uint16_t                            txtLen,
241*48a54d36SAndroid Build Coastguard Worker     const void                          *txtRecord,    /* may be NULL */
242*48a54d36SAndroid Build Coastguard Worker     DNSServiceRegisterReply             callBack,      /* may be NULL */
243*48a54d36SAndroid Build Coastguard Worker     void                                *context       /* may be NULL */
244*48a54d36SAndroid Build Coastguard Worker     );
245*48a54d36SAndroid Build Coastguard Worker 
246*48a54d36SAndroid Build Coastguard Worker 
247*48a54d36SAndroid Build Coastguard Worker typedef void ( DNSSD_API *DNSServiceRefDeallocateFunc )( DNSServiceRef sdRef );
248*48a54d36SAndroid Build Coastguard Worker 
249*48a54d36SAndroid Build Coastguard Worker mDNSlocal HMODULE					gDNSSDLibrary				= NULL;
250*48a54d36SAndroid Build Coastguard Worker mDNSlocal DNSServiceRegisterFunc	gDNSServiceRegister			= NULL;
251*48a54d36SAndroid Build Coastguard Worker mDNSlocal DNSServiceRefDeallocateFunc gDNSServiceRefDeallocate	= NULL;
252*48a54d36SAndroid Build Coastguard Worker mDNSlocal HANDLE					gSMBThread					= NULL;
253*48a54d36SAndroid Build Coastguard Worker mDNSlocal HANDLE					gSMBThreadRegisterEvent		= NULL;
254*48a54d36SAndroid Build Coastguard Worker mDNSlocal HANDLE					gSMBThreadDeregisterEvent	= NULL;
255*48a54d36SAndroid Build Coastguard Worker mDNSlocal HANDLE					gSMBThreadStopEvent			= NULL;
256*48a54d36SAndroid Build Coastguard Worker mDNSlocal HANDLE					gSMBThreadQuitEvent			= NULL;
257*48a54d36SAndroid Build Coastguard Worker 
258*48a54d36SAndroid Build Coastguard Worker #define	kSMBStopEvent				( WAIT_OBJECT_0 + 0 )
259*48a54d36SAndroid Build Coastguard Worker #define	kSMBRegisterEvent			( WAIT_OBJECT_0 + 1 )
260*48a54d36SAndroid Build Coastguard Worker #define kSMBDeregisterEvent			( WAIT_OBJECT_0 + 2 )
261*48a54d36SAndroid Build Coastguard Worker 
262*48a54d36SAndroid Build Coastguard Worker 
263*48a54d36SAndroid Build Coastguard Worker #if 0
264*48a54d36SAndroid Build Coastguard Worker #pragma mark -
265*48a54d36SAndroid Build Coastguard Worker #pragma mark == Platform Support ==
266*48a54d36SAndroid Build Coastguard Worker #endif
267*48a54d36SAndroid Build Coastguard Worker 
268*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
269*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformInit
270*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
271*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformInit(mDNS * const inMDNS)272*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus	mDNSPlatformInit( mDNS * const inMDNS )
273*48a54d36SAndroid Build Coastguard Worker {
274*48a54d36SAndroid Build Coastguard Worker 	mStatus		err;
275*48a54d36SAndroid Build Coastguard Worker 	WSADATA		wsaData;
276*48a54d36SAndroid Build Coastguard Worker 	int			supported;
277*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in	sa4;
278*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in6 sa6;
279*48a54d36SAndroid Build Coastguard Worker 	int					sa4len;
280*48a54d36SAndroid Build Coastguard Worker 	int					sa6len;
281*48a54d36SAndroid Build Coastguard Worker 	DWORD				size;
282*48a54d36SAndroid Build Coastguard Worker 	DWORD				val;
283*48a54d36SAndroid Build Coastguard Worker 
284*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "platform init\n" );
285*48a54d36SAndroid Build Coastguard Worker 
286*48a54d36SAndroid Build Coastguard Worker 	// Initialize variables. If the PlatformSupport pointer is not null then just assume that a non-Apple client is
287*48a54d36SAndroid Build Coastguard Worker 	// calling mDNS_Init and wants to provide its own storage for the platform-specific data so do not overwrite it.
288*48a54d36SAndroid Build Coastguard Worker 
289*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero( &gMDNSPlatformSupport, sizeof( gMDNSPlatformSupport ) );
290*48a54d36SAndroid Build Coastguard Worker 	if( !inMDNS->p ) inMDNS->p				= &gMDNSPlatformSupport;
291*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->mainThread					= OpenThread( THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId() );
292*48a54d36SAndroid Build Coastguard Worker 	require_action( inMDNS->p->mainThread, exit, err = mStatus_UnknownErr );
293*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->checkFileSharesTimer = CreateWaitableTimer( NULL, FALSE, NULL );
294*48a54d36SAndroid Build Coastguard Worker 	require_action( inMDNS->p->checkFileSharesTimer, exit, err = mStatus_UnknownErr );
295*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->checkFileSharesTimeout		= 10;		// Retry time for CheckFileShares() in seconds
296*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformOneSecond 					= 1000;		// Use milliseconds as the quantum of time
297*48a54d36SAndroid Build Coastguard Worker 	InitLinkedList( &gTCPDispatchableSockets, offsetof( TCPSocket, nextDispatchable ) );
298*48a54d36SAndroid Build Coastguard Worker 	InitLinkedList( &gUDPDispatchableSockets, offsetof( UDPSocket, nextDispatchable ) );
299*48a54d36SAndroid Build Coastguard Worker 
300*48a54d36SAndroid Build Coastguard Worker 	// Startup WinSock 2.2 or later.
301*48a54d36SAndroid Build Coastguard Worker 
302*48a54d36SAndroid Build Coastguard Worker 	err = WSAStartup( MAKEWORD( kWinSockMajorMin, kWinSockMinorMin ), &wsaData );
303*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
304*48a54d36SAndroid Build Coastguard Worker 
305*48a54d36SAndroid Build Coastguard Worker 	supported = ( ( LOBYTE( wsaData.wVersion ) == kWinSockMajorMin ) && ( HIBYTE( wsaData.wVersion ) == kWinSockMinorMin ) );
306*48a54d36SAndroid Build Coastguard Worker 	require_action( supported, exit, err = mStatus_UnsupportedErr );
307*48a54d36SAndroid Build Coastguard Worker 
308*48a54d36SAndroid Build Coastguard Worker 	inMDNS->CanReceiveUnicastOn5353 = CanReceiveUnicast();
309*48a54d36SAndroid Build Coastguard Worker 
310*48a54d36SAndroid Build Coastguard Worker 	// Setup the HINFO HW strings.
311*48a54d36SAndroid Build Coastguard Worker 	//<rdar://problem/7245119> device-info should have model=Windows
312*48a54d36SAndroid Build Coastguard Worker 
313*48a54d36SAndroid Build Coastguard Worker 	strcpy_s( ( char* ) &inMDNS->HIHardware.c[ 1 ], sizeof( inMDNS->HIHardware.c ) - 2, "Windows" );
314*48a54d36SAndroid Build Coastguard Worker 	inMDNS->HIHardware.c[ 0 ] = ( mDNSu8 ) mDNSPlatformStrLen( &inMDNS->HIHardware.c[ 1 ] );
315*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "HIHardware: %#s\n", inMDNS->HIHardware.c );
316*48a54d36SAndroid Build Coastguard Worker 
317*48a54d36SAndroid Build Coastguard Worker 	// Setup the HINFO SW strings.
318*48a54d36SAndroid Build Coastguard Worker #if ( MDNS_SET_HINFO_STRINGS )
319*48a54d36SAndroid Build Coastguard Worker 	mDNS_snprintf( (char *) &inMDNS->HISoftware.c[ 1 ], sizeof( inMDNS->HISoftware.c ) - 2,
320*48a54d36SAndroid Build Coastguard Worker 		"mDNSResponder (%s %s)", __DATE__, __TIME__ );
321*48a54d36SAndroid Build Coastguard Worker 	inMDNS->HISoftware.c[ 0 ] = (mDNSu8) mDNSPlatformStrLen( &inMDNS->HISoftware.c[ 1 ] );
322*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "HISoftware: %#s\n", inMDNS->HISoftware.c );
323*48a54d36SAndroid Build Coastguard Worker #endif
324*48a54d36SAndroid Build Coastguard Worker 
325*48a54d36SAndroid Build Coastguard Worker 	// Set the thread global overlapped flag
326*48a54d36SAndroid Build Coastguard Worker 
327*48a54d36SAndroid Build Coastguard Worker 	val = 0;
328*48a54d36SAndroid Build Coastguard Worker 	err = setsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, ( char* ) &val, sizeof( val ) );
329*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err != SOCKET_ERROR, WSAGetLastError(), kUnknownErr );
330*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
331*48a54d36SAndroid Build Coastguard Worker 
332*48a54d36SAndroid Build Coastguard Worker 	// Set up the IPv4 unicast socket
333*48a54d36SAndroid Build Coastguard Worker 
334*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.fd			= INVALID_SOCKET;
335*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.recvMsgPtr	= NULL;
336*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.ifd			= NULL;
337*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.overlapped.pending = FALSE;
338*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.next		= NULL;
339*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.m			= inMDNS;
340*48a54d36SAndroid Build Coastguard Worker 
341*48a54d36SAndroid Build Coastguard Worker #if ( MDNS_WINDOWS_ENABLE_IPV4 )
342*48a54d36SAndroid Build Coastguard Worker 
343*48a54d36SAndroid Build Coastguard Worker 	sa4.sin_family		= AF_INET;
344*48a54d36SAndroid Build Coastguard Worker 	sa4.sin_addr.s_addr = INADDR_ANY;
345*48a54d36SAndroid Build Coastguard Worker 	err = SetupSocket( inMDNS, (const struct sockaddr*) &sa4, zeroIPPort, &inMDNS->p->unicastSock4.fd );
346*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
347*48a54d36SAndroid Build Coastguard Worker 	sa4len = sizeof( sa4 );
348*48a54d36SAndroid Build Coastguard Worker 	err = getsockname( inMDNS->p->unicastSock4.fd, (struct sockaddr*) &sa4, &sa4len );
349*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
350*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock4.port.NotAnInteger = sa4.sin_port;
351*48a54d36SAndroid Build Coastguard Worker 	inMDNS->UnicastPort4 = inMDNS->p->unicastSock4.port;
352*48a54d36SAndroid Build Coastguard Worker 	err = WSAIoctl( inMDNS->p->unicastSock4.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &inMDNS->p->unicastSock4.recvMsgPtr, sizeof( inMDNS->p->unicastSock4.recvMsgPtr ), &size, NULL, NULL );
353*48a54d36SAndroid Build Coastguard Worker 
354*48a54d36SAndroid Build Coastguard Worker 	if ( err )
355*48a54d36SAndroid Build Coastguard Worker 	{
356*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->unicastSock4.recvMsgPtr = NULL;
357*48a54d36SAndroid Build Coastguard Worker 	}
358*48a54d36SAndroid Build Coastguard Worker 
359*48a54d36SAndroid Build Coastguard Worker 	err = UDPBeginRecv( &inMDNS->p->unicastSock4 );
360*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
361*48a54d36SAndroid Build Coastguard Worker 
362*48a54d36SAndroid Build Coastguard Worker #endif
363*48a54d36SAndroid Build Coastguard Worker 
364*48a54d36SAndroid Build Coastguard Worker 	// Set up the IPv6 unicast socket
365*48a54d36SAndroid Build Coastguard Worker 
366*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock6.fd			= INVALID_SOCKET;
367*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock6.recvMsgPtr	= NULL;
368*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock6.ifd			= NULL;
369*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock6.overlapped.pending = FALSE;
370*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock6.next		= NULL;
371*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->unicastSock6.m			= inMDNS;
372*48a54d36SAndroid Build Coastguard Worker 
373*48a54d36SAndroid Build Coastguard Worker #if ( MDNS_WINDOWS_ENABLE_IPV6 )
374*48a54d36SAndroid Build Coastguard Worker 
375*48a54d36SAndroid Build Coastguard Worker 	sa6.sin6_family		= AF_INET6;
376*48a54d36SAndroid Build Coastguard Worker 	sa6.sin6_addr		= in6addr_any;
377*48a54d36SAndroid Build Coastguard Worker 	sa6.sin6_scope_id	= 0;
378*48a54d36SAndroid Build Coastguard Worker 
379*48a54d36SAndroid Build Coastguard Worker 	// This call will fail if the machine hasn't installed IPv6.  In that case,
380*48a54d36SAndroid Build Coastguard Worker 	// the error will be WSAEAFNOSUPPORT.
381*48a54d36SAndroid Build Coastguard Worker 
382*48a54d36SAndroid Build Coastguard Worker 	err = SetupSocket( inMDNS, (const struct sockaddr*) &sa6, zeroIPPort, &inMDNS->p->unicastSock6.fd );
383*48a54d36SAndroid Build Coastguard Worker 	require_action( !err || ( err == WSAEAFNOSUPPORT ), exit, err = (mStatus) WSAGetLastError() );
384*48a54d36SAndroid Build Coastguard Worker 	err = kNoErr;
385*48a54d36SAndroid Build Coastguard Worker 
386*48a54d36SAndroid Build Coastguard Worker 	// If we weren't able to create the socket (because IPv6 hasn't been installed) don't do this
387*48a54d36SAndroid Build Coastguard Worker 
388*48a54d36SAndroid Build Coastguard Worker 	if ( inMDNS->p->unicastSock6.fd != INVALID_SOCKET )
389*48a54d36SAndroid Build Coastguard Worker 	{
390*48a54d36SAndroid Build Coastguard Worker 		sa6len = sizeof( sa6 );
391*48a54d36SAndroid Build Coastguard Worker 		err = getsockname( inMDNS->p->unicastSock6.fd, (struct sockaddr*) &sa6, &sa6len );
392*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
393*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->unicastSock6.port.NotAnInteger = sa6.sin6_port;
394*48a54d36SAndroid Build Coastguard Worker 		inMDNS->UnicastPort6 = inMDNS->p->unicastSock6.port;
395*48a54d36SAndroid Build Coastguard Worker 
396*48a54d36SAndroid Build Coastguard Worker 		err = WSAIoctl( inMDNS->p->unicastSock6.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &inMDNS->p->unicastSock6.recvMsgPtr, sizeof( inMDNS->p->unicastSock6.recvMsgPtr ), &size, NULL, NULL );
397*48a54d36SAndroid Build Coastguard Worker 
398*48a54d36SAndroid Build Coastguard Worker 		if ( err != 0 )
399*48a54d36SAndroid Build Coastguard Worker 		{
400*48a54d36SAndroid Build Coastguard Worker 			inMDNS->p->unicastSock6.recvMsgPtr = NULL;
401*48a54d36SAndroid Build Coastguard Worker 		}
402*48a54d36SAndroid Build Coastguard Worker 
403*48a54d36SAndroid Build Coastguard Worker 		err = UDPBeginRecv( &inMDNS->p->unicastSock6 );
404*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
405*48a54d36SAndroid Build Coastguard Worker 	}
406*48a54d36SAndroid Build Coastguard Worker 
407*48a54d36SAndroid Build Coastguard Worker #endif
408*48a54d36SAndroid Build Coastguard Worker 
409*48a54d36SAndroid Build Coastguard Worker 	// Notify core of domain secret keys
410*48a54d36SAndroid Build Coastguard Worker 
411*48a54d36SAndroid Build Coastguard Worker 	SetDomainSecrets( inMDNS );
412*48a54d36SAndroid Build Coastguard Worker 
413*48a54d36SAndroid Build Coastguard Worker 	// Success!
414*48a54d36SAndroid Build Coastguard Worker 
415*48a54d36SAndroid Build Coastguard Worker 	mDNSCoreInitComplete( inMDNS, err );
416*48a54d36SAndroid Build Coastguard Worker 
417*48a54d36SAndroid Build Coastguard Worker 
418*48a54d36SAndroid Build Coastguard Worker exit:
419*48a54d36SAndroid Build Coastguard Worker 
420*48a54d36SAndroid Build Coastguard Worker 	if ( err )
421*48a54d36SAndroid Build Coastguard Worker 	{
422*48a54d36SAndroid Build Coastguard Worker 		mDNSPlatformClose( inMDNS );
423*48a54d36SAndroid Build Coastguard Worker 	}
424*48a54d36SAndroid Build Coastguard Worker 
425*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "platform init done (err=%d %m)\n", err, err );
426*48a54d36SAndroid Build Coastguard Worker 	return( err );
427*48a54d36SAndroid Build Coastguard Worker }
428*48a54d36SAndroid Build Coastguard Worker 
429*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
430*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformClose
431*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
432*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformClose(mDNS * const inMDNS)433*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformClose( mDNS * const inMDNS )
434*48a54d36SAndroid Build Coastguard Worker {
435*48a54d36SAndroid Build Coastguard Worker 	mStatus		err;
436*48a54d36SAndroid Build Coastguard Worker 
437*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "platform close\n" );
438*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
439*48a54d36SAndroid Build Coastguard Worker 
440*48a54d36SAndroid Build Coastguard Worker 	if ( gSMBThread != NULL )
441*48a54d36SAndroid Build Coastguard Worker 	{
442*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelTrace, DEBUG_NAME "tearing down smb registration thread\n" );
443*48a54d36SAndroid Build Coastguard Worker 		SetEvent( gSMBThreadStopEvent );
444*48a54d36SAndroid Build Coastguard Worker 
445*48a54d36SAndroid Build Coastguard Worker 		if ( WaitForSingleObject( gSMBThreadQuitEvent, 5 * 1000 ) == WAIT_OBJECT_0 )
446*48a54d36SAndroid Build Coastguard Worker 		{
447*48a54d36SAndroid Build Coastguard Worker 			if ( gSMBThreadQuitEvent )
448*48a54d36SAndroid Build Coastguard Worker 			{
449*48a54d36SAndroid Build Coastguard Worker 				CloseHandle( gSMBThreadQuitEvent );
450*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadQuitEvent = NULL;
451*48a54d36SAndroid Build Coastguard Worker 			}
452*48a54d36SAndroid Build Coastguard Worker 
453*48a54d36SAndroid Build Coastguard Worker 			if ( gSMBThreadStopEvent )
454*48a54d36SAndroid Build Coastguard Worker 			{
455*48a54d36SAndroid Build Coastguard Worker 				CloseHandle( gSMBThreadStopEvent );
456*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadStopEvent = NULL;
457*48a54d36SAndroid Build Coastguard Worker 			}
458*48a54d36SAndroid Build Coastguard Worker 
459*48a54d36SAndroid Build Coastguard Worker 			if ( gSMBThreadDeregisterEvent )
460*48a54d36SAndroid Build Coastguard Worker 			{
461*48a54d36SAndroid Build Coastguard Worker 				CloseHandle( gSMBThreadDeregisterEvent );
462*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadDeregisterEvent = NULL;
463*48a54d36SAndroid Build Coastguard Worker 			}
464*48a54d36SAndroid Build Coastguard Worker 
465*48a54d36SAndroid Build Coastguard Worker 			if ( gSMBThreadRegisterEvent )
466*48a54d36SAndroid Build Coastguard Worker 			{
467*48a54d36SAndroid Build Coastguard Worker 				CloseHandle( gSMBThreadRegisterEvent );
468*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadRegisterEvent = NULL;
469*48a54d36SAndroid Build Coastguard Worker 			}
470*48a54d36SAndroid Build Coastguard Worker 
471*48a54d36SAndroid Build Coastguard Worker 			if ( gDNSSDLibrary )
472*48a54d36SAndroid Build Coastguard Worker 			{
473*48a54d36SAndroid Build Coastguard Worker 				FreeLibrary( gDNSSDLibrary );
474*48a54d36SAndroid Build Coastguard Worker 				gDNSSDLibrary = NULL;
475*48a54d36SAndroid Build Coastguard Worker 			}
476*48a54d36SAndroid Build Coastguard Worker 		}
477*48a54d36SAndroid Build Coastguard Worker 		else
478*48a54d36SAndroid Build Coastguard Worker 		{
479*48a54d36SAndroid Build Coastguard Worker 			LogMsg( "Unable to stop SMBThread" );
480*48a54d36SAndroid Build Coastguard Worker 		}
481*48a54d36SAndroid Build Coastguard Worker 
482*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->smbFileSharing = mDNSfalse;
483*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->smbPrintSharing = mDNSfalse;
484*48a54d36SAndroid Build Coastguard Worker 	}
485*48a54d36SAndroid Build Coastguard Worker 
486*48a54d36SAndroid Build Coastguard Worker 	// Tear everything down in reverse order to how it was set up.
487*48a54d36SAndroid Build Coastguard Worker 
488*48a54d36SAndroid Build Coastguard Worker 	err = TearDownInterfaceList( inMDNS );
489*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
490*48a54d36SAndroid Build Coastguard Worker 	check( !inMDNS->p->inactiveInterfaceList );
491*48a54d36SAndroid Build Coastguard Worker 
492*48a54d36SAndroid Build Coastguard Worker #if ( MDNS_WINDOWS_ENABLE_IPV4 )
493*48a54d36SAndroid Build Coastguard Worker 
494*48a54d36SAndroid Build Coastguard Worker 	UDPCloseSocket( &inMDNS->p->unicastSock4 );
495*48a54d36SAndroid Build Coastguard Worker 
496*48a54d36SAndroid Build Coastguard Worker #endif
497*48a54d36SAndroid Build Coastguard Worker 
498*48a54d36SAndroid Build Coastguard Worker #if ( MDNS_WINDOWS_ENABLE_IPV6 )
499*48a54d36SAndroid Build Coastguard Worker 
500*48a54d36SAndroid Build Coastguard Worker 	UDPCloseSocket( &inMDNS->p->unicastSock6 );
501*48a54d36SAndroid Build Coastguard Worker 
502*48a54d36SAndroid Build Coastguard Worker #endif
503*48a54d36SAndroid Build Coastguard Worker 
504*48a54d36SAndroid Build Coastguard Worker 	// Free the DLL needed for IPv6 support.
505*48a54d36SAndroid Build Coastguard Worker 
506*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
507*48a54d36SAndroid Build Coastguard Worker 	if( gIPHelperLibraryInstance )
508*48a54d36SAndroid Build Coastguard Worker 	{
509*48a54d36SAndroid Build Coastguard Worker 		gGetAdaptersAddressesFunctionPtr = NULL;
510*48a54d36SAndroid Build Coastguard Worker 
511*48a54d36SAndroid Build Coastguard Worker 		FreeLibrary( gIPHelperLibraryInstance );
512*48a54d36SAndroid Build Coastguard Worker 		gIPHelperLibraryInstance = NULL;
513*48a54d36SAndroid Build Coastguard Worker 	}
514*48a54d36SAndroid Build Coastguard Worker #endif
515*48a54d36SAndroid Build Coastguard Worker 
516*48a54d36SAndroid Build Coastguard Worker 	if ( g_hAAPI32 )
517*48a54d36SAndroid Build Coastguard Worker 	{
518*48a54d36SAndroid Build Coastguard Worker 		// Release any resources
519*48a54d36SAndroid Build Coastguard Worker 
520*48a54d36SAndroid Build Coastguard Worker 		if ( g_hProvider && g_lpCryptReleaseContext )
521*48a54d36SAndroid Build Coastguard Worker 		{
522*48a54d36SAndroid Build Coastguard Worker 			( g_lpCryptReleaseContext )( g_hProvider, 0 );
523*48a54d36SAndroid Build Coastguard Worker 		}
524*48a54d36SAndroid Build Coastguard Worker 
525*48a54d36SAndroid Build Coastguard Worker 		// Free the AdvApi32.dll
526*48a54d36SAndroid Build Coastguard Worker 
527*48a54d36SAndroid Build Coastguard Worker 		FreeLibrary( g_hAAPI32 );
528*48a54d36SAndroid Build Coastguard Worker 
529*48a54d36SAndroid Build Coastguard Worker 		// And reset all the data
530*48a54d36SAndroid Build Coastguard Worker 
531*48a54d36SAndroid Build Coastguard Worker 		g_lpCryptAcquireContext = NULL;
532*48a54d36SAndroid Build Coastguard Worker 		g_lpCryptReleaseContext = NULL;
533*48a54d36SAndroid Build Coastguard Worker 		g_lpCryptGenRandom 		= NULL;
534*48a54d36SAndroid Build Coastguard Worker 		g_hProvider 			= ( ULONG_PTR ) NULL;
535*48a54d36SAndroid Build Coastguard Worker 		g_hAAPI32				= NULL;
536*48a54d36SAndroid Build Coastguard Worker 	}
537*48a54d36SAndroid Build Coastguard Worker 
538*48a54d36SAndroid Build Coastguard Worker 	// Clear out the APC queue
539*48a54d36SAndroid Build Coastguard Worker 
540*48a54d36SAndroid Build Coastguard Worker 	while ( SleepEx( 0, TRUE ) == WAIT_IO_COMPLETION )
541*48a54d36SAndroid Build Coastguard Worker 	{
542*48a54d36SAndroid Build Coastguard Worker 		DispatchSocketEvents( inMDNS );
543*48a54d36SAndroid Build Coastguard Worker 	}
544*48a54d36SAndroid Build Coastguard Worker 
545*48a54d36SAndroid Build Coastguard Worker 	WSACleanup();
546*48a54d36SAndroid Build Coastguard Worker 
547*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "platform close done\n" );
548*48a54d36SAndroid Build Coastguard Worker }
549*48a54d36SAndroid Build Coastguard Worker 
550*48a54d36SAndroid Build Coastguard Worker 
551*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
552*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformLock
553*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
554*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformLock(const mDNS * const inMDNS)555*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformLock( const mDNS * const inMDNS )
556*48a54d36SAndroid Build Coastguard Worker {
557*48a54d36SAndroid Build Coastguard Worker 	( void ) inMDNS;
558*48a54d36SAndroid Build Coastguard Worker }
559*48a54d36SAndroid Build Coastguard Worker 
560*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
561*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformUnlock
562*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
563*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformUnlock(const mDNS * const inMDNS)564*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformUnlock( const mDNS * const inMDNS )
565*48a54d36SAndroid Build Coastguard Worker {
566*48a54d36SAndroid Build Coastguard Worker 	( void ) inMDNS;
567*48a54d36SAndroid Build Coastguard Worker }
568*48a54d36SAndroid Build Coastguard Worker 
569*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
570*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformStrCopy
571*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
572*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformStrCopy(void * inDst,const void * inSrc)573*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformStrCopy( void *inDst, const void *inSrc )
574*48a54d36SAndroid Build Coastguard Worker {
575*48a54d36SAndroid Build Coastguard Worker 	check( inSrc );
576*48a54d36SAndroid Build Coastguard Worker 	check( inDst );
577*48a54d36SAndroid Build Coastguard Worker 
578*48a54d36SAndroid Build Coastguard Worker 	strcpy( (char *) inDst, (const char*) inSrc );
579*48a54d36SAndroid Build Coastguard Worker }
580*48a54d36SAndroid Build Coastguard Worker 
581*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
582*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformStrLCopy
583*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
584*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformStrLCopy(void * inDst,const void * inSrc,mDNSu32 inSize)585*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSu32 mDNSPlatformStrLCopy(void *inDst, const void *inSrc, mDNSu32 inSize)
586*48a54d36SAndroid Build Coastguard Worker {
587*48a54d36SAndroid Build Coastguard Worker 	const char *		src = (const char *) inSrc;
588*48a54d36SAndroid Build Coastguard Worker 
589*48a54d36SAndroid Build Coastguard Worker 	if( inSize > 0 )
590*48a54d36SAndroid Build Coastguard Worker 	{
591*48a54d36SAndroid Build Coastguard Worker 		size_t		n;
592*48a54d36SAndroid Build Coastguard Worker 		char *		dst = (char *) inDst;
593*48a54d36SAndroid Build Coastguard Worker 
594*48a54d36SAndroid Build Coastguard Worker 		for( n = inSize - 1; n > 0; --n )
595*48a54d36SAndroid Build Coastguard Worker 		{
596*48a54d36SAndroid Build Coastguard Worker 			if( ( *dst++ = *src++ ) == '\0' )
597*48a54d36SAndroid Build Coastguard Worker 			{
598*48a54d36SAndroid Build Coastguard Worker 				// Null terminator encountered, so exit.
599*48a54d36SAndroid Build Coastguard Worker 				goto exit;
600*48a54d36SAndroid Build Coastguard Worker 			}
601*48a54d36SAndroid Build Coastguard Worker 		}
602*48a54d36SAndroid Build Coastguard Worker 		*dst = '\0';
603*48a54d36SAndroid Build Coastguard Worker 	}
604*48a54d36SAndroid Build Coastguard Worker 
605*48a54d36SAndroid Build Coastguard Worker 	while( *src++ != '\0' )
606*48a54d36SAndroid Build Coastguard Worker 	{
607*48a54d36SAndroid Build Coastguard Worker 		// Stop at null terminator.
608*48a54d36SAndroid Build Coastguard Worker 	}
609*48a54d36SAndroid Build Coastguard Worker 
610*48a54d36SAndroid Build Coastguard Worker exit:
611*48a54d36SAndroid Build Coastguard Worker 	return( (mDNSu32)( src - (const char *) inSrc ) - 1 );
612*48a54d36SAndroid Build Coastguard Worker }
613*48a54d36SAndroid Build Coastguard Worker 
614*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
615*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformStrLen
616*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
617*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformStrLen(const void * inSrc)618*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSu32	mDNSPlatformStrLen( const void *inSrc )
619*48a54d36SAndroid Build Coastguard Worker {
620*48a54d36SAndroid Build Coastguard Worker 	check( inSrc );
621*48a54d36SAndroid Build Coastguard Worker 
622*48a54d36SAndroid Build Coastguard Worker 	return( (mDNSu32) strlen( (const char *) inSrc ) );
623*48a54d36SAndroid Build Coastguard Worker }
624*48a54d36SAndroid Build Coastguard Worker 
625*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
626*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformMemCopy
627*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
628*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformMemCopy(void * inDst,const void * inSrc,mDNSu32 inSize)629*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformMemCopy( void *inDst, const void *inSrc, mDNSu32 inSize )
630*48a54d36SAndroid Build Coastguard Worker {
631*48a54d36SAndroid Build Coastguard Worker 	check( inSrc );
632*48a54d36SAndroid Build Coastguard Worker 	check( inDst );
633*48a54d36SAndroid Build Coastguard Worker 
634*48a54d36SAndroid Build Coastguard Worker 	memcpy( inDst, inSrc, inSize );
635*48a54d36SAndroid Build Coastguard Worker }
636*48a54d36SAndroid Build Coastguard Worker 
637*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
638*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformMemSame
639*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
640*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformMemSame(const void * inDst,const void * inSrc,mDNSu32 inSize)641*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSBool	mDNSPlatformMemSame( const void *inDst, const void *inSrc, mDNSu32 inSize )
642*48a54d36SAndroid Build Coastguard Worker {
643*48a54d36SAndroid Build Coastguard Worker 	check( inSrc );
644*48a54d36SAndroid Build Coastguard Worker 	check( inDst );
645*48a54d36SAndroid Build Coastguard Worker 
646*48a54d36SAndroid Build Coastguard Worker 	return( (mDNSBool)( memcmp( inSrc, inDst, inSize ) == 0 ) );
647*48a54d36SAndroid Build Coastguard Worker }
648*48a54d36SAndroid Build Coastguard Worker 
649*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
650*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformMemZero
651*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
652*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformMemZero(void * inDst,mDNSu32 inSize)653*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformMemZero( void *inDst, mDNSu32 inSize )
654*48a54d36SAndroid Build Coastguard Worker {
655*48a54d36SAndroid Build Coastguard Worker 	check( inDst );
656*48a54d36SAndroid Build Coastguard Worker 
657*48a54d36SAndroid Build Coastguard Worker 	memset( inDst, 0, inSize );
658*48a54d36SAndroid Build Coastguard Worker }
659*48a54d36SAndroid Build Coastguard Worker 
660*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
661*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformMemAllocate
662*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
663*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformMemAllocate(mDNSu32 inSize)664*48a54d36SAndroid Build Coastguard Worker mDNSexport void *	mDNSPlatformMemAllocate( mDNSu32 inSize )
665*48a54d36SAndroid Build Coastguard Worker {
666*48a54d36SAndroid Build Coastguard Worker 	void *		mem;
667*48a54d36SAndroid Build Coastguard Worker 
668*48a54d36SAndroid Build Coastguard Worker 	check( inSize > 0 );
669*48a54d36SAndroid Build Coastguard Worker 
670*48a54d36SAndroid Build Coastguard Worker 	mem = malloc( inSize );
671*48a54d36SAndroid Build Coastguard Worker 	check( mem );
672*48a54d36SAndroid Build Coastguard Worker 
673*48a54d36SAndroid Build Coastguard Worker 	return( mem );
674*48a54d36SAndroid Build Coastguard Worker }
675*48a54d36SAndroid Build Coastguard Worker 
676*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
677*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformMemFree
678*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
679*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformMemFree(void * inMem)680*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformMemFree( void *inMem )
681*48a54d36SAndroid Build Coastguard Worker {
682*48a54d36SAndroid Build Coastguard Worker 	check( inMem );
683*48a54d36SAndroid Build Coastguard Worker 
684*48a54d36SAndroid Build Coastguard Worker 	free( inMem );
685*48a54d36SAndroid Build Coastguard Worker }
686*48a54d36SAndroid Build Coastguard Worker 
687*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
688*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformRandomNumber
689*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
690*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformRandomNumber(void)691*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
692*48a54d36SAndroid Build Coastguard Worker {
693*48a54d36SAndroid Build Coastguard Worker 	mDNSu32		randomNumber = 0;
694*48a54d36SAndroid Build Coastguard Worker 	BOOL		bResult;
695*48a54d36SAndroid Build Coastguard Worker 	OSStatus	err = 0;
696*48a54d36SAndroid Build Coastguard Worker 
697*48a54d36SAndroid Build Coastguard Worker 	if ( !g_hAAPI32 )
698*48a54d36SAndroid Build Coastguard Worker 	{
699*48a54d36SAndroid Build Coastguard Worker 		g_hAAPI32 = LoadLibrary( TEXT("AdvAPI32.dll") );
700*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( g_hAAPI32 != NULL, GetLastError(), mStatus_UnknownErr );
701*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
702*48a54d36SAndroid Build Coastguard Worker 	}
703*48a54d36SAndroid Build Coastguard Worker 
704*48a54d36SAndroid Build Coastguard Worker 	// Function Pointer: CryptAcquireContext
705*48a54d36SAndroid Build Coastguard Worker 
706*48a54d36SAndroid Build Coastguard Worker 	if ( !g_lpCryptAcquireContext )
707*48a54d36SAndroid Build Coastguard Worker 	{
708*48a54d36SAndroid Build Coastguard Worker 		g_lpCryptAcquireContext = ( fnCryptAcquireContext )
709*48a54d36SAndroid Build Coastguard Worker #ifdef UNICODE
710*48a54d36SAndroid Build Coastguard Worker 			( GetProcAddress( g_hAAPI32, "CryptAcquireContextW" ) );
711*48a54d36SAndroid Build Coastguard Worker #else
712*48a54d36SAndroid Build Coastguard Worker 			( GetProcAddress( g_hAAPI32, "CryptAcquireContextA" ) );
713*48a54d36SAndroid Build Coastguard Worker #endif
714*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( g_lpCryptAcquireContext != NULL, GetLastError(), mStatus_UnknownErr );
715*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
716*48a54d36SAndroid Build Coastguard Worker 	}
717*48a54d36SAndroid Build Coastguard Worker 
718*48a54d36SAndroid Build Coastguard Worker 	// Function Pointer: CryptReleaseContext
719*48a54d36SAndroid Build Coastguard Worker 
720*48a54d36SAndroid Build Coastguard Worker 	if ( !g_lpCryptReleaseContext )
721*48a54d36SAndroid Build Coastguard Worker 	{
722*48a54d36SAndroid Build Coastguard Worker 		g_lpCryptReleaseContext = ( fnCryptReleaseContext )
723*48a54d36SAndroid Build Coastguard Worker          ( GetProcAddress( g_hAAPI32, "CryptReleaseContext" ) );
724*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( g_lpCryptReleaseContext != NULL, GetLastError(), mStatus_UnknownErr );
725*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
726*48a54d36SAndroid Build Coastguard Worker 	}
727*48a54d36SAndroid Build Coastguard Worker 
728*48a54d36SAndroid Build Coastguard Worker 	// Function Pointer: CryptGenRandom
729*48a54d36SAndroid Build Coastguard Worker 
730*48a54d36SAndroid Build Coastguard Worker 	if ( !g_lpCryptGenRandom )
731*48a54d36SAndroid Build Coastguard Worker 	{
732*48a54d36SAndroid Build Coastguard Worker 		g_lpCryptGenRandom = ( fnCryptGenRandom )
733*48a54d36SAndroid Build Coastguard Worker           ( GetProcAddress( g_hAAPI32, "CryptGenRandom" ) );
734*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( g_lpCryptGenRandom != NULL, GetLastError(), mStatus_UnknownErr );
735*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
736*48a54d36SAndroid Build Coastguard Worker 	}
737*48a54d36SAndroid Build Coastguard Worker 
738*48a54d36SAndroid Build Coastguard Worker 	// Setup
739*48a54d36SAndroid Build Coastguard Worker 
740*48a54d36SAndroid Build Coastguard Worker 	if ( !g_hProvider )
741*48a54d36SAndroid Build Coastguard Worker 	{
742*48a54d36SAndroid Build Coastguard Worker 		bResult = (*g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET );
743*48a54d36SAndroid Build Coastguard Worker 
744*48a54d36SAndroid Build Coastguard Worker 		if ( !bResult )
745*48a54d36SAndroid Build Coastguard Worker 		{
746*48a54d36SAndroid Build Coastguard Worker 			bResult =  ( *g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET );
747*48a54d36SAndroid Build Coastguard Worker 			err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
748*48a54d36SAndroid Build Coastguard Worker 			require_noerr( err, exit );
749*48a54d36SAndroid Build Coastguard Worker 		}
750*48a54d36SAndroid Build Coastguard Worker 	}
751*48a54d36SAndroid Build Coastguard Worker 
752*48a54d36SAndroid Build Coastguard Worker 	bResult = (*g_lpCryptGenRandom)( g_hProvider, sizeof( randomNumber ), ( BYTE* ) &randomNumber );
753*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
754*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
755*48a54d36SAndroid Build Coastguard Worker 
756*48a54d36SAndroid Build Coastguard Worker exit:
757*48a54d36SAndroid Build Coastguard Worker 
758*48a54d36SAndroid Build Coastguard Worker 	if ( err )
759*48a54d36SAndroid Build Coastguard Worker 	{
760*48a54d36SAndroid Build Coastguard Worker 		randomNumber = rand();
761*48a54d36SAndroid Build Coastguard Worker 	}
762*48a54d36SAndroid Build Coastguard Worker 
763*48a54d36SAndroid Build Coastguard Worker 	return randomNumber;
764*48a54d36SAndroid Build Coastguard Worker }
765*48a54d36SAndroid Build Coastguard Worker 
766*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
767*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTimeInit
768*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
769*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformTimeInit(void)770*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus	mDNSPlatformTimeInit( void )
771*48a54d36SAndroid Build Coastguard Worker {
772*48a54d36SAndroid Build Coastguard Worker 	// No special setup is required on Windows -- we just use GetTickCount().
773*48a54d36SAndroid Build Coastguard Worker 	return( mStatus_NoError );
774*48a54d36SAndroid Build Coastguard Worker }
775*48a54d36SAndroid Build Coastguard Worker 
776*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
777*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformRawTime
778*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
779*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformRawTime(void)780*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSs32	mDNSPlatformRawTime( void )
781*48a54d36SAndroid Build Coastguard Worker {
782*48a54d36SAndroid Build Coastguard Worker 	return( (mDNSs32) GetTickCount() );
783*48a54d36SAndroid Build Coastguard Worker }
784*48a54d36SAndroid Build Coastguard Worker 
785*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
786*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformUTC
787*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
788*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformUTC(void)789*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSs32	mDNSPlatformUTC( void )
790*48a54d36SAndroid Build Coastguard Worker {
791*48a54d36SAndroid Build Coastguard Worker 	return ( mDNSs32 ) time( NULL );
792*48a54d36SAndroid Build Coastguard Worker }
793*48a54d36SAndroid Build Coastguard Worker 
794*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
795*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformInterfaceNameToID
796*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
797*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformInterfaceNameToID(mDNS * const inMDNS,const char * inName,mDNSInterfaceID * outID)798*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus	mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID )
799*48a54d36SAndroid Build Coastguard Worker {
800*48a54d36SAndroid Build Coastguard Worker 	mStatus					err;
801*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData *		ifd;
802*48a54d36SAndroid Build Coastguard Worker 
803*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
804*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS->p );
805*48a54d36SAndroid Build Coastguard Worker 	check( inName );
806*48a54d36SAndroid Build Coastguard Worker 
807*48a54d36SAndroid Build Coastguard Worker 	// Search for an interface with the specified name,
808*48a54d36SAndroid Build Coastguard Worker 
809*48a54d36SAndroid Build Coastguard Worker 	for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
810*48a54d36SAndroid Build Coastguard Worker 	{
811*48a54d36SAndroid Build Coastguard Worker 		if( strcmp( ifd->name, inName ) == 0 )
812*48a54d36SAndroid Build Coastguard Worker 		{
813*48a54d36SAndroid Build Coastguard Worker 			break;
814*48a54d36SAndroid Build Coastguard Worker 		}
815*48a54d36SAndroid Build Coastguard Worker 	}
816*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( ifd, exit, err = mStatus_NoSuchNameErr );
817*48a54d36SAndroid Build Coastguard Worker 
818*48a54d36SAndroid Build Coastguard Worker 	// Success!
819*48a54d36SAndroid Build Coastguard Worker 
820*48a54d36SAndroid Build Coastguard Worker 	if( outID )
821*48a54d36SAndroid Build Coastguard Worker 	{
822*48a54d36SAndroid Build Coastguard Worker 		*outID = (mDNSInterfaceID) ifd;
823*48a54d36SAndroid Build Coastguard Worker 	}
824*48a54d36SAndroid Build Coastguard Worker 	err = mStatus_NoError;
825*48a54d36SAndroid Build Coastguard Worker 
826*48a54d36SAndroid Build Coastguard Worker exit:
827*48a54d36SAndroid Build Coastguard Worker 	return( err );
828*48a54d36SAndroid Build Coastguard Worker }
829*48a54d36SAndroid Build Coastguard Worker 
830*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
831*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformInterfaceIDToInfo
832*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
833*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformInterfaceIDToInfo(mDNS * const inMDNS,mDNSInterfaceID inID,mDNSPlatformInterfaceInfo * outInfo)834*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus	mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo )
835*48a54d36SAndroid Build Coastguard Worker {
836*48a54d36SAndroid Build Coastguard Worker 	mStatus					err;
837*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData *		ifd;
838*48a54d36SAndroid Build Coastguard Worker 
839*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
840*48a54d36SAndroid Build Coastguard Worker 	check( inID );
841*48a54d36SAndroid Build Coastguard Worker 	check( outInfo );
842*48a54d36SAndroid Build Coastguard Worker 
843*48a54d36SAndroid Build Coastguard Worker 	// Search for an interface with the specified ID,
844*48a54d36SAndroid Build Coastguard Worker 
845*48a54d36SAndroid Build Coastguard Worker 	for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
846*48a54d36SAndroid Build Coastguard Worker 	{
847*48a54d36SAndroid Build Coastguard Worker 		if( ifd == (mDNSInterfaceData *) inID )
848*48a54d36SAndroid Build Coastguard Worker 		{
849*48a54d36SAndroid Build Coastguard Worker 			break;
850*48a54d36SAndroid Build Coastguard Worker 		}
851*48a54d36SAndroid Build Coastguard Worker 	}
852*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( ifd, exit, err = mStatus_NoSuchNameErr );
853*48a54d36SAndroid Build Coastguard Worker 
854*48a54d36SAndroid Build Coastguard Worker 	// Success!
855*48a54d36SAndroid Build Coastguard Worker 
856*48a54d36SAndroid Build Coastguard Worker 	outInfo->name 	= ifd->name;
857*48a54d36SAndroid Build Coastguard Worker 	outInfo->ip 	= ifd->interfaceInfo.ip;
858*48a54d36SAndroid Build Coastguard Worker 	err 			= mStatus_NoError;
859*48a54d36SAndroid Build Coastguard Worker 
860*48a54d36SAndroid Build Coastguard Worker exit:
861*48a54d36SAndroid Build Coastguard Worker 	return( err );
862*48a54d36SAndroid Build Coastguard Worker }
863*48a54d36SAndroid Build Coastguard Worker 
864*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
865*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformInterfaceIDfromInterfaceIndex
866*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
867*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS * const inMDNS,mDNSu32 inIndex)868*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSInterfaceID	mDNSPlatformInterfaceIDfromInterfaceIndex( mDNS * const inMDNS, mDNSu32 inIndex )
869*48a54d36SAndroid Build Coastguard Worker {
870*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceID		id;
871*48a54d36SAndroid Build Coastguard Worker 
872*48a54d36SAndroid Build Coastguard Worker 	id = mDNSNULL;
873*48a54d36SAndroid Build Coastguard Worker 	if( inIndex == kDNSServiceInterfaceIndexLocalOnly )
874*48a54d36SAndroid Build Coastguard Worker 	{
875*48a54d36SAndroid Build Coastguard Worker 		id = mDNSInterface_LocalOnly;
876*48a54d36SAndroid Build Coastguard Worker 	}
877*48a54d36SAndroid Build Coastguard Worker 	/* uncomment if Windows ever supports P2P
878*48a54d36SAndroid Build Coastguard Worker 	else if( inIndex == kDNSServiceInterfaceIndexP2P )
879*48a54d36SAndroid Build Coastguard Worker 	{
880*48a54d36SAndroid Build Coastguard Worker 		id = mDNSInterface_P2P;
881*48a54d36SAndroid Build Coastguard Worker 	}
882*48a54d36SAndroid Build Coastguard Worker 	*/
883*48a54d36SAndroid Build Coastguard Worker 	else if( inIndex != 0 )
884*48a54d36SAndroid Build Coastguard Worker 	{
885*48a54d36SAndroid Build Coastguard Worker 		mDNSInterfaceData *		ifd;
886*48a54d36SAndroid Build Coastguard Worker 
887*48a54d36SAndroid Build Coastguard Worker 		for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
888*48a54d36SAndroid Build Coastguard Worker 		{
889*48a54d36SAndroid Build Coastguard Worker 			if( ( ifd->scopeID == inIndex ) && ifd->interfaceInfo.InterfaceActive )
890*48a54d36SAndroid Build Coastguard Worker 			{
891*48a54d36SAndroid Build Coastguard Worker 				id = ifd->interfaceInfo.InterfaceID;
892*48a54d36SAndroid Build Coastguard Worker 				break;
893*48a54d36SAndroid Build Coastguard Worker 			}
894*48a54d36SAndroid Build Coastguard Worker 		}
895*48a54d36SAndroid Build Coastguard Worker 		check( ifd );
896*48a54d36SAndroid Build Coastguard Worker 	}
897*48a54d36SAndroid Build Coastguard Worker 	return( id );
898*48a54d36SAndroid Build Coastguard Worker }
899*48a54d36SAndroid Build Coastguard Worker 
900*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
901*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformInterfaceIndexfromInterfaceID
902*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
903*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformInterfaceIndexfromInterfaceID(mDNS * const inMDNS,mDNSInterfaceID inID,mDNSBool suppressNetworkChange)904*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSu32	mDNSPlatformInterfaceIndexfromInterfaceID( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSBool suppressNetworkChange )
905*48a54d36SAndroid Build Coastguard Worker {
906*48a54d36SAndroid Build Coastguard Worker 	mDNSu32		index;
907*48a54d36SAndroid Build Coastguard Worker 	(void) suppressNetworkChange; // Unused
908*48a54d36SAndroid Build Coastguard Worker 
909*48a54d36SAndroid Build Coastguard Worker 	index = 0;
910*48a54d36SAndroid Build Coastguard Worker 	if( inID == mDNSInterface_LocalOnly )
911*48a54d36SAndroid Build Coastguard Worker 	{
912*48a54d36SAndroid Build Coastguard Worker 		index = (mDNSu32) kDNSServiceInterfaceIndexLocalOnly;
913*48a54d36SAndroid Build Coastguard Worker 	}
914*48a54d36SAndroid Build Coastguard Worker 	/* uncomment if Windows ever supports P2P
915*48a54d36SAndroid Build Coastguard Worker 	else if( inID == mDNSInterface_P2P )
916*48a54d36SAndroid Build Coastguard Worker 	{
917*48a54d36SAndroid Build Coastguard Worker 		index = (mDNSu32) kDNSServiceInterfaceIndexP2P;
918*48a54d36SAndroid Build Coastguard Worker 	}
919*48a54d36SAndroid Build Coastguard Worker 	*/
920*48a54d36SAndroid Build Coastguard Worker 	else if( inID )
921*48a54d36SAndroid Build Coastguard Worker 	{
922*48a54d36SAndroid Build Coastguard Worker 		mDNSInterfaceData *		ifd;
923*48a54d36SAndroid Build Coastguard Worker 
924*48a54d36SAndroid Build Coastguard Worker 		// Search active interfaces.
925*48a54d36SAndroid Build Coastguard Worker 		for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
926*48a54d36SAndroid Build Coastguard Worker 		{
927*48a54d36SAndroid Build Coastguard Worker 			if( (mDNSInterfaceID) ifd == inID )
928*48a54d36SAndroid Build Coastguard Worker 			{
929*48a54d36SAndroid Build Coastguard Worker 				index = ifd->scopeID;
930*48a54d36SAndroid Build Coastguard Worker 				break;
931*48a54d36SAndroid Build Coastguard Worker 			}
932*48a54d36SAndroid Build Coastguard Worker 		}
933*48a54d36SAndroid Build Coastguard Worker 
934*48a54d36SAndroid Build Coastguard Worker 		// Search inactive interfaces too so remove events for inactive interfaces report the old interface index.
935*48a54d36SAndroid Build Coastguard Worker 
936*48a54d36SAndroid Build Coastguard Worker 		if( !ifd )
937*48a54d36SAndroid Build Coastguard Worker 		{
938*48a54d36SAndroid Build Coastguard Worker 			for( ifd = inMDNS->p->inactiveInterfaceList; ifd; ifd = ifd->next )
939*48a54d36SAndroid Build Coastguard Worker 			{
940*48a54d36SAndroid Build Coastguard Worker 				if( (mDNSInterfaceID) ifd == inID )
941*48a54d36SAndroid Build Coastguard Worker 				{
942*48a54d36SAndroid Build Coastguard Worker 					index = ifd->scopeID;
943*48a54d36SAndroid Build Coastguard Worker 					break;
944*48a54d36SAndroid Build Coastguard Worker 				}
945*48a54d36SAndroid Build Coastguard Worker 			}
946*48a54d36SAndroid Build Coastguard Worker 		}
947*48a54d36SAndroid Build Coastguard Worker 		check( ifd );
948*48a54d36SAndroid Build Coastguard Worker 	}
949*48a54d36SAndroid Build Coastguard Worker 	return( index );
950*48a54d36SAndroid Build Coastguard Worker }
951*48a54d36SAndroid Build Coastguard Worker 
952*48a54d36SAndroid Build Coastguard Worker 
953*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
954*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTCPSocket
955*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
956*48a54d36SAndroid Build Coastguard Worker 
957*48a54d36SAndroid Build Coastguard Worker TCPSocket *
mDNSPlatformTCPSocket(mDNS * const m,TCPSocketFlags flags,mDNSIPPort * port)958*48a54d36SAndroid Build Coastguard Worker mDNSPlatformTCPSocket
959*48a54d36SAndroid Build Coastguard Worker 	(
960*48a54d36SAndroid Build Coastguard Worker 	mDNS			* const m,
961*48a54d36SAndroid Build Coastguard Worker 	TCPSocketFlags		flags,
962*48a54d36SAndroid Build Coastguard Worker 	mDNSIPPort			*	port
963*48a54d36SAndroid Build Coastguard Worker 	)
964*48a54d36SAndroid Build Coastguard Worker {
965*48a54d36SAndroid Build Coastguard Worker 	TCPSocket *		sock    = NULL;
966*48a54d36SAndroid Build Coastguard Worker 	u_long				on		= 1;  // "on" for setsockopt
967*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in	saddr;
968*48a54d36SAndroid Build Coastguard Worker 	int					len;
969*48a54d36SAndroid Build Coastguard Worker 	mStatus				err		= mStatus_NoError;
970*48a54d36SAndroid Build Coastguard Worker 
971*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( m );
972*48a54d36SAndroid Build Coastguard Worker 
973*48a54d36SAndroid Build Coastguard Worker 	require_action( flags == 0, exit, err = mStatus_UnsupportedErr );
974*48a54d36SAndroid Build Coastguard Worker 
975*48a54d36SAndroid Build Coastguard Worker 	// Setup connection data object
976*48a54d36SAndroid Build Coastguard Worker 
977*48a54d36SAndroid Build Coastguard Worker 	sock = (TCPSocket *) malloc( sizeof( TCPSocket ) );
978*48a54d36SAndroid Build Coastguard Worker 	require_action( sock, exit, err = mStatus_NoMemoryErr );
979*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
980*48a54d36SAndroid Build Coastguard Worker 	sock->fd		= INVALID_SOCKET;
981*48a54d36SAndroid Build Coastguard Worker 	sock->flags		= flags;
982*48a54d36SAndroid Build Coastguard Worker 	sock->m			= m;
983*48a54d36SAndroid Build Coastguard Worker 
984*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero(&saddr, sizeof(saddr));
985*48a54d36SAndroid Build Coastguard Worker 	saddr.sin_family		= AF_INET;
986*48a54d36SAndroid Build Coastguard Worker 	saddr.sin_addr.s_addr	= htonl( INADDR_ANY );
987*48a54d36SAndroid Build Coastguard Worker 	saddr.sin_port			= port->NotAnInteger;
988*48a54d36SAndroid Build Coastguard Worker 
989*48a54d36SAndroid Build Coastguard Worker 	// Create the socket
990*48a54d36SAndroid Build Coastguard Worker 
991*48a54d36SAndroid Build Coastguard Worker 	sock->fd = socket(AF_INET, SOCK_STREAM, 0);
992*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( sock->fd != INVALID_SOCKET, WSAGetLastError(), mStatus_UnknownErr );
993*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
994*48a54d36SAndroid Build Coastguard Worker 
995*48a54d36SAndroid Build Coastguard Worker 	// bind
996*48a54d36SAndroid Build Coastguard Worker 
997*48a54d36SAndroid Build Coastguard Worker 	err = bind( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr )  );
998*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
999*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1000*48a54d36SAndroid Build Coastguard Worker 
1001*48a54d36SAndroid Build Coastguard Worker 	// Set it to be non-blocking
1002*48a54d36SAndroid Build Coastguard Worker 
1003*48a54d36SAndroid Build Coastguard Worker 	err = ioctlsocket( sock->fd, FIONBIO, &on );
1004*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
1005*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1006*48a54d36SAndroid Build Coastguard Worker 
1007*48a54d36SAndroid Build Coastguard Worker 	// Get port number
1008*48a54d36SAndroid Build Coastguard Worker 
1009*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero( &saddr, sizeof( saddr ) );
1010*48a54d36SAndroid Build Coastguard Worker 	len = sizeof( saddr );
1011*48a54d36SAndroid Build Coastguard Worker 
1012*48a54d36SAndroid Build Coastguard Worker 	err = getsockname( sock->fd, ( struct sockaddr* ) &saddr, &len );
1013*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
1014*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1015*48a54d36SAndroid Build Coastguard Worker 
1016*48a54d36SAndroid Build Coastguard Worker 	port->NotAnInteger = saddr.sin_port;
1017*48a54d36SAndroid Build Coastguard Worker 
1018*48a54d36SAndroid Build Coastguard Worker exit:
1019*48a54d36SAndroid Build Coastguard Worker 
1020*48a54d36SAndroid Build Coastguard Worker 	if ( err && sock )
1021*48a54d36SAndroid Build Coastguard Worker 	{
1022*48a54d36SAndroid Build Coastguard Worker 		TCPFreeSocket( sock );
1023*48a54d36SAndroid Build Coastguard Worker 		sock = mDNSNULL;
1024*48a54d36SAndroid Build Coastguard Worker 	}
1025*48a54d36SAndroid Build Coastguard Worker 
1026*48a54d36SAndroid Build Coastguard Worker 	return sock;
1027*48a54d36SAndroid Build Coastguard Worker }
1028*48a54d36SAndroid Build Coastguard Worker 
1029*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1030*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTCPConnect
1031*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1032*48a54d36SAndroid Build Coastguard Worker 
1033*48a54d36SAndroid Build Coastguard Worker mStatus
mDNSPlatformTCPConnect(TCPSocket * sock,const mDNSAddr * inDstIP,mDNSOpaque16 inDstPort,domainname * hostname,mDNSInterfaceID inInterfaceID,TCPConnectionCallback inCallback,void * inContext)1034*48a54d36SAndroid Build Coastguard Worker mDNSPlatformTCPConnect
1035*48a54d36SAndroid Build Coastguard Worker 	(
1036*48a54d36SAndroid Build Coastguard Worker 	TCPSocket			*	sock,
1037*48a54d36SAndroid Build Coastguard Worker 	const mDNSAddr		*	inDstIP,
1038*48a54d36SAndroid Build Coastguard Worker 	mDNSOpaque16 			inDstPort,
1039*48a54d36SAndroid Build Coastguard Worker 	domainname          *   hostname,
1040*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceID			inInterfaceID,
1041*48a54d36SAndroid Build Coastguard Worker 	TCPConnectionCallback	inCallback,
1042*48a54d36SAndroid Build Coastguard Worker 	void *					inContext
1043*48a54d36SAndroid Build Coastguard Worker 	)
1044*48a54d36SAndroid Build Coastguard Worker {
1045*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in	saddr;
1046*48a54d36SAndroid Build Coastguard Worker 	mStatus				err		= mStatus_NoError;
1047*48a54d36SAndroid Build Coastguard Worker 
1048*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inInterfaceID );
1049*48a54d36SAndroid Build Coastguard Worker 	( void ) hostname;
1050*48a54d36SAndroid Build Coastguard Worker 
1051*48a54d36SAndroid Build Coastguard Worker 	if ( inDstIP->type != mDNSAddrType_IPv4 )
1052*48a54d36SAndroid Build Coastguard Worker 	{
1053*48a54d36SAndroid Build Coastguard Worker 		LogMsg("ERROR: mDNSPlatformTCPConnect - attempt to connect to an IPv6 address: operation not supported");
1054*48a54d36SAndroid Build Coastguard Worker 		return mStatus_UnknownErr;
1055*48a54d36SAndroid Build Coastguard Worker 	}
1056*48a54d36SAndroid Build Coastguard Worker 
1057*48a54d36SAndroid Build Coastguard Worker 	// Setup connection data object
1058*48a54d36SAndroid Build Coastguard Worker 
1059*48a54d36SAndroid Build Coastguard Worker 	sock->readEventHandler	= TCPCanRead;
1060*48a54d36SAndroid Build Coastguard Worker 	sock->userCallback		= inCallback;
1061*48a54d36SAndroid Build Coastguard Worker 	sock->userContext		= inContext;
1062*48a54d36SAndroid Build Coastguard Worker 
1063*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero(&saddr, sizeof(saddr));
1064*48a54d36SAndroid Build Coastguard Worker 	saddr.sin_family	= AF_INET;
1065*48a54d36SAndroid Build Coastguard Worker 	saddr.sin_port		= inDstPort.NotAnInteger;
1066*48a54d36SAndroid Build Coastguard Worker 	memcpy(&saddr.sin_addr, &inDstIP->ip.v4.NotAnInteger, sizeof(saddr.sin_addr));
1067*48a54d36SAndroid Build Coastguard Worker 
1068*48a54d36SAndroid Build Coastguard Worker 	// Try and do connect
1069*48a54d36SAndroid Build Coastguard Worker 
1070*48a54d36SAndroid Build Coastguard Worker 	err = connect( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr ) );
1071*48a54d36SAndroid Build Coastguard Worker 	require_action( !err || ( WSAGetLastError() == WSAEWOULDBLOCK ), exit, err = mStatus_ConnFailed );
1072*48a54d36SAndroid Build Coastguard Worker 	sock->connected	= !err ? TRUE : FALSE;
1073*48a54d36SAndroid Build Coastguard Worker 
1074*48a54d36SAndroid Build Coastguard Worker 	if ( sock->connected )
1075*48a54d36SAndroid Build Coastguard Worker 	{
1076*48a54d36SAndroid Build Coastguard Worker 		err = TCPAddSocket( sock->m, sock );
1077*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1078*48a54d36SAndroid Build Coastguard Worker 	}
1079*48a54d36SAndroid Build Coastguard Worker 	else
1080*48a54d36SAndroid Build Coastguard Worker 	{
1081*48a54d36SAndroid Build Coastguard Worker 		require_action( sock->m->p->registerWaitableEventFunc != NULL, exit, err = mStatus_ConnFailed );
1082*48a54d36SAndroid Build Coastguard Worker 
1083*48a54d36SAndroid Build Coastguard Worker 		sock->connectEvent	= CreateEvent( NULL, FALSE, FALSE, NULL );
1084*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( sock->connectEvent, GetLastError(), mStatus_UnknownErr );
1085*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1086*48a54d36SAndroid Build Coastguard Worker 
1087*48a54d36SAndroid Build Coastguard Worker 		err = WSAEventSelect( sock->fd, sock->connectEvent, FD_CONNECT );
1088*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1089*48a54d36SAndroid Build Coastguard Worker 
1090*48a54d36SAndroid Build Coastguard Worker 		err = sock->m->p->registerWaitableEventFunc( sock->m, sock->connectEvent, sock, TCPDidConnect );
1091*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1092*48a54d36SAndroid Build Coastguard Worker 	}
1093*48a54d36SAndroid Build Coastguard Worker 
1094*48a54d36SAndroid Build Coastguard Worker exit:
1095*48a54d36SAndroid Build Coastguard Worker 
1096*48a54d36SAndroid Build Coastguard Worker 	if ( !err )
1097*48a54d36SAndroid Build Coastguard Worker 	{
1098*48a54d36SAndroid Build Coastguard Worker 		err = sock->connected ? mStatus_ConnEstablished : mStatus_ConnPending;
1099*48a54d36SAndroid Build Coastguard Worker 	}
1100*48a54d36SAndroid Build Coastguard Worker 
1101*48a54d36SAndroid Build Coastguard Worker 	return err;
1102*48a54d36SAndroid Build Coastguard Worker }
1103*48a54d36SAndroid Build Coastguard Worker 
1104*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1105*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTCPAccept
1106*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1107*48a54d36SAndroid Build Coastguard Worker 
1108*48a54d36SAndroid Build Coastguard Worker mDNSexport
mDNSPlatformTCPAccept(TCPSocketFlags flags,int fd)1109*48a54d36SAndroid Build Coastguard Worker mDNSexport TCPSocket *mDNSPlatformTCPAccept( TCPSocketFlags flags, int fd )
1110*48a54d36SAndroid Build Coastguard Worker 	{
1111*48a54d36SAndroid Build Coastguard Worker 	TCPSocket	*	sock = NULL;
1112*48a54d36SAndroid Build Coastguard Worker 	mStatus							err = mStatus_NoError;
1113*48a54d36SAndroid Build Coastguard Worker 
1114*48a54d36SAndroid Build Coastguard Worker 	require_action( !flags, exit, err = mStatus_UnsupportedErr );
1115*48a54d36SAndroid Build Coastguard Worker 
1116*48a54d36SAndroid Build Coastguard Worker 	sock = malloc( sizeof( TCPSocket ) );
1117*48a54d36SAndroid Build Coastguard Worker 	require_action( sock, exit, err = mStatus_NoMemoryErr );
1118*48a54d36SAndroid Build Coastguard Worker 
1119*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformMemZero( sock, sizeof( *sock ) );
1120*48a54d36SAndroid Build Coastguard Worker 
1121*48a54d36SAndroid Build Coastguard Worker 	sock->fd	= fd;
1122*48a54d36SAndroid Build Coastguard Worker 	sock->flags = flags;
1123*48a54d36SAndroid Build Coastguard Worker 
1124*48a54d36SAndroid Build Coastguard Worker exit:
1125*48a54d36SAndroid Build Coastguard Worker 
1126*48a54d36SAndroid Build Coastguard Worker 	if ( err && sock )
1127*48a54d36SAndroid Build Coastguard Worker 	{
1128*48a54d36SAndroid Build Coastguard Worker 		free( sock );
1129*48a54d36SAndroid Build Coastguard Worker 		sock = NULL;
1130*48a54d36SAndroid Build Coastguard Worker 	}
1131*48a54d36SAndroid Build Coastguard Worker 
1132*48a54d36SAndroid Build Coastguard Worker 	return sock;
1133*48a54d36SAndroid Build Coastguard Worker 	}
1134*48a54d36SAndroid Build Coastguard Worker 
1135*48a54d36SAndroid Build Coastguard Worker 
1136*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1137*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTCPCloseConnection
1138*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1139*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformTCPCloseConnection(TCPSocket * sock)1140*48a54d36SAndroid Build Coastguard Worker mDNSexport void	mDNSPlatformTCPCloseConnection( TCPSocket *sock )
1141*48a54d36SAndroid Build Coastguard Worker {
1142*48a54d36SAndroid Build Coastguard Worker 	check( sock );
1143*48a54d36SAndroid Build Coastguard Worker 
1144*48a54d36SAndroid Build Coastguard Worker 	if ( sock->connectEvent && sock->m->p->unregisterWaitableEventFunc )
1145*48a54d36SAndroid Build Coastguard Worker 	{
1146*48a54d36SAndroid Build Coastguard Worker 		sock->m->p->unregisterWaitableEventFunc( sock->m, sock->connectEvent );
1147*48a54d36SAndroid Build Coastguard Worker 	}
1148*48a54d36SAndroid Build Coastguard Worker 
1149*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
1150*48a54d36SAndroid Build Coastguard Worker 	{
1151*48a54d36SAndroid Build Coastguard Worker 		TCPCloseSocket( sock );
1152*48a54d36SAndroid Build Coastguard Worker 
1153*48a54d36SAndroid Build Coastguard Worker 		QueueUserAPC( ( PAPCFUNC ) TCPFreeSocket, sock->m->p->mainThread, ( ULONG_PTR ) sock );
1154*48a54d36SAndroid Build Coastguard Worker 	}
1155*48a54d36SAndroid Build Coastguard Worker }
1156*48a54d36SAndroid Build Coastguard Worker 
1157*48a54d36SAndroid Build Coastguard Worker 
1158*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1159*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformReadTCP
1160*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1161*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformReadTCP(TCPSocket * sock,void * inBuffer,unsigned long inBufferSize,mDNSBool * closed)1162*48a54d36SAndroid Build Coastguard Worker mDNSexport long	mDNSPlatformReadTCP( TCPSocket *sock, void *inBuffer, unsigned long inBufferSize, mDNSBool * closed )
1163*48a54d36SAndroid Build Coastguard Worker {
1164*48a54d36SAndroid Build Coastguard Worker 	unsigned long	bytesLeft;
1165*48a54d36SAndroid Build Coastguard Worker 	int				wsaError;
1166*48a54d36SAndroid Build Coastguard Worker 	long			ret;
1167*48a54d36SAndroid Build Coastguard Worker 
1168*48a54d36SAndroid Build Coastguard Worker 	*closed = sock->closed;
1169*48a54d36SAndroid Build Coastguard Worker 	wsaError = sock->lastError;
1170*48a54d36SAndroid Build Coastguard Worker 	ret = -1;
1171*48a54d36SAndroid Build Coastguard Worker 
1172*48a54d36SAndroid Build Coastguard Worker 	if ( *closed )
1173*48a54d36SAndroid Build Coastguard Worker 	{
1174*48a54d36SAndroid Build Coastguard Worker 		ret = 0;
1175*48a54d36SAndroid Build Coastguard Worker 	}
1176*48a54d36SAndroid Build Coastguard Worker 	else if ( sock->lastError == 0 )
1177*48a54d36SAndroid Build Coastguard Worker 	{
1178*48a54d36SAndroid Build Coastguard Worker 		// First check to see if we have any data left in our buffer
1179*48a54d36SAndroid Build Coastguard Worker 
1180*48a54d36SAndroid Build Coastguard Worker 		bytesLeft = ( DWORD ) ( sock->eptr - sock->bptr );
1181*48a54d36SAndroid Build Coastguard Worker 
1182*48a54d36SAndroid Build Coastguard Worker 		if ( bytesLeft )
1183*48a54d36SAndroid Build Coastguard Worker 		{
1184*48a54d36SAndroid Build Coastguard Worker 			unsigned long bytesToCopy = ( bytesLeft < inBufferSize ) ? bytesLeft : inBufferSize;
1185*48a54d36SAndroid Build Coastguard Worker 
1186*48a54d36SAndroid Build Coastguard Worker 			memcpy( inBuffer, sock->bptr, bytesToCopy );
1187*48a54d36SAndroid Build Coastguard Worker 			sock->bptr += bytesToCopy;
1188*48a54d36SAndroid Build Coastguard Worker 
1189*48a54d36SAndroid Build Coastguard Worker 			if ( !sock->overlapped.pending && ( sock->bptr == sock->eptr ) )
1190*48a54d36SAndroid Build Coastguard Worker 			{
1191*48a54d36SAndroid Build Coastguard Worker 				sock->bptr = sock->bbuf;
1192*48a54d36SAndroid Build Coastguard Worker 				sock->eptr = sock->bbuf;
1193*48a54d36SAndroid Build Coastguard Worker 			}
1194*48a54d36SAndroid Build Coastguard Worker 
1195*48a54d36SAndroid Build Coastguard Worker 			ret = bytesToCopy;
1196*48a54d36SAndroid Build Coastguard Worker 		}
1197*48a54d36SAndroid Build Coastguard Worker 		else
1198*48a54d36SAndroid Build Coastguard Worker 		{
1199*48a54d36SAndroid Build Coastguard Worker 			wsaError = WSAEWOULDBLOCK;
1200*48a54d36SAndroid Build Coastguard Worker 		}
1201*48a54d36SAndroid Build Coastguard Worker 	}
1202*48a54d36SAndroid Build Coastguard Worker 
1203*48a54d36SAndroid Build Coastguard Worker 	// Always set the last winsock error, so that we don't inadvertently use a previous one
1204*48a54d36SAndroid Build Coastguard Worker 
1205*48a54d36SAndroid Build Coastguard Worker 	WSASetLastError( wsaError );
1206*48a54d36SAndroid Build Coastguard Worker 
1207*48a54d36SAndroid Build Coastguard Worker 	return ret;
1208*48a54d36SAndroid Build Coastguard Worker }
1209*48a54d36SAndroid Build Coastguard Worker 
1210*48a54d36SAndroid Build Coastguard Worker 
1211*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1212*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformWriteTCP
1213*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1214*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformWriteTCP(TCPSocket * sock,const char * inMsg,unsigned long inMsgSize)1215*48a54d36SAndroid Build Coastguard Worker mDNSexport long	mDNSPlatformWriteTCP( TCPSocket *sock, const char *inMsg, unsigned long inMsgSize )
1216*48a54d36SAndroid Build Coastguard Worker {
1217*48a54d36SAndroid Build Coastguard Worker 	int			nsent;
1218*48a54d36SAndroid Build Coastguard Worker 	OSStatus	err;
1219*48a54d36SAndroid Build Coastguard Worker 
1220*48a54d36SAndroid Build Coastguard Worker 	nsent = send( sock->fd, inMsg, inMsgSize, 0 );
1221*48a54d36SAndroid Build Coastguard Worker 
1222*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( ( nsent >= 0 ) || ( WSAGetLastError() == WSAEWOULDBLOCK ), WSAGetLastError(), mStatus_UnknownErr );
1223*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1224*48a54d36SAndroid Build Coastguard Worker 
1225*48a54d36SAndroid Build Coastguard Worker 	if ( nsent < 0)
1226*48a54d36SAndroid Build Coastguard Worker 	{
1227*48a54d36SAndroid Build Coastguard Worker 		nsent = 0;
1228*48a54d36SAndroid Build Coastguard Worker 	}
1229*48a54d36SAndroid Build Coastguard Worker 
1230*48a54d36SAndroid Build Coastguard Worker exit:
1231*48a54d36SAndroid Build Coastguard Worker 
1232*48a54d36SAndroid Build Coastguard Worker 	return nsent;
1233*48a54d36SAndroid Build Coastguard Worker }
1234*48a54d36SAndroid Build Coastguard Worker 
1235*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1236*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTCPGetFD
1237*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1238*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformTCPGetFD(TCPSocket * sock)1239*48a54d36SAndroid Build Coastguard Worker mDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock )
1240*48a54d36SAndroid Build Coastguard Worker {
1241*48a54d36SAndroid Build Coastguard Worker 	return ( int ) sock->fd;
1242*48a54d36SAndroid Build Coastguard Worker }
1243*48a54d36SAndroid Build Coastguard Worker 
1244*48a54d36SAndroid Build Coastguard Worker 
1245*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1246*48a54d36SAndroid Build Coastguard Worker //	TCPAddConnection
1247*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1248*48a54d36SAndroid Build Coastguard Worker 
TCPAddSocket(mDNS * const inMDNS,TCPSocket * sock)1249*48a54d36SAndroid Build Coastguard Worker mStatus TCPAddSocket( mDNS * const inMDNS, TCPSocket *sock )
1250*48a54d36SAndroid Build Coastguard Worker {
1251*48a54d36SAndroid Build Coastguard Worker 	mStatus err;
1252*48a54d36SAndroid Build Coastguard Worker 
1253*48a54d36SAndroid Build Coastguard Worker 	( void ) inMDNS;
1254*48a54d36SAndroid Build Coastguard Worker 
1255*48a54d36SAndroid Build Coastguard Worker 	sock->bptr	= sock->bbuf;
1256*48a54d36SAndroid Build Coastguard Worker 	sock->eptr	= sock->bbuf;
1257*48a54d36SAndroid Build Coastguard Worker 	sock->ebuf	= sock->bbuf + sizeof( sock->bbuf );
1258*48a54d36SAndroid Build Coastguard Worker 
1259*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "adding TCPSocket 0x%x:%d\n", sock, sock->fd );
1260*48a54d36SAndroid Build Coastguard Worker 	err = TCPBeginRecv( sock );
1261*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1262*48a54d36SAndroid Build Coastguard Worker 
1263*48a54d36SAndroid Build Coastguard Worker exit:
1264*48a54d36SAndroid Build Coastguard Worker 
1265*48a54d36SAndroid Build Coastguard Worker 	return err;
1266*48a54d36SAndroid Build Coastguard Worker }
1267*48a54d36SAndroid Build Coastguard Worker 
1268*48a54d36SAndroid Build Coastguard Worker 
1269*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1270*48a54d36SAndroid Build Coastguard Worker //	TCPDidConnect
1271*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1272*48a54d36SAndroid Build Coastguard Worker 
TCPDidConnect(mDNS * const inMDNS,HANDLE event,void * context)1273*48a54d36SAndroid Build Coastguard Worker mDNSlocal void TCPDidConnect( mDNS * const inMDNS, HANDLE event, void * context )
1274*48a54d36SAndroid Build Coastguard Worker {
1275*48a54d36SAndroid Build Coastguard Worker 	TCPSocket * sock = ( TCPSocket* ) context;
1276*48a54d36SAndroid Build Coastguard Worker 	TCPConnectionCallback callback = NULL;
1277*48a54d36SAndroid Build Coastguard Worker 	WSANETWORKEVENTS sockEvent;
1278*48a54d36SAndroid Build Coastguard Worker 	int err = kNoErr;
1279*48a54d36SAndroid Build Coastguard Worker 
1280*48a54d36SAndroid Build Coastguard Worker 	if ( inMDNS->p->unregisterWaitableEventFunc )
1281*48a54d36SAndroid Build Coastguard Worker 	{
1282*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->unregisterWaitableEventFunc( inMDNS, event );
1283*48a54d36SAndroid Build Coastguard Worker 	}
1284*48a54d36SAndroid Build Coastguard Worker 
1285*48a54d36SAndroid Build Coastguard Worker 	if ( sock )
1286*48a54d36SAndroid Build Coastguard Worker 	{
1287*48a54d36SAndroid Build Coastguard Worker 		callback = ( TCPConnectionCallback ) sock->userCallback;
1288*48a54d36SAndroid Build Coastguard Worker 		err = WSAEnumNetworkEvents( sock->fd, sock->connectEvent, &sockEvent );
1289*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1290*48a54d36SAndroid Build Coastguard Worker 		require_action( sockEvent.lNetworkEvents & FD_CONNECT, exit, err = mStatus_UnknownErr );
1291*48a54d36SAndroid Build Coastguard Worker 		require_action( sockEvent.iErrorCode[ FD_CONNECT_BIT ] == 0, exit, err = sockEvent.iErrorCode[ FD_CONNECT_BIT ] );
1292*48a54d36SAndroid Build Coastguard Worker 
1293*48a54d36SAndroid Build Coastguard Worker 		sock->connected	= mDNStrue;
1294*48a54d36SAndroid Build Coastguard Worker 
1295*48a54d36SAndroid Build Coastguard Worker 		if ( sock->fd != INVALID_SOCKET )
1296*48a54d36SAndroid Build Coastguard Worker 		{
1297*48a54d36SAndroid Build Coastguard Worker 			err = TCPAddSocket( sock->m, sock );
1298*48a54d36SAndroid Build Coastguard Worker 			require_noerr( err, exit );
1299*48a54d36SAndroid Build Coastguard Worker 		}
1300*48a54d36SAndroid Build Coastguard Worker 
1301*48a54d36SAndroid Build Coastguard Worker 		if ( callback )
1302*48a54d36SAndroid Build Coastguard Worker 		{
1303*48a54d36SAndroid Build Coastguard Worker 			callback( sock, sock->userContext, TRUE, 0 );
1304*48a54d36SAndroid Build Coastguard Worker 		}
1305*48a54d36SAndroid Build Coastguard Worker 	}
1306*48a54d36SAndroid Build Coastguard Worker 
1307*48a54d36SAndroid Build Coastguard Worker exit:
1308*48a54d36SAndroid Build Coastguard Worker 
1309*48a54d36SAndroid Build Coastguard Worker 	if ( err && callback )
1310*48a54d36SAndroid Build Coastguard Worker 	{
1311*48a54d36SAndroid Build Coastguard Worker 		callback( sock, sock->userContext, TRUE, err );
1312*48a54d36SAndroid Build Coastguard Worker 	}
1313*48a54d36SAndroid Build Coastguard Worker }
1314*48a54d36SAndroid Build Coastguard Worker 
1315*48a54d36SAndroid Build Coastguard Worker 
1316*48a54d36SAndroid Build Coastguard Worker 
1317*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1318*48a54d36SAndroid Build Coastguard Worker //	TCPCanRead
1319*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1320*48a54d36SAndroid Build Coastguard Worker 
TCPCanRead(TCPSocket * sock)1321*48a54d36SAndroid Build Coastguard Worker mDNSlocal void TCPCanRead( TCPSocket * sock )
1322*48a54d36SAndroid Build Coastguard Worker {
1323*48a54d36SAndroid Build Coastguard Worker 	TCPConnectionCallback callback = ( TCPConnectionCallback ) sock->userCallback;
1324*48a54d36SAndroid Build Coastguard Worker 
1325*48a54d36SAndroid Build Coastguard Worker 	if ( callback )
1326*48a54d36SAndroid Build Coastguard Worker 	{
1327*48a54d36SAndroid Build Coastguard Worker 		callback( sock, sock->userContext, mDNSfalse, sock->lastError );
1328*48a54d36SAndroid Build Coastguard Worker 	}
1329*48a54d36SAndroid Build Coastguard Worker }
1330*48a54d36SAndroid Build Coastguard Worker 
1331*48a54d36SAndroid Build Coastguard Worker 
1332*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1333*48a54d36SAndroid Build Coastguard Worker //	TCPBeginRecv
1334*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1335*48a54d36SAndroid Build Coastguard Worker 
TCPBeginRecv(TCPSocket * sock)1336*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus TCPBeginRecv( TCPSocket * sock )
1337*48a54d36SAndroid Build Coastguard Worker {
1338*48a54d36SAndroid Build Coastguard Worker 	DWORD	bytesReceived	= 0;
1339*48a54d36SAndroid Build Coastguard Worker 	DWORD	flags			= 0;
1340*48a54d36SAndroid Build Coastguard Worker 	mStatus err;
1341*48a54d36SAndroid Build Coastguard Worker 
1342*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
1343*48a54d36SAndroid Build Coastguard Worker 
1344*48a54d36SAndroid Build Coastguard Worker 	check( !sock->overlapped.pending );
1345*48a54d36SAndroid Build Coastguard Worker 
1346*48a54d36SAndroid Build Coastguard Worker 	ZeroMemory( &sock->overlapped.data, sizeof( sock->overlapped.data ) );
1347*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.data.hEvent = sock;
1348*48a54d36SAndroid Build Coastguard Worker 
1349*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.wbuf.buf = ( char* ) sock->eptr;
1350*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.wbuf.len = ( ULONG) ( sock->ebuf - sock->eptr );
1351*48a54d36SAndroid Build Coastguard Worker 
1352*48a54d36SAndroid Build Coastguard Worker 	err = WSARecv( sock->fd, &sock->overlapped.wbuf, 1, &bytesReceived, &flags, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) TCPEndRecv );
1353*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), WSAGetLastError(), kUnknownErr );
1354*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1355*48a54d36SAndroid Build Coastguard Worker 
1356*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.pending = TRUE;
1357*48a54d36SAndroid Build Coastguard Worker 
1358*48a54d36SAndroid Build Coastguard Worker exit:
1359*48a54d36SAndroid Build Coastguard Worker 
1360*48a54d36SAndroid Build Coastguard Worker 	return err;
1361*48a54d36SAndroid Build Coastguard Worker }
1362*48a54d36SAndroid Build Coastguard Worker 
1363*48a54d36SAndroid Build Coastguard Worker 
1364*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1365*48a54d36SAndroid Build Coastguard Worker //	TCPEndRecv
1366*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1367*48a54d36SAndroid Build Coastguard Worker 
TCPEndRecv(DWORD error,DWORD bytesTransferred,LPWSAOVERLAPPED overlapped,DWORD flags)1368*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK TCPEndRecv( DWORD error, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags )
1369*48a54d36SAndroid Build Coastguard Worker {
1370*48a54d36SAndroid Build Coastguard Worker 	TCPSocket * sock;
1371*48a54d36SAndroid Build Coastguard Worker 
1372*48a54d36SAndroid Build Coastguard Worker 	( void ) flags;
1373*48a54d36SAndroid Build Coastguard Worker 
1374*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "%s: error = %d, bytesTransferred = %d\n", __ROUTINE__, error, bytesTransferred );
1375*48a54d36SAndroid Build Coastguard Worker 	sock = ( overlapped != NULL ) ? overlapped->hEvent : NULL;
1376*48a54d36SAndroid Build Coastguard Worker 	require_action( sock, exit, error = ( DWORD ) mStatus_BadStateErr );
1377*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
1378*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.error				= error;
1379*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.bytesTransferred	= bytesTransferred;
1380*48a54d36SAndroid Build Coastguard Worker 	check( sock->overlapped.pending );
1381*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.pending			= FALSE;
1382*48a54d36SAndroid Build Coastguard Worker 
1383*48a54d36SAndroid Build Coastguard Worker 	// Queue this socket
1384*48a54d36SAndroid Build Coastguard Worker 
1385*48a54d36SAndroid Build Coastguard Worker 	AddToTail( &gTCPDispatchableSockets, sock );
1386*48a54d36SAndroid Build Coastguard Worker 
1387*48a54d36SAndroid Build Coastguard Worker exit:
1388*48a54d36SAndroid Build Coastguard Worker 
1389*48a54d36SAndroid Build Coastguard Worker 	return;
1390*48a54d36SAndroid Build Coastguard Worker }
1391*48a54d36SAndroid Build Coastguard Worker 
1392*48a54d36SAndroid Build Coastguard Worker 
1393*48a54d36SAndroid Build Coastguard Worker 
1394*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1395*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformUDPSocket
1396*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1397*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformUDPSocket(mDNS * const m,const mDNSIPPort requestedport)1398*48a54d36SAndroid Build Coastguard Worker mDNSexport UDPSocket* mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport)
1399*48a54d36SAndroid Build Coastguard Worker {
1400*48a54d36SAndroid Build Coastguard Worker 	UDPSocket*	sock	= NULL;
1401*48a54d36SAndroid Build Coastguard Worker 	mDNSIPPort	port	= requestedport;
1402*48a54d36SAndroid Build Coastguard Worker 	mStatus		err		= mStatus_NoError;
1403*48a54d36SAndroid Build Coastguard Worker 	unsigned	i;
1404*48a54d36SAndroid Build Coastguard Worker 
1405*48a54d36SAndroid Build Coastguard Worker 	// Setup connection data object
1406*48a54d36SAndroid Build Coastguard Worker 
1407*48a54d36SAndroid Build Coastguard Worker 	sock = ( UDPSocket* ) malloc(sizeof( UDPSocket ) );
1408*48a54d36SAndroid Build Coastguard Worker 	require_action( sock, exit, err = mStatus_NoMemoryErr );
1409*48a54d36SAndroid Build Coastguard Worker 	memset( sock, 0, sizeof( UDPSocket ) );
1410*48a54d36SAndroid Build Coastguard Worker 
1411*48a54d36SAndroid Build Coastguard Worker 	// Create the socket
1412*48a54d36SAndroid Build Coastguard Worker 
1413*48a54d36SAndroid Build Coastguard Worker 	sock->fd					= INVALID_SOCKET;
1414*48a54d36SAndroid Build Coastguard Worker 	sock->recvMsgPtr			= m->p->unicastSock4.recvMsgPtr;
1415*48a54d36SAndroid Build Coastguard Worker 	sock->addr					= m->p->unicastSock4.addr;
1416*48a54d36SAndroid Build Coastguard Worker 	sock->ifd					= NULL;
1417*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.pending	= FALSE;
1418*48a54d36SAndroid Build Coastguard Worker 	sock->m						= m;
1419*48a54d36SAndroid Build Coastguard Worker 
1420*48a54d36SAndroid Build Coastguard Worker 	// Try at most 10000 times to get a unique random port
1421*48a54d36SAndroid Build Coastguard Worker 
1422*48a54d36SAndroid Build Coastguard Worker 	for (i=0; i<10000; i++)
1423*48a54d36SAndroid Build Coastguard Worker 	{
1424*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in saddr;
1425*48a54d36SAndroid Build Coastguard Worker 
1426*48a54d36SAndroid Build Coastguard Worker 		saddr.sin_family		= AF_INET;
1427*48a54d36SAndroid Build Coastguard Worker 		saddr.sin_addr.s_addr	= 0;
1428*48a54d36SAndroid Build Coastguard Worker 
1429*48a54d36SAndroid Build Coastguard Worker 		// The kernel doesn't do cryptographically strong random port
1430*48a54d36SAndroid Build Coastguard Worker 		// allocation, so we do it ourselves here
1431*48a54d36SAndroid Build Coastguard Worker 
1432*48a54d36SAndroid Build Coastguard Worker         if (mDNSIPPortIsZero(requestedport))
1433*48a54d36SAndroid Build Coastguard Worker 		{
1434*48a54d36SAndroid Build Coastguard Worker 			port = mDNSOpaque16fromIntVal( ( mDNSu16 ) ( 0xC000 + mDNSRandom(0x3FFF) ) );
1435*48a54d36SAndroid Build Coastguard Worker 		}
1436*48a54d36SAndroid Build Coastguard Worker 
1437*48a54d36SAndroid Build Coastguard Worker 		saddr.sin_port = port.NotAnInteger;
1438*48a54d36SAndroid Build Coastguard Worker 
1439*48a54d36SAndroid Build Coastguard Worker         err = SetupSocket(m, ( struct sockaddr* ) &saddr, port, &sock->fd );
1440*48a54d36SAndroid Build Coastguard Worker         if (!err) break;
1441*48a54d36SAndroid Build Coastguard Worker 	}
1442*48a54d36SAndroid Build Coastguard Worker 
1443*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1444*48a54d36SAndroid Build Coastguard Worker 
1445*48a54d36SAndroid Build Coastguard Worker 	// Set the port
1446*48a54d36SAndroid Build Coastguard Worker 
1447*48a54d36SAndroid Build Coastguard Worker 	sock->port = port;
1448*48a54d36SAndroid Build Coastguard Worker 
1449*48a54d36SAndroid Build Coastguard Worker 	// Arm the completion routine
1450*48a54d36SAndroid Build Coastguard Worker 
1451*48a54d36SAndroid Build Coastguard Worker 	err = UDPBeginRecv( sock );
1452*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1453*48a54d36SAndroid Build Coastguard Worker 
1454*48a54d36SAndroid Build Coastguard Worker 	// Bookkeeping
1455*48a54d36SAndroid Build Coastguard Worker 
1456*48a54d36SAndroid Build Coastguard Worker 	sock->next		= gUDPSockets;
1457*48a54d36SAndroid Build Coastguard Worker 	gUDPSockets		= sock;
1458*48a54d36SAndroid Build Coastguard Worker 	gUDPNumSockets++;
1459*48a54d36SAndroid Build Coastguard Worker 
1460*48a54d36SAndroid Build Coastguard Worker exit:
1461*48a54d36SAndroid Build Coastguard Worker 
1462*48a54d36SAndroid Build Coastguard Worker 	if ( err && sock )
1463*48a54d36SAndroid Build Coastguard Worker 	{
1464*48a54d36SAndroid Build Coastguard Worker 		UDPFreeSocket( sock );
1465*48a54d36SAndroid Build Coastguard Worker 		sock = NULL;
1466*48a54d36SAndroid Build Coastguard Worker 	}
1467*48a54d36SAndroid Build Coastguard Worker 
1468*48a54d36SAndroid Build Coastguard Worker 	return sock;
1469*48a54d36SAndroid Build Coastguard Worker }
1470*48a54d36SAndroid Build Coastguard Worker 
1471*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1472*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformUDPClose
1473*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1474*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformUDPClose(UDPSocket * sock)1475*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformUDPClose( UDPSocket *sock )
1476*48a54d36SAndroid Build Coastguard Worker {
1477*48a54d36SAndroid Build Coastguard Worker 	UDPSocket	*	current  = gUDPSockets;
1478*48a54d36SAndroid Build Coastguard Worker 	UDPSocket	*	last = NULL;
1479*48a54d36SAndroid Build Coastguard Worker 
1480*48a54d36SAndroid Build Coastguard Worker 	while ( current )
1481*48a54d36SAndroid Build Coastguard Worker 	{
1482*48a54d36SAndroid Build Coastguard Worker 		if ( current == sock )
1483*48a54d36SAndroid Build Coastguard Worker 		{
1484*48a54d36SAndroid Build Coastguard Worker 			if ( last == NULL )
1485*48a54d36SAndroid Build Coastguard Worker 			{
1486*48a54d36SAndroid Build Coastguard Worker 				gUDPSockets = sock->next;
1487*48a54d36SAndroid Build Coastguard Worker 			}
1488*48a54d36SAndroid Build Coastguard Worker 			else
1489*48a54d36SAndroid Build Coastguard Worker 			{
1490*48a54d36SAndroid Build Coastguard Worker 				last->next = sock->next;
1491*48a54d36SAndroid Build Coastguard Worker 			}
1492*48a54d36SAndroid Build Coastguard Worker 
1493*48a54d36SAndroid Build Coastguard Worker 			// Alertable I/O is great, except not so much when it comes to closing
1494*48a54d36SAndroid Build Coastguard Worker 			// the socket.  Anything that has been previously queued for this socket
1495*48a54d36SAndroid Build Coastguard Worker 			// will stay in the queue after you close the socket.  This is problematic
1496*48a54d36SAndroid Build Coastguard Worker 			// for obvious reasons. So we'll attempt to workaround this by closing
1497*48a54d36SAndroid Build Coastguard Worker 			// the socket which will prevent any further queued packets and then not calling
1498*48a54d36SAndroid Build Coastguard Worker 			// UDPFreeSocket directly, but by queueing it using QueueUserAPC.  The queues
1499*48a54d36SAndroid Build Coastguard Worker 			// are FIFO, so that will execute *after* any other previous items in the queue
1500*48a54d36SAndroid Build Coastguard Worker 			//
1501*48a54d36SAndroid Build Coastguard Worker 			// UDPEndRecv will check if the socket is valid, and if not, it will ignore
1502*48a54d36SAndroid Build Coastguard Worker 			// the packet
1503*48a54d36SAndroid Build Coastguard Worker 
1504*48a54d36SAndroid Build Coastguard Worker 			UDPCloseSocket( sock );
1505*48a54d36SAndroid Build Coastguard Worker 
1506*48a54d36SAndroid Build Coastguard Worker 			QueueUserAPC( ( PAPCFUNC ) UDPFreeSocket, sock->m->p->mainThread, ( ULONG_PTR ) sock );
1507*48a54d36SAndroid Build Coastguard Worker 
1508*48a54d36SAndroid Build Coastguard Worker 			gUDPNumSockets--;
1509*48a54d36SAndroid Build Coastguard Worker 
1510*48a54d36SAndroid Build Coastguard Worker 			break;
1511*48a54d36SAndroid Build Coastguard Worker 		}
1512*48a54d36SAndroid Build Coastguard Worker 
1513*48a54d36SAndroid Build Coastguard Worker 		last	= current;
1514*48a54d36SAndroid Build Coastguard Worker 		current	= current->next;
1515*48a54d36SAndroid Build Coastguard Worker 	}
1516*48a54d36SAndroid Build Coastguard Worker }
1517*48a54d36SAndroid Build Coastguard Worker 
1518*48a54d36SAndroid Build Coastguard Worker 
1519*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1520*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformSendUDP
1521*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1522*48a54d36SAndroid Build Coastguard Worker 
1523*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus
mDNSPlatformSendUDP(const mDNS * const inMDNS,const void * const inMsg,const mDNSu8 * const inMsgEnd,mDNSInterfaceID inInterfaceID,UDPSocket * inSrcSocket,const mDNSAddr * inDstIP,mDNSIPPort inDstPort)1524*48a54d36SAndroid Build Coastguard Worker 	mDNSPlatformSendUDP(
1525*48a54d36SAndroid Build Coastguard Worker 		const mDNS * const			inMDNS,
1526*48a54d36SAndroid Build Coastguard Worker 		const void * const	        inMsg,
1527*48a54d36SAndroid Build Coastguard Worker 		const mDNSu8 * const		inMsgEnd,
1528*48a54d36SAndroid Build Coastguard Worker 		mDNSInterfaceID 			inInterfaceID,
1529*48a54d36SAndroid Build Coastguard Worker 		UDPSocket *					inSrcSocket,
1530*48a54d36SAndroid Build Coastguard Worker 		const mDNSAddr *			inDstIP,
1531*48a54d36SAndroid Build Coastguard Worker 		mDNSIPPort 					inDstPort )
1532*48a54d36SAndroid Build Coastguard Worker {
1533*48a54d36SAndroid Build Coastguard Worker 	SOCKET						sendingsocket = INVALID_SOCKET;
1534*48a54d36SAndroid Build Coastguard Worker 	mStatus						err = mStatus_NoError;
1535*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData *			ifd = (mDNSInterfaceData*) inInterfaceID;
1536*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_storage		addr;
1537*48a54d36SAndroid Build Coastguard Worker 	int							n;
1538*48a54d36SAndroid Build Coastguard Worker 
1539*48a54d36SAndroid Build Coastguard Worker 	DEBUG_USE_ONLY( inMDNS );
1540*48a54d36SAndroid Build Coastguard Worker 
1541*48a54d36SAndroid Build Coastguard Worker 	n = (int)( inMsgEnd - ( (const mDNSu8 * const) inMsg ) );
1542*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
1543*48a54d36SAndroid Build Coastguard Worker 	check( inMsg );
1544*48a54d36SAndroid Build Coastguard Worker 	check( inMsgEnd );
1545*48a54d36SAndroid Build Coastguard Worker 	check( inDstIP );
1546*48a54d36SAndroid Build Coastguard Worker 
1547*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "platform send %d bytes to %#a:%u\n", n, inDstIP, ntohs( inDstPort.NotAnInteger ) );
1548*48a54d36SAndroid Build Coastguard Worker 
1549*48a54d36SAndroid Build Coastguard Worker 	if( inDstIP->type == mDNSAddrType_IPv4 )
1550*48a54d36SAndroid Build Coastguard Worker 	{
1551*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in *		sa4;
1552*48a54d36SAndroid Build Coastguard Worker 
1553*48a54d36SAndroid Build Coastguard Worker 		sa4						= (struct sockaddr_in *) &addr;
1554*48a54d36SAndroid Build Coastguard Worker 		sa4->sin_family			= AF_INET;
1555*48a54d36SAndroid Build Coastguard Worker 		sa4->sin_port			= inDstPort.NotAnInteger;
1556*48a54d36SAndroid Build Coastguard Worker 		sa4->sin_addr.s_addr	= inDstIP->ip.v4.NotAnInteger;
1557*48a54d36SAndroid Build Coastguard Worker 		sendingsocket           = ifd ? ifd->sock.fd : inMDNS->p->unicastSock4.fd;
1558*48a54d36SAndroid Build Coastguard Worker 
1559*48a54d36SAndroid Build Coastguard Worker 		if (inSrcSocket) { sendingsocket = inSrcSocket->fd; debugf("mDNSPlatformSendUDP using port %d, static port %d, sock %d", mDNSVal16(inSrcSocket->port), inMDNS->p->unicastSock4.fd, sendingsocket); }
1560*48a54d36SAndroid Build Coastguard Worker 	}
1561*48a54d36SAndroid Build Coastguard Worker 	else if( inDstIP->type == mDNSAddrType_IPv6 )
1562*48a54d36SAndroid Build Coastguard Worker 	{
1563*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in6 *		sa6;
1564*48a54d36SAndroid Build Coastguard Worker 
1565*48a54d36SAndroid Build Coastguard Worker 		sa6					= (struct sockaddr_in6 *) &addr;
1566*48a54d36SAndroid Build Coastguard Worker 		sa6->sin6_family	= AF_INET6;
1567*48a54d36SAndroid Build Coastguard Worker 		sa6->sin6_port		= inDstPort.NotAnInteger;
1568*48a54d36SAndroid Build Coastguard Worker 		sa6->sin6_flowinfo	= 0;
1569*48a54d36SAndroid Build Coastguard Worker 		sa6->sin6_addr		= *( (struct in6_addr *) &inDstIP->ip.v6 );
1570*48a54d36SAndroid Build Coastguard Worker 		sa6->sin6_scope_id	= 0;	// Windows requires the scope ID to be zero. IPV6_MULTICAST_IF specifies interface.
1571*48a54d36SAndroid Build Coastguard Worker 		sendingsocket		= ifd ? ifd->sock.fd : inMDNS->p->unicastSock6.fd;
1572*48a54d36SAndroid Build Coastguard Worker 	}
1573*48a54d36SAndroid Build Coastguard Worker 	else
1574*48a54d36SAndroid Build Coastguard Worker 	{
1575*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelError, DEBUG_NAME "%s: dst is not an IPv4 or IPv6 address (type=%d)\n", __ROUTINE__, inDstIP->type );
1576*48a54d36SAndroid Build Coastguard Worker 		err = mStatus_BadParamErr;
1577*48a54d36SAndroid Build Coastguard Worker 		goto exit;
1578*48a54d36SAndroid Build Coastguard Worker 	}
1579*48a54d36SAndroid Build Coastguard Worker 
1580*48a54d36SAndroid Build Coastguard Worker 	if (IsValidSocket(sendingsocket))
1581*48a54d36SAndroid Build Coastguard Worker 	{
1582*48a54d36SAndroid Build Coastguard Worker 		n = sendto( sendingsocket, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
1583*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( n > 0, errno_compat(), kWriteErr );
1584*48a54d36SAndroid Build Coastguard Worker 
1585*48a54d36SAndroid Build Coastguard Worker 		if ( err )
1586*48a54d36SAndroid Build Coastguard Worker 		{
1587*48a54d36SAndroid Build Coastguard Worker 			// Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
1588*48a54d36SAndroid Build Coastguard Worker 
1589*48a54d36SAndroid Build Coastguard Worker 			if ( !mDNSAddressIsAllDNSLinkGroup( inDstIP ) && ( WSAGetLastError() == WSAEHOSTDOWN || WSAGetLastError() == WSAENETDOWN || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAENETUNREACH ) )
1590*48a54d36SAndroid Build Coastguard Worker 			{
1591*48a54d36SAndroid Build Coastguard Worker 				err = mStatus_TransientErr;
1592*48a54d36SAndroid Build Coastguard Worker 			}
1593*48a54d36SAndroid Build Coastguard Worker 			else
1594*48a54d36SAndroid Build Coastguard Worker 			{
1595*48a54d36SAndroid Build Coastguard Worker 				require_noerr( err, exit );
1596*48a54d36SAndroid Build Coastguard Worker 			}
1597*48a54d36SAndroid Build Coastguard Worker 		}
1598*48a54d36SAndroid Build Coastguard Worker 	}
1599*48a54d36SAndroid Build Coastguard Worker 
1600*48a54d36SAndroid Build Coastguard Worker exit:
1601*48a54d36SAndroid Build Coastguard Worker 	return( err );
1602*48a54d36SAndroid Build Coastguard Worker }
1603*48a54d36SAndroid Build Coastguard Worker 
1604*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformUpdateProxyList(mDNS * const m,const mDNSInterfaceID InterfaceID)1605*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
1606*48a54d36SAndroid Build Coastguard Worker 	{
1607*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( m );
1608*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( InterfaceID );
1609*48a54d36SAndroid Build Coastguard Worker 	}
1610*48a54d36SAndroid Build Coastguard Worker 
1611*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1612*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformSendRawPacket
1613*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1614*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformSetAllowSleep(mDNS * const m,mDNSBool allowSleep,const char * reason)1615*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)
1616*48a54d36SAndroid Build Coastguard Worker     {
1617*48a54d36SAndroid Build Coastguard Worker     DEBUG_UNUSED( m );
1618*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( allowSleep );
1619*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( reason );
1620*48a54d36SAndroid Build Coastguard Worker     }
1621*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformSendRawPacket(const void * const msg,const mDNSu8 * const end,mDNSInterfaceID InterfaceID)1622*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
1623*48a54d36SAndroid Build Coastguard Worker 	{
1624*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( msg );
1625*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( end );
1626*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( InterfaceID );
1627*48a54d36SAndroid Build Coastguard Worker 	}
1628*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformReceiveRawPacket(const void * const msg,const mDNSu8 * const end,mDNSInterfaceID InterfaceID)1629*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformReceiveRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
1630*48a54d36SAndroid Build Coastguard Worker 	{
1631*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( msg );
1632*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( end );
1633*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( InterfaceID );
1634*48a54d36SAndroid Build Coastguard Worker 	}
1635*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformSetLocalAddressCacheEntry(mDNS * const m,const mDNSAddr * const tpa,const mDNSEthAddr * const tha,mDNSInterfaceID InterfaceID)1636*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
1637*48a54d36SAndroid Build Coastguard Worker 	{
1638*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( m );
1639*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( tpa );
1640*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( tha );
1641*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( InterfaceID );
1642*48a54d36SAndroid Build Coastguard Worker 	}
1643*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformWriteDebugMsg(const char * msg)1644*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
1645*48a54d36SAndroid Build Coastguard Worker 	{
1646*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, "%s\n", msg );
1647*48a54d36SAndroid Build Coastguard Worker 	}
1648*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformWriteLogMsg(const char * ident,const char * msg,mDNSLogLevel_t loglevel)1649*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformWriteLogMsg( const char * ident, const char * msg, mDNSLogLevel_t loglevel )
1650*48a54d36SAndroid Build Coastguard Worker 	{
1651*48a54d36SAndroid Build Coastguard Worker 	extern mDNS mDNSStorage;
1652*48a54d36SAndroid Build Coastguard Worker 	int type;
1653*48a54d36SAndroid Build Coastguard Worker 
1654*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( ident );
1655*48a54d36SAndroid Build Coastguard Worker 
1656*48a54d36SAndroid Build Coastguard Worker 	type = EVENTLOG_ERROR_TYPE;
1657*48a54d36SAndroid Build Coastguard Worker 
1658*48a54d36SAndroid Build Coastguard Worker 	switch (loglevel)
1659*48a54d36SAndroid Build Coastguard Worker 	{
1660*48a54d36SAndroid Build Coastguard Worker 		case MDNS_LOG_MSG:       type = EVENTLOG_ERROR_TYPE;		break;
1661*48a54d36SAndroid Build Coastguard Worker 		case MDNS_LOG_OPERATION: type = EVENTLOG_WARNING_TYPE;		break;
1662*48a54d36SAndroid Build Coastguard Worker 		case MDNS_LOG_SPS:       type = EVENTLOG_INFORMATION_TYPE;  break;
1663*48a54d36SAndroid Build Coastguard Worker 		case MDNS_LOG_INFO:      type = EVENTLOG_INFORMATION_TYPE;	break;
1664*48a54d36SAndroid Build Coastguard Worker 		case MDNS_LOG_DEBUG:     type = EVENTLOG_INFORMATION_TYPE;	break;
1665*48a54d36SAndroid Build Coastguard Worker 		default:
1666*48a54d36SAndroid Build Coastguard Worker 			fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
1667*48a54d36SAndroid Build Coastguard Worker 			fflush(stderr);
1668*48a54d36SAndroid Build Coastguard Worker 			}
1669*48a54d36SAndroid Build Coastguard Worker 
1670*48a54d36SAndroid Build Coastguard Worker 	mDNSStorage.p->reportStatusFunc( type, msg );
1671*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, "%s\n", msg );
1672*48a54d36SAndroid Build Coastguard Worker 	}
1673*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformSourceAddrForDest(mDNSAddr * const src,const mDNSAddr * const dst)1674*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformSourceAddrForDest( mDNSAddr * const src, const mDNSAddr * const dst )
1675*48a54d36SAndroid Build Coastguard Worker 	{
1676*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( src );
1677*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( dst );
1678*48a54d36SAndroid Build Coastguard Worker 	}
1679*48a54d36SAndroid Build Coastguard Worker 
1680*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1681*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTLSSetupCerts
1682*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1683*48a54d36SAndroid Build Coastguard Worker 
1684*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus
mDNSPlatformTLSSetupCerts(void)1685*48a54d36SAndroid Build Coastguard Worker mDNSPlatformTLSSetupCerts(void)
1686*48a54d36SAndroid Build Coastguard Worker {
1687*48a54d36SAndroid Build Coastguard Worker 	return mStatus_UnsupportedErr;
1688*48a54d36SAndroid Build Coastguard Worker }
1689*48a54d36SAndroid Build Coastguard Worker 
1690*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1691*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformTLSTearDownCerts
1692*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1693*48a54d36SAndroid Build Coastguard Worker 
1694*48a54d36SAndroid Build Coastguard Worker mDNSexport void
mDNSPlatformTLSTearDownCerts(void)1695*48a54d36SAndroid Build Coastguard Worker mDNSPlatformTLSTearDownCerts(void)
1696*48a54d36SAndroid Build Coastguard Worker {
1697*48a54d36SAndroid Build Coastguard Worker }
1698*48a54d36SAndroid Build Coastguard Worker 
1699*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1700*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformSetDNSConfig
1701*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1702*48a54d36SAndroid Build Coastguard Worker 
1703*48a54d36SAndroid Build Coastguard Worker mDNSlocal void SetDNSServers( mDNS *const m );
1704*48a54d36SAndroid Build Coastguard Worker mDNSlocal void SetSearchDomainList( void );
1705*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformSetDNSConfig(mDNS * const m,mDNSBool setservers,mDNSBool setsearch,domainname * const fqdn,DNameListElem ** regDomains,DNameListElem ** browseDomains)1706*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **regDomains, DNameListElem **browseDomains)
1707*48a54d36SAndroid Build Coastguard Worker {
1708*48a54d36SAndroid Build Coastguard Worker 	if (setservers) SetDNSServers(m);
1709*48a54d36SAndroid Build Coastguard Worker 	if (setsearch) SetSearchDomainList();
1710*48a54d36SAndroid Build Coastguard Worker 
1711*48a54d36SAndroid Build Coastguard Worker 	if ( fqdn )
1712*48a54d36SAndroid Build Coastguard Worker 	{
1713*48a54d36SAndroid Build Coastguard Worker 		GetDDNSFQDN( fqdn );
1714*48a54d36SAndroid Build Coastguard Worker 	}
1715*48a54d36SAndroid Build Coastguard Worker 
1716*48a54d36SAndroid Build Coastguard Worker 	if ( browseDomains )
1717*48a54d36SAndroid Build Coastguard Worker 	{
1718*48a54d36SAndroid Build Coastguard Worker 		GetDDNSDomains( browseDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSBrowseDomains );
1719*48a54d36SAndroid Build Coastguard Worker 	}
1720*48a54d36SAndroid Build Coastguard Worker 
1721*48a54d36SAndroid Build Coastguard Worker 	if ( regDomains )
1722*48a54d36SAndroid Build Coastguard Worker 	{
1723*48a54d36SAndroid Build Coastguard Worker 		GetDDNSDomains( regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
1724*48a54d36SAndroid Build Coastguard Worker 	}
1725*48a54d36SAndroid Build Coastguard Worker }
1726*48a54d36SAndroid Build Coastguard Worker 
1727*48a54d36SAndroid Build Coastguard Worker 
1728*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1729*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformDynDNSHostNameStatusChanged
1730*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1731*48a54d36SAndroid Build Coastguard Worker 
1732*48a54d36SAndroid Build Coastguard Worker mDNSexport void
mDNSPlatformDynDNSHostNameStatusChanged(const domainname * const dname,const mStatus status)1733*48a54d36SAndroid Build Coastguard Worker mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
1734*48a54d36SAndroid Build Coastguard Worker {
1735*48a54d36SAndroid Build Coastguard Worker 	char		uname[MAX_ESCAPED_DOMAIN_NAME];
1736*48a54d36SAndroid Build Coastguard Worker 	BYTE		bStatus;
1737*48a54d36SAndroid Build Coastguard Worker 	LPCTSTR		name;
1738*48a54d36SAndroid Build Coastguard Worker 	HKEY		key = NULL;
1739*48a54d36SAndroid Build Coastguard Worker 	mStatus		err;
1740*48a54d36SAndroid Build Coastguard Worker 	char	*	p;
1741*48a54d36SAndroid Build Coastguard Worker 
1742*48a54d36SAndroid Build Coastguard Worker 	ConvertDomainNameToCString(dname, uname);
1743*48a54d36SAndroid Build Coastguard Worker 
1744*48a54d36SAndroid Build Coastguard Worker 	p = uname;
1745*48a54d36SAndroid Build Coastguard Worker 
1746*48a54d36SAndroid Build Coastguard Worker 	while (*p)
1747*48a54d36SAndroid Build Coastguard Worker 	{
1748*48a54d36SAndroid Build Coastguard Worker 		*p = (char) tolower(*p);
1749*48a54d36SAndroid Build Coastguard Worker 		if (!(*(p+1)) && *p == '.') *p = 0; // if last character, strip trailing dot
1750*48a54d36SAndroid Build Coastguard Worker 		p++;
1751*48a54d36SAndroid Build Coastguard Worker 	}
1752*48a54d36SAndroid Build Coastguard Worker 
1753*48a54d36SAndroid Build Coastguard Worker 	check( strlen( p ) <= MAX_ESCAPED_DOMAIN_NAME );
1754*48a54d36SAndroid Build Coastguard Worker 	name = kServiceParametersNode TEXT("\\DynDNS\\State\\HostNames");
1755*48a54d36SAndroid Build Coastguard Worker 	err = RegCreateKey( HKEY_LOCAL_MACHINE, name, &key );
1756*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1757*48a54d36SAndroid Build Coastguard Worker 
1758*48a54d36SAndroid Build Coastguard Worker 	bStatus = ( status ) ? 0 : 1;
1759*48a54d36SAndroid Build Coastguard Worker 	err = RegSetValueEx( key, kServiceDynDNSStatus, 0, REG_DWORD, (const LPBYTE) &bStatus, sizeof(DWORD) );
1760*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1761*48a54d36SAndroid Build Coastguard Worker 
1762*48a54d36SAndroid Build Coastguard Worker exit:
1763*48a54d36SAndroid Build Coastguard Worker 
1764*48a54d36SAndroid Build Coastguard Worker 	if ( key )
1765*48a54d36SAndroid Build Coastguard Worker 	{
1766*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( key );
1767*48a54d36SAndroid Build Coastguard Worker 	}
1768*48a54d36SAndroid Build Coastguard Worker 
1769*48a54d36SAndroid Build Coastguard Worker 	return;
1770*48a54d36SAndroid Build Coastguard Worker }
1771*48a54d36SAndroid Build Coastguard Worker 
1772*48a54d36SAndroid Build Coastguard Worker 
FreeEtcHosts(mDNS * const m,AuthRecord * const rr,mStatus result)1773*48a54d36SAndroid Build Coastguard Worker mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result)
1774*48a54d36SAndroid Build Coastguard Worker     {
1775*48a54d36SAndroid Build Coastguard Worker     (void)m;  // unused
1776*48a54d36SAndroid Build Coastguard Worker     (void)rr;
1777*48a54d36SAndroid Build Coastguard Worker     (void)result;
1778*48a54d36SAndroid Build Coastguard Worker     }
1779*48a54d36SAndroid Build Coastguard Worker 
1780*48a54d36SAndroid Build Coastguard Worker 
1781*48a54d36SAndroid Build Coastguard Worker 
1782*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1783*48a54d36SAndroid Build Coastguard Worker //	SetDomainSecrets
1784*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1785*48a54d36SAndroid Build Coastguard Worker 
1786*48a54d36SAndroid Build Coastguard Worker // This routine needs to be called whenever the system secrets database changes.
1787*48a54d36SAndroid Build Coastguard Worker // We call it from DynDNSConfigDidChange and mDNSPlatformInit
1788*48a54d36SAndroid Build Coastguard Worker 
1789*48a54d36SAndroid Build Coastguard Worker void
SetDomainSecrets(mDNS * const m)1790*48a54d36SAndroid Build Coastguard Worker SetDomainSecrets( mDNS * const m )
1791*48a54d36SAndroid Build Coastguard Worker {
1792*48a54d36SAndroid Build Coastguard Worker 	DomainAuthInfo *ptr;
1793*48a54d36SAndroid Build Coastguard Worker 	domainname		fqdn;
1794*48a54d36SAndroid Build Coastguard Worker 	DNameListElem * regDomains = NULL;
1795*48a54d36SAndroid Build Coastguard Worker 
1796*48a54d36SAndroid Build Coastguard Worker 	// Rather than immediately deleting all keys now, we mark them for deletion in ten seconds.
1797*48a54d36SAndroid Build Coastguard Worker 	// In the case where the user simultaneously removes their DDNS host name and the key
1798*48a54d36SAndroid Build Coastguard Worker 	// for it, this gives mDNSResponder ten seconds to gracefully delete the name from the
1799*48a54d36SAndroid Build Coastguard Worker 	// server before it loses access to the necessary key. Otherwise, we'd leave orphaned
1800*48a54d36SAndroid Build Coastguard Worker 	// address records behind that we no longer have permission to delete.
1801*48a54d36SAndroid Build Coastguard Worker 
1802*48a54d36SAndroid Build Coastguard Worker 	for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
1803*48a54d36SAndroid Build Coastguard Worker 		ptr->deltime = NonZeroTime(m->timenow + mDNSPlatformOneSecond*10);
1804*48a54d36SAndroid Build Coastguard Worker 
1805*48a54d36SAndroid Build Coastguard Worker 	GetDDNSFQDN( &fqdn );
1806*48a54d36SAndroid Build Coastguard Worker 
1807*48a54d36SAndroid Build Coastguard Worker 	if ( fqdn.c[ 0 ] )
1808*48a54d36SAndroid Build Coastguard Worker 	{
1809*48a54d36SAndroid Build Coastguard Worker 		SetDomainSecret( m, &fqdn );
1810*48a54d36SAndroid Build Coastguard Worker 	}
1811*48a54d36SAndroid Build Coastguard Worker 
1812*48a54d36SAndroid Build Coastguard Worker 	GetDDNSDomains( &regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
1813*48a54d36SAndroid Build Coastguard Worker 
1814*48a54d36SAndroid Build Coastguard Worker 	while ( regDomains )
1815*48a54d36SAndroid Build Coastguard Worker 	{
1816*48a54d36SAndroid Build Coastguard Worker 		DNameListElem * current = regDomains;
1817*48a54d36SAndroid Build Coastguard Worker 		SetDomainSecret( m, &current->name );
1818*48a54d36SAndroid Build Coastguard Worker 		regDomains = regDomains->next;
1819*48a54d36SAndroid Build Coastguard Worker 		free( current );
1820*48a54d36SAndroid Build Coastguard Worker 	}
1821*48a54d36SAndroid Build Coastguard Worker }
1822*48a54d36SAndroid Build Coastguard Worker 
1823*48a54d36SAndroid Build Coastguard Worker 
1824*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1825*48a54d36SAndroid Build Coastguard Worker //	SetSearchDomainList
1826*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1827*48a54d36SAndroid Build Coastguard Worker 
1828*48a54d36SAndroid Build Coastguard Worker mDNSlocal void SetDomainFromDHCP( void );
1829*48a54d36SAndroid Build Coastguard Worker mDNSlocal void SetReverseMapSearchDomainList( void );
1830*48a54d36SAndroid Build Coastguard Worker 
1831*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
SetSearchDomainList(void)1832*48a54d36SAndroid Build Coastguard Worker SetSearchDomainList( void )
1833*48a54d36SAndroid Build Coastguard Worker {
1834*48a54d36SAndroid Build Coastguard Worker 	char			*	searchList	= NULL;
1835*48a54d36SAndroid Build Coastguard Worker 	DWORD				searchListLen;
1836*48a54d36SAndroid Build Coastguard Worker 	//DNameListElem	*	head = NULL;
1837*48a54d36SAndroid Build Coastguard Worker 	//DNameListElem	*	current = NULL;
1838*48a54d36SAndroid Build Coastguard Worker 	char			*	tok;
1839*48a54d36SAndroid Build Coastguard Worker 	HKEY				key;
1840*48a54d36SAndroid Build Coastguard Worker 	mStatus				err;
1841*48a54d36SAndroid Build Coastguard Worker 
1842*48a54d36SAndroid Build Coastguard Worker 	err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &key );
1843*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1844*48a54d36SAndroid Build Coastguard Worker 
1845*48a54d36SAndroid Build Coastguard Worker 	err = RegQueryString( key, "SearchList", &searchList, &searchListLen, NULL );
1846*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1847*48a54d36SAndroid Build Coastguard Worker 
1848*48a54d36SAndroid Build Coastguard Worker 	// Windows separates the search domains with ','
1849*48a54d36SAndroid Build Coastguard Worker 
1850*48a54d36SAndroid Build Coastguard Worker 	tok = strtok( searchList, "," );
1851*48a54d36SAndroid Build Coastguard Worker 	while ( tok )
1852*48a54d36SAndroid Build Coastguard Worker 	{
1853*48a54d36SAndroid Build Coastguard Worker 		if ( ( strcmp( tok, "" ) != 0 ) && ( strcmp( tok, "." ) != 0 ) )
1854*48a54d36SAndroid Build Coastguard Worker 			mDNS_AddSearchDomain_CString(tok, mDNSNULL);
1855*48a54d36SAndroid Build Coastguard Worker 		tok = strtok( NULL, "," );
1856*48a54d36SAndroid Build Coastguard Worker 	}
1857*48a54d36SAndroid Build Coastguard Worker 
1858*48a54d36SAndroid Build Coastguard Worker exit:
1859*48a54d36SAndroid Build Coastguard Worker 
1860*48a54d36SAndroid Build Coastguard Worker 	if ( searchList )
1861*48a54d36SAndroid Build Coastguard Worker 	{
1862*48a54d36SAndroid Build Coastguard Worker 		free( searchList );
1863*48a54d36SAndroid Build Coastguard Worker 	}
1864*48a54d36SAndroid Build Coastguard Worker 
1865*48a54d36SAndroid Build Coastguard Worker 	if ( key )
1866*48a54d36SAndroid Build Coastguard Worker 	{
1867*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( key );
1868*48a54d36SAndroid Build Coastguard Worker 	}
1869*48a54d36SAndroid Build Coastguard Worker 
1870*48a54d36SAndroid Build Coastguard Worker 	SetDomainFromDHCP();
1871*48a54d36SAndroid Build Coastguard Worker 	SetReverseMapSearchDomainList();
1872*48a54d36SAndroid Build Coastguard Worker }
1873*48a54d36SAndroid Build Coastguard Worker 
1874*48a54d36SAndroid Build Coastguard Worker 
1875*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1876*48a54d36SAndroid Build Coastguard Worker //	SetReverseMapSearchDomainList
1877*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1878*48a54d36SAndroid Build Coastguard Worker 
1879*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
SetReverseMapSearchDomainList(void)1880*48a54d36SAndroid Build Coastguard Worker SetReverseMapSearchDomainList( void )
1881*48a54d36SAndroid Build Coastguard Worker {
1882*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs	*	ifa;
1883*48a54d36SAndroid Build Coastguard Worker 
1884*48a54d36SAndroid Build Coastguard Worker 	ifa = myGetIfAddrs( 1 );
1885*48a54d36SAndroid Build Coastguard Worker 	while (ifa)
1886*48a54d36SAndroid Build Coastguard Worker 	{
1887*48a54d36SAndroid Build Coastguard Worker 		mDNSAddr addr;
1888*48a54d36SAndroid Build Coastguard Worker 
1889*48a54d36SAndroid Build Coastguard Worker 		if (ifa->ifa_addr->sa_family == AF_INET && !SetupAddr(&addr, ifa->ifa_addr) && !(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_netmask)
1890*48a54d36SAndroid Build Coastguard Worker 		{
1891*48a54d36SAndroid Build Coastguard Worker 			mDNSAddr	netmask;
1892*48a54d36SAndroid Build Coastguard Worker 			char		buffer[256];
1893*48a54d36SAndroid Build Coastguard Worker 
1894*48a54d36SAndroid Build Coastguard Worker 			if (!SetupAddr(&netmask, ifa->ifa_netmask))
1895*48a54d36SAndroid Build Coastguard Worker 			{
1896*48a54d36SAndroid Build Coastguard Worker 				sprintf(buffer, "%d.%d.%d.%d.in-addr.arpa.", addr.ip.v4.b[3] & netmask.ip.v4.b[3],
1897*48a54d36SAndroid Build Coastguard Worker                                                              addr.ip.v4.b[2] & netmask.ip.v4.b[2],
1898*48a54d36SAndroid Build Coastguard Worker                                                              addr.ip.v4.b[1] & netmask.ip.v4.b[1],
1899*48a54d36SAndroid Build Coastguard Worker                                                              addr.ip.v4.b[0] & netmask.ip.v4.b[0]);
1900*48a54d36SAndroid Build Coastguard Worker 				mDNS_AddSearchDomain_CString(buffer, mDNSNULL);
1901*48a54d36SAndroid Build Coastguard Worker 			}
1902*48a54d36SAndroid Build Coastguard Worker 		}
1903*48a54d36SAndroid Build Coastguard Worker 
1904*48a54d36SAndroid Build Coastguard Worker 		ifa = ifa->ifa_next;
1905*48a54d36SAndroid Build Coastguard Worker 	}
1906*48a54d36SAndroid Build Coastguard Worker 
1907*48a54d36SAndroid Build Coastguard Worker 	return;
1908*48a54d36SAndroid Build Coastguard Worker }
1909*48a54d36SAndroid Build Coastguard Worker 
1910*48a54d36SAndroid Build Coastguard Worker 
1911*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1912*48a54d36SAndroid Build Coastguard Worker //	SetDNSServers
1913*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1914*48a54d36SAndroid Build Coastguard Worker 
1915*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
SetDNSServers(mDNS * const m)1916*48a54d36SAndroid Build Coastguard Worker SetDNSServers( mDNS *const m )
1917*48a54d36SAndroid Build Coastguard Worker {
1918*48a54d36SAndroid Build Coastguard Worker 	PIP_PER_ADAPTER_INFO	pAdapterInfo	=	NULL;
1919*48a54d36SAndroid Build Coastguard Worker 	FIXED_INFO			*	fixedInfo	= NULL;
1920*48a54d36SAndroid Build Coastguard Worker 	ULONG					bufLen		= 0;
1921*48a54d36SAndroid Build Coastguard Worker 	IP_ADDR_STRING		*	dnsServerList;
1922*48a54d36SAndroid Build Coastguard Worker 	IP_ADDR_STRING		*	ipAddr;
1923*48a54d36SAndroid Build Coastguard Worker 	DWORD					index;
1924*48a54d36SAndroid Build Coastguard Worker 	int						i			= 0;
1925*48a54d36SAndroid Build Coastguard Worker 	mStatus					err			= kUnknownErr;
1926*48a54d36SAndroid Build Coastguard Worker 
1927*48a54d36SAndroid Build Coastguard Worker 	// Get the primary interface.
1928*48a54d36SAndroid Build Coastguard Worker 
1929*48a54d36SAndroid Build Coastguard Worker 	index = GetPrimaryInterface();
1930*48a54d36SAndroid Build Coastguard Worker 
1931*48a54d36SAndroid Build Coastguard Worker 	// This should have the interface index of the primary index.  Fall back in cases where
1932*48a54d36SAndroid Build Coastguard Worker 	// it can't be determined.
1933*48a54d36SAndroid Build Coastguard Worker 
1934*48a54d36SAndroid Build Coastguard Worker 	if ( index )
1935*48a54d36SAndroid Build Coastguard Worker 	{
1936*48a54d36SAndroid Build Coastguard Worker 		bufLen = 0;
1937*48a54d36SAndroid Build Coastguard Worker 
1938*48a54d36SAndroid Build Coastguard Worker 		for ( i = 0; i < 100; i++ )
1939*48a54d36SAndroid Build Coastguard Worker 		{
1940*48a54d36SAndroid Build Coastguard Worker 			err = GetPerAdapterInfo( index, pAdapterInfo, &bufLen );
1941*48a54d36SAndroid Build Coastguard Worker 
1942*48a54d36SAndroid Build Coastguard Worker 			if ( err != ERROR_BUFFER_OVERFLOW )
1943*48a54d36SAndroid Build Coastguard Worker 			{
1944*48a54d36SAndroid Build Coastguard Worker 				break;
1945*48a54d36SAndroid Build Coastguard Worker 			}
1946*48a54d36SAndroid Build Coastguard Worker 
1947*48a54d36SAndroid Build Coastguard Worker 			pAdapterInfo = (PIP_PER_ADAPTER_INFO) realloc( pAdapterInfo, bufLen );
1948*48a54d36SAndroid Build Coastguard Worker 			require_action( pAdapterInfo, exit, err = mStatus_NoMemoryErr );
1949*48a54d36SAndroid Build Coastguard Worker 		}
1950*48a54d36SAndroid Build Coastguard Worker 
1951*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1952*48a54d36SAndroid Build Coastguard Worker 
1953*48a54d36SAndroid Build Coastguard Worker 		dnsServerList = &pAdapterInfo->DnsServerList;
1954*48a54d36SAndroid Build Coastguard Worker 	}
1955*48a54d36SAndroid Build Coastguard Worker 	else
1956*48a54d36SAndroid Build Coastguard Worker 	{
1957*48a54d36SAndroid Build Coastguard Worker 		bufLen = sizeof( FIXED_INFO );
1958*48a54d36SAndroid Build Coastguard Worker 
1959*48a54d36SAndroid Build Coastguard Worker 		for ( i = 0; i < 100; i++ )
1960*48a54d36SAndroid Build Coastguard Worker 		{
1961*48a54d36SAndroid Build Coastguard Worker 			if ( fixedInfo )
1962*48a54d36SAndroid Build Coastguard Worker 			{
1963*48a54d36SAndroid Build Coastguard Worker 				GlobalFree( fixedInfo );
1964*48a54d36SAndroid Build Coastguard Worker 				fixedInfo = NULL;
1965*48a54d36SAndroid Build Coastguard Worker 			}
1966*48a54d36SAndroid Build Coastguard Worker 
1967*48a54d36SAndroid Build Coastguard Worker 			fixedInfo = (FIXED_INFO*) GlobalAlloc( GPTR, bufLen );
1968*48a54d36SAndroid Build Coastguard Worker 			require_action( fixedInfo, exit, err = mStatus_NoMemoryErr );
1969*48a54d36SAndroid Build Coastguard Worker 
1970*48a54d36SAndroid Build Coastguard Worker 			err = GetNetworkParams( fixedInfo, &bufLen );
1971*48a54d36SAndroid Build Coastguard Worker 
1972*48a54d36SAndroid Build Coastguard Worker 			if ( err != ERROR_BUFFER_OVERFLOW )
1973*48a54d36SAndroid Build Coastguard Worker 			{
1974*48a54d36SAndroid Build Coastguard Worker 				break;
1975*48a54d36SAndroid Build Coastguard Worker 			}
1976*48a54d36SAndroid Build Coastguard Worker 		}
1977*48a54d36SAndroid Build Coastguard Worker 
1978*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1979*48a54d36SAndroid Build Coastguard Worker 
1980*48a54d36SAndroid Build Coastguard Worker 		dnsServerList = &fixedInfo->DnsServerList;
1981*48a54d36SAndroid Build Coastguard Worker 	}
1982*48a54d36SAndroid Build Coastguard Worker 
1983*48a54d36SAndroid Build Coastguard Worker 	for ( ipAddr = dnsServerList; ipAddr; ipAddr = ipAddr->Next )
1984*48a54d36SAndroid Build Coastguard Worker 	{
1985*48a54d36SAndroid Build Coastguard Worker 		mDNSAddr addr;
1986*48a54d36SAndroid Build Coastguard Worker 		err = StringToAddress( &addr, ipAddr->IpAddress.String );
1987*48a54d36SAndroid Build Coastguard Worker 		if ( !err ) mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, &addr, UnicastDNSPort, mDNSfalse, 0);
1988*48a54d36SAndroid Build Coastguard Worker 	}
1989*48a54d36SAndroid Build Coastguard Worker 
1990*48a54d36SAndroid Build Coastguard Worker exit:
1991*48a54d36SAndroid Build Coastguard Worker 
1992*48a54d36SAndroid Build Coastguard Worker 	if ( pAdapterInfo )
1993*48a54d36SAndroid Build Coastguard Worker 	{
1994*48a54d36SAndroid Build Coastguard Worker 		free( pAdapterInfo );
1995*48a54d36SAndroid Build Coastguard Worker 	}
1996*48a54d36SAndroid Build Coastguard Worker 
1997*48a54d36SAndroid Build Coastguard Worker 	if ( fixedInfo )
1998*48a54d36SAndroid Build Coastguard Worker 	{
1999*48a54d36SAndroid Build Coastguard Worker 		GlobalFree( fixedInfo );
2000*48a54d36SAndroid Build Coastguard Worker 	}
2001*48a54d36SAndroid Build Coastguard Worker }
2002*48a54d36SAndroid Build Coastguard Worker 
2003*48a54d36SAndroid Build Coastguard Worker 
2004*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2005*48a54d36SAndroid Build Coastguard Worker //	SetDomainFromDHCP
2006*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2007*48a54d36SAndroid Build Coastguard Worker 
2008*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
SetDomainFromDHCP(void)2009*48a54d36SAndroid Build Coastguard Worker SetDomainFromDHCP( void )
2010*48a54d36SAndroid Build Coastguard Worker {
2011*48a54d36SAndroid Build Coastguard Worker 	int					i			= 0;
2012*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_INFO *	pAdapterInfo;
2013*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_INFO *	pAdapter;
2014*48a54d36SAndroid Build Coastguard Worker 	DWORD				bufLen;
2015*48a54d36SAndroid Build Coastguard Worker 	DWORD				index;
2016*48a54d36SAndroid Build Coastguard Worker 	HKEY				key = NULL;
2017*48a54d36SAndroid Build Coastguard Worker 	LPSTR				domain = NULL;
2018*48a54d36SAndroid Build Coastguard Worker 	DWORD				dwSize;
2019*48a54d36SAndroid Build Coastguard Worker 	mStatus				err = mStatus_NoError;
2020*48a54d36SAndroid Build Coastguard Worker 
2021*48a54d36SAndroid Build Coastguard Worker 	pAdapterInfo	= NULL;
2022*48a54d36SAndroid Build Coastguard Worker 
2023*48a54d36SAndroid Build Coastguard Worker 	for ( i = 0; i < 100; i++ )
2024*48a54d36SAndroid Build Coastguard Worker 	{
2025*48a54d36SAndroid Build Coastguard Worker 		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
2026*48a54d36SAndroid Build Coastguard Worker 
2027*48a54d36SAndroid Build Coastguard Worker 		if ( err != ERROR_BUFFER_OVERFLOW )
2028*48a54d36SAndroid Build Coastguard Worker 		{
2029*48a54d36SAndroid Build Coastguard Worker 			break;
2030*48a54d36SAndroid Build Coastguard Worker 		}
2031*48a54d36SAndroid Build Coastguard Worker 
2032*48a54d36SAndroid Build Coastguard Worker 		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
2033*48a54d36SAndroid Build Coastguard Worker 		require_action( pAdapterInfo, exit, err = kNoMemoryErr );
2034*48a54d36SAndroid Build Coastguard Worker 	}
2035*48a54d36SAndroid Build Coastguard Worker 
2036*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2037*48a54d36SAndroid Build Coastguard Worker 
2038*48a54d36SAndroid Build Coastguard Worker 	index = GetPrimaryInterface();
2039*48a54d36SAndroid Build Coastguard Worker 
2040*48a54d36SAndroid Build Coastguard Worker 	for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
2041*48a54d36SAndroid Build Coastguard Worker 	{
2042*48a54d36SAndroid Build Coastguard Worker 		if ( pAdapter->IpAddressList.IpAddress.String &&
2043*48a54d36SAndroid Build Coastguard Worker 		     pAdapter->IpAddressList.IpAddress.String[0] &&
2044*48a54d36SAndroid Build Coastguard Worker 		     pAdapter->GatewayList.IpAddress.String &&
2045*48a54d36SAndroid Build Coastguard Worker 		     pAdapter->GatewayList.IpAddress.String[0] &&
2046*48a54d36SAndroid Build Coastguard Worker 		     ( !index || ( pAdapter->Index == index ) ) )
2047*48a54d36SAndroid Build Coastguard Worker 		{
2048*48a54d36SAndroid Build Coastguard Worker 			// Found one that will work
2049*48a54d36SAndroid Build Coastguard Worker 
2050*48a54d36SAndroid Build Coastguard Worker 			char keyName[1024];
2051*48a54d36SAndroid Build Coastguard Worker 
2052*48a54d36SAndroid Build Coastguard Worker 			_snprintf( keyName, 1024, "%s%s", "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\", pAdapter->AdapterName );
2053*48a54d36SAndroid Build Coastguard Worker 
2054*48a54d36SAndroid Build Coastguard Worker 			err = RegCreateKeyA( HKEY_LOCAL_MACHINE, keyName, &key );
2055*48a54d36SAndroid Build Coastguard Worker 			require_noerr( err, exit );
2056*48a54d36SAndroid Build Coastguard Worker 
2057*48a54d36SAndroid Build Coastguard Worker 			err = RegQueryString( key, "Domain", &domain, &dwSize, NULL );
2058*48a54d36SAndroid Build Coastguard Worker 			check_noerr( err );
2059*48a54d36SAndroid Build Coastguard Worker 
2060*48a54d36SAndroid Build Coastguard Worker 			if ( !domain || !domain[0] )
2061*48a54d36SAndroid Build Coastguard Worker 			{
2062*48a54d36SAndroid Build Coastguard Worker 				if ( domain )
2063*48a54d36SAndroid Build Coastguard Worker 				{
2064*48a54d36SAndroid Build Coastguard Worker 					free( domain );
2065*48a54d36SAndroid Build Coastguard Worker 					domain = NULL;
2066*48a54d36SAndroid Build Coastguard Worker 				}
2067*48a54d36SAndroid Build Coastguard Worker 
2068*48a54d36SAndroid Build Coastguard Worker 				err = RegQueryString( key, "DhcpDomain", &domain, &dwSize, NULL );
2069*48a54d36SAndroid Build Coastguard Worker 				check_noerr( err );
2070*48a54d36SAndroid Build Coastguard Worker 			}
2071*48a54d36SAndroid Build Coastguard Worker 
2072*48a54d36SAndroid Build Coastguard Worker 			if ( domain && domain[0] ) mDNS_AddSearchDomain_CString(domain, mDNSNULL);
2073*48a54d36SAndroid Build Coastguard Worker 
2074*48a54d36SAndroid Build Coastguard Worker 			break;
2075*48a54d36SAndroid Build Coastguard Worker 		}
2076*48a54d36SAndroid Build Coastguard Worker 	}
2077*48a54d36SAndroid Build Coastguard Worker 
2078*48a54d36SAndroid Build Coastguard Worker exit:
2079*48a54d36SAndroid Build Coastguard Worker 
2080*48a54d36SAndroid Build Coastguard Worker 	if ( pAdapterInfo )
2081*48a54d36SAndroid Build Coastguard Worker 	{
2082*48a54d36SAndroid Build Coastguard Worker 		free( pAdapterInfo );
2083*48a54d36SAndroid Build Coastguard Worker 	}
2084*48a54d36SAndroid Build Coastguard Worker 
2085*48a54d36SAndroid Build Coastguard Worker 	if ( domain )
2086*48a54d36SAndroid Build Coastguard Worker 	{
2087*48a54d36SAndroid Build Coastguard Worker 		free( domain );
2088*48a54d36SAndroid Build Coastguard Worker 	}
2089*48a54d36SAndroid Build Coastguard Worker 
2090*48a54d36SAndroid Build Coastguard Worker 	if ( key )
2091*48a54d36SAndroid Build Coastguard Worker 	{
2092*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( key );
2093*48a54d36SAndroid Build Coastguard Worker 	}
2094*48a54d36SAndroid Build Coastguard Worker }
2095*48a54d36SAndroid Build Coastguard Worker 
2096*48a54d36SAndroid Build Coastguard Worker 
2097*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2098*48a54d36SAndroid Build Coastguard Worker //	mDNSPlatformGetPrimaryInterface
2099*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2100*48a54d36SAndroid Build Coastguard Worker 
2101*48a54d36SAndroid Build Coastguard Worker mDNSexport mStatus
mDNSPlatformGetPrimaryInterface(mDNS * const m,mDNSAddr * v4,mDNSAddr * v6,mDNSAddr * router)2102*48a54d36SAndroid Build Coastguard Worker mDNSPlatformGetPrimaryInterface( mDNS * const m, mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router )
2103*48a54d36SAndroid Build Coastguard Worker {
2104*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_INFO *	pAdapterInfo;
2105*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_INFO *	pAdapter;
2106*48a54d36SAndroid Build Coastguard Worker 	DWORD				bufLen;
2107*48a54d36SAndroid Build Coastguard Worker 	int					i;
2108*48a54d36SAndroid Build Coastguard Worker 	BOOL				found;
2109*48a54d36SAndroid Build Coastguard Worker 	DWORD				index;
2110*48a54d36SAndroid Build Coastguard Worker 	mStatus				err = mStatus_NoError;
2111*48a54d36SAndroid Build Coastguard Worker 
2112*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( m );
2113*48a54d36SAndroid Build Coastguard Worker 
2114*48a54d36SAndroid Build Coastguard Worker 	*v6 = zeroAddr;
2115*48a54d36SAndroid Build Coastguard Worker 
2116*48a54d36SAndroid Build Coastguard Worker 	pAdapterInfo	= NULL;
2117*48a54d36SAndroid Build Coastguard Worker 	bufLen			= 0;
2118*48a54d36SAndroid Build Coastguard Worker 	found			= FALSE;
2119*48a54d36SAndroid Build Coastguard Worker 
2120*48a54d36SAndroid Build Coastguard Worker 	for ( i = 0; i < 100; i++ )
2121*48a54d36SAndroid Build Coastguard Worker 	{
2122*48a54d36SAndroid Build Coastguard Worker 		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
2123*48a54d36SAndroid Build Coastguard Worker 
2124*48a54d36SAndroid Build Coastguard Worker 		if ( err != ERROR_BUFFER_OVERFLOW )
2125*48a54d36SAndroid Build Coastguard Worker 		{
2126*48a54d36SAndroid Build Coastguard Worker 			break;
2127*48a54d36SAndroid Build Coastguard Worker 		}
2128*48a54d36SAndroid Build Coastguard Worker 
2129*48a54d36SAndroid Build Coastguard Worker 		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
2130*48a54d36SAndroid Build Coastguard Worker 		require_action( pAdapterInfo, exit, err = kNoMemoryErr );
2131*48a54d36SAndroid Build Coastguard Worker 	}
2132*48a54d36SAndroid Build Coastguard Worker 
2133*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2134*48a54d36SAndroid Build Coastguard Worker 
2135*48a54d36SAndroid Build Coastguard Worker 	index = GetPrimaryInterface();
2136*48a54d36SAndroid Build Coastguard Worker 
2137*48a54d36SAndroid Build Coastguard Worker 	for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
2138*48a54d36SAndroid Build Coastguard Worker 	{
2139*48a54d36SAndroid Build Coastguard Worker 		if ( pAdapter->IpAddressList.IpAddress.String &&
2140*48a54d36SAndroid Build Coastguard Worker 		     pAdapter->IpAddressList.IpAddress.String[0] &&
2141*48a54d36SAndroid Build Coastguard Worker 		     pAdapter->GatewayList.IpAddress.String &&
2142*48a54d36SAndroid Build Coastguard Worker 		     pAdapter->GatewayList.IpAddress.String[0] &&
2143*48a54d36SAndroid Build Coastguard Worker 		     ( StringToAddress( v4, pAdapter->IpAddressList.IpAddress.String ) == mStatus_NoError ) &&
2144*48a54d36SAndroid Build Coastguard Worker 		     ( StringToAddress( router, pAdapter->GatewayList.IpAddress.String ) == mStatus_NoError ) &&
2145*48a54d36SAndroid Build Coastguard Worker 		     ( !index || ( pAdapter->Index == index ) ) )
2146*48a54d36SAndroid Build Coastguard Worker 		{
2147*48a54d36SAndroid Build Coastguard Worker 			// Found one that will work
2148*48a54d36SAndroid Build Coastguard Worker 
2149*48a54d36SAndroid Build Coastguard Worker 			if ( pAdapter->AddressLength == sizeof( m->PrimaryMAC ) )
2150*48a54d36SAndroid Build Coastguard Worker 			{
2151*48a54d36SAndroid Build Coastguard Worker 				memcpy( &m->PrimaryMAC, pAdapter->Address, pAdapter->AddressLength );
2152*48a54d36SAndroid Build Coastguard Worker 			}
2153*48a54d36SAndroid Build Coastguard Worker 
2154*48a54d36SAndroid Build Coastguard Worker 			found = TRUE;
2155*48a54d36SAndroid Build Coastguard Worker 			break;
2156*48a54d36SAndroid Build Coastguard Worker 		}
2157*48a54d36SAndroid Build Coastguard Worker 	}
2158*48a54d36SAndroid Build Coastguard Worker 
2159*48a54d36SAndroid Build Coastguard Worker exit:
2160*48a54d36SAndroid Build Coastguard Worker 
2161*48a54d36SAndroid Build Coastguard Worker 	if ( pAdapterInfo )
2162*48a54d36SAndroid Build Coastguard Worker 	{
2163*48a54d36SAndroid Build Coastguard Worker 		free( pAdapterInfo );
2164*48a54d36SAndroid Build Coastguard Worker 	}
2165*48a54d36SAndroid Build Coastguard Worker 
2166*48a54d36SAndroid Build Coastguard Worker 	return err;
2167*48a54d36SAndroid Build Coastguard Worker }
2168*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformSendWakeupPacket(mDNS * const m,mDNSInterfaceID InterfaceID,char * EthAddr,char * IPAddr,int iteration)2169*48a54d36SAndroid Build Coastguard Worker mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
2170*48a54d36SAndroid Build Coastguard Worker 	{
2171*48a54d36SAndroid Build Coastguard Worker 	(void) m;
2172*48a54d36SAndroid Build Coastguard Worker 	(void) InterfaceID;
2173*48a54d36SAndroid Build Coastguard Worker 	(void) EthAddr;
2174*48a54d36SAndroid Build Coastguard Worker 	(void) IPAddr;
2175*48a54d36SAndroid Build Coastguard Worker 	(void) iteration;
2176*48a54d36SAndroid Build Coastguard Worker 	}
2177*48a54d36SAndroid Build Coastguard Worker 
mDNSPlatformValidRecordForInterface(AuthRecord * rr,const NetworkInterfaceInfo * intf)2178*48a54d36SAndroid Build Coastguard Worker mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
2179*48a54d36SAndroid Build Coastguard Worker 	{
2180*48a54d36SAndroid Build Coastguard Worker 	(void) rr;
2181*48a54d36SAndroid Build Coastguard Worker 	(void) intf;
2182*48a54d36SAndroid Build Coastguard Worker 
2183*48a54d36SAndroid Build Coastguard Worker 	return 1;
2184*48a54d36SAndroid Build Coastguard Worker 	}
2185*48a54d36SAndroid Build Coastguard Worker 
2186*48a54d36SAndroid Build Coastguard Worker 
2187*48a54d36SAndroid Build Coastguard Worker #if 0
2188*48a54d36SAndroid Build Coastguard Worker #pragma mark -
2189*48a54d36SAndroid Build Coastguard Worker #endif
2190*48a54d36SAndroid Build Coastguard Worker 
2191*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2192*48a54d36SAndroid Build Coastguard Worker //	debugf_
2193*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2194*48a54d36SAndroid Build Coastguard Worker #if( MDNS_DEBUGMSGS )
debugf_(const char * inFormat,...)2195*48a54d36SAndroid Build Coastguard Worker mDNSexport void	debugf_( const char *inFormat, ... )
2196*48a54d36SAndroid Build Coastguard Worker {
2197*48a54d36SAndroid Build Coastguard Worker 	char		buffer[ 512 ];
2198*48a54d36SAndroid Build Coastguard Worker     va_list		args;
2199*48a54d36SAndroid Build Coastguard Worker     mDNSu32		length;
2200*48a54d36SAndroid Build Coastguard Worker 
2201*48a54d36SAndroid Build Coastguard Worker 	va_start( args, inFormat );
2202*48a54d36SAndroid Build Coastguard Worker 	length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
2203*48a54d36SAndroid Build Coastguard Worker 	va_end( args );
2204*48a54d36SAndroid Build Coastguard Worker 
2205*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, "%s\n", buffer );
2206*48a54d36SAndroid Build Coastguard Worker }
2207*48a54d36SAndroid Build Coastguard Worker #endif
2208*48a54d36SAndroid Build Coastguard Worker 
2209*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2210*48a54d36SAndroid Build Coastguard Worker //	verbosedebugf_
2211*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2212*48a54d36SAndroid Build Coastguard Worker 
2213*48a54d36SAndroid Build Coastguard Worker #if( MDNS_DEBUGMSGS > 1 )
verbosedebugf_(const char * inFormat,...)2214*48a54d36SAndroid Build Coastguard Worker mDNSexport void	verbosedebugf_( const char *inFormat, ... )
2215*48a54d36SAndroid Build Coastguard Worker {
2216*48a54d36SAndroid Build Coastguard Worker 	char		buffer[ 512 ];
2217*48a54d36SAndroid Build Coastguard Worker     va_list		args;
2218*48a54d36SAndroid Build Coastguard Worker     mDNSu32		length;
2219*48a54d36SAndroid Build Coastguard Worker 
2220*48a54d36SAndroid Build Coastguard Worker 	va_start( args, inFormat );
2221*48a54d36SAndroid Build Coastguard Worker 	length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
2222*48a54d36SAndroid Build Coastguard Worker 	va_end( args );
2223*48a54d36SAndroid Build Coastguard Worker 
2224*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelVerbose, "%s\n", buffer );
2225*48a54d36SAndroid Build Coastguard Worker }
2226*48a54d36SAndroid Build Coastguard Worker #endif
2227*48a54d36SAndroid Build Coastguard Worker 
2228*48a54d36SAndroid Build Coastguard Worker 
2229*48a54d36SAndroid Build Coastguard Worker #if 0
2230*48a54d36SAndroid Build Coastguard Worker #pragma mark -
2231*48a54d36SAndroid Build Coastguard Worker #pragma mark == Platform Internals  ==
2232*48a54d36SAndroid Build Coastguard Worker #endif
2233*48a54d36SAndroid Build Coastguard Worker 
2234*48a54d36SAndroid Build Coastguard Worker 
2235*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2236*48a54d36SAndroid Build Coastguard Worker //	SetupNiceName
2237*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2238*48a54d36SAndroid Build Coastguard Worker 
SetupNiceName(mDNS * const inMDNS)2239*48a54d36SAndroid Build Coastguard Worker mStatus	SetupNiceName( mDNS * const inMDNS )
2240*48a54d36SAndroid Build Coastguard Worker {
2241*48a54d36SAndroid Build Coastguard Worker 	HKEY		descKey = NULL;
2242*48a54d36SAndroid Build Coastguard Worker 	char		utf8[ 256 ];
2243*48a54d36SAndroid Build Coastguard Worker 	LPCTSTR		s;
2244*48a54d36SAndroid Build Coastguard Worker 	LPWSTR		joinName;
2245*48a54d36SAndroid Build Coastguard Worker 	NETSETUP_JOIN_STATUS joinStatus;
2246*48a54d36SAndroid Build Coastguard Worker 	mStatus		err = 0;
2247*48a54d36SAndroid Build Coastguard Worker 	DWORD		namelen;
2248*48a54d36SAndroid Build Coastguard Worker 	BOOL		ok;
2249*48a54d36SAndroid Build Coastguard Worker 
2250*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2251*48a54d36SAndroid Build Coastguard Worker 
2252*48a54d36SAndroid Build Coastguard Worker 	// Set up the nice name.
2253*48a54d36SAndroid Build Coastguard Worker 	utf8[0] = '\0';
2254*48a54d36SAndroid Build Coastguard Worker 
2255*48a54d36SAndroid Build Coastguard Worker 	// First try and open the registry key that contains the computer description value
2256*48a54d36SAndroid Build Coastguard Worker 	s = TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters");
2257*48a54d36SAndroid Build Coastguard Worker 	err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, s, 0, KEY_READ, &descKey);
2258*48a54d36SAndroid Build Coastguard Worker 	check_translated_errno( err == 0, errno_compat(), kNameErr );
2259*48a54d36SAndroid Build Coastguard Worker 
2260*48a54d36SAndroid Build Coastguard Worker 	if ( !err )
2261*48a54d36SAndroid Build Coastguard Worker 	{
2262*48a54d36SAndroid Build Coastguard Worker 		TCHAR	desc[256];
2263*48a54d36SAndroid Build Coastguard Worker 		DWORD	descSize = sizeof( desc );
2264*48a54d36SAndroid Build Coastguard Worker 
2265*48a54d36SAndroid Build Coastguard Worker 		// look for the computer description
2266*48a54d36SAndroid Build Coastguard Worker 		err = RegQueryValueEx( descKey, TEXT("srvcomment"), 0, NULL, (LPBYTE) &desc, &descSize);
2267*48a54d36SAndroid Build Coastguard Worker 
2268*48a54d36SAndroid Build Coastguard Worker 		if ( !err )
2269*48a54d36SAndroid Build Coastguard Worker 		{
2270*48a54d36SAndroid Build Coastguard Worker 			err = TCHARtoUTF8( desc, utf8, sizeof( utf8 ) );
2271*48a54d36SAndroid Build Coastguard Worker 		}
2272*48a54d36SAndroid Build Coastguard Worker 
2273*48a54d36SAndroid Build Coastguard Worker 		if ( err )
2274*48a54d36SAndroid Build Coastguard Worker 		{
2275*48a54d36SAndroid Build Coastguard Worker 			utf8[ 0 ] = '\0';
2276*48a54d36SAndroid Build Coastguard Worker 		}
2277*48a54d36SAndroid Build Coastguard Worker 	}
2278*48a54d36SAndroid Build Coastguard Worker 
2279*48a54d36SAndroid Build Coastguard Worker 	// if we can't find it in the registry, then use the hostname of the machine
2280*48a54d36SAndroid Build Coastguard Worker 	if ( err || ( utf8[ 0 ] == '\0' ) )
2281*48a54d36SAndroid Build Coastguard Worker 	{
2282*48a54d36SAndroid Build Coastguard Worker 		TCHAR hostname[256];
2283*48a54d36SAndroid Build Coastguard Worker 
2284*48a54d36SAndroid Build Coastguard Worker 		namelen = sizeof( hostname ) / sizeof( TCHAR );
2285*48a54d36SAndroid Build Coastguard Worker 
2286*48a54d36SAndroid Build Coastguard Worker 		ok = GetComputerNameExW( ComputerNamePhysicalDnsHostname, hostname, &namelen );
2287*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
2288*48a54d36SAndroid Build Coastguard Worker 		check_noerr( err );
2289*48a54d36SAndroid Build Coastguard Worker 
2290*48a54d36SAndroid Build Coastguard Worker 		if( !err )
2291*48a54d36SAndroid Build Coastguard Worker 		{
2292*48a54d36SAndroid Build Coastguard Worker 			err = TCHARtoUTF8( hostname, utf8, sizeof( utf8 ) );
2293*48a54d36SAndroid Build Coastguard Worker 		}
2294*48a54d36SAndroid Build Coastguard Worker 
2295*48a54d36SAndroid Build Coastguard Worker 		if ( err )
2296*48a54d36SAndroid Build Coastguard Worker 		{
2297*48a54d36SAndroid Build Coastguard Worker 			utf8[ 0 ] = '\0';
2298*48a54d36SAndroid Build Coastguard Worker 		}
2299*48a54d36SAndroid Build Coastguard Worker 	}
2300*48a54d36SAndroid Build Coastguard Worker 
2301*48a54d36SAndroid Build Coastguard Worker 	// if we can't get the hostname
2302*48a54d36SAndroid Build Coastguard Worker 	if ( err || ( utf8[ 0 ] == '\0' ) )
2303*48a54d36SAndroid Build Coastguard Worker 	{
2304*48a54d36SAndroid Build Coastguard Worker 		// Invalidate name so fall back to a default name.
2305*48a54d36SAndroid Build Coastguard Worker 
2306*48a54d36SAndroid Build Coastguard Worker 		strcpy( utf8, kMDNSDefaultName );
2307*48a54d36SAndroid Build Coastguard Worker 	}
2308*48a54d36SAndroid Build Coastguard Worker 
2309*48a54d36SAndroid Build Coastguard Worker 	utf8[ sizeof( utf8 ) - 1 ]	= '\0';
2310*48a54d36SAndroid Build Coastguard Worker 	inMDNS->nicelabel.c[ 0 ]	= (mDNSu8) (strlen( utf8 ) < MAX_DOMAIN_LABEL ? strlen( utf8 ) : MAX_DOMAIN_LABEL);
2311*48a54d36SAndroid Build Coastguard Worker 	memcpy( &inMDNS->nicelabel.c[ 1 ], utf8, inMDNS->nicelabel.c[ 0 ] );
2312*48a54d36SAndroid Build Coastguard Worker 
2313*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "nice name \"%.*s\"\n", inMDNS->nicelabel.c[ 0 ], &inMDNS->nicelabel.c[ 1 ] );
2314*48a54d36SAndroid Build Coastguard Worker 
2315*48a54d36SAndroid Build Coastguard Worker 	if ( descKey )
2316*48a54d36SAndroid Build Coastguard Worker 	{
2317*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( descKey );
2318*48a54d36SAndroid Build Coastguard Worker 	}
2319*48a54d36SAndroid Build Coastguard Worker 
2320*48a54d36SAndroid Build Coastguard Worker 	ZeroMemory( inMDNS->p->nbname, sizeof( inMDNS->p->nbname ) );
2321*48a54d36SAndroid Build Coastguard Worker 	ZeroMemory( inMDNS->p->nbdomain, sizeof( inMDNS->p->nbdomain ) );
2322*48a54d36SAndroid Build Coastguard Worker 
2323*48a54d36SAndroid Build Coastguard Worker 	namelen = sizeof( inMDNS->p->nbname );
2324*48a54d36SAndroid Build Coastguard Worker 	ok = GetComputerNameExA( ComputerNamePhysicalNetBIOS, inMDNS->p->nbname, &namelen );
2325*48a54d36SAndroid Build Coastguard Worker 	check( ok );
2326*48a54d36SAndroid Build Coastguard Worker 	if ( ok ) dlog( kDebugLevelInfo, DEBUG_NAME "netbios name \"%s\"\n", inMDNS->p->nbname );
2327*48a54d36SAndroid Build Coastguard Worker 
2328*48a54d36SAndroid Build Coastguard Worker 	err = NetGetJoinInformation( NULL, &joinName, &joinStatus );
2329*48a54d36SAndroid Build Coastguard Worker 	check ( err == NERR_Success );
2330*48a54d36SAndroid Build Coastguard Worker 	if ( err == NERR_Success )
2331*48a54d36SAndroid Build Coastguard Worker 	{
2332*48a54d36SAndroid Build Coastguard Worker 		if ( ( joinStatus == NetSetupWorkgroupName ) || ( joinStatus == NetSetupDomainName ) )
2333*48a54d36SAndroid Build Coastguard Worker 		{
2334*48a54d36SAndroid Build Coastguard Worker 			err = TCHARtoUTF8( joinName, inMDNS->p->nbdomain, sizeof( inMDNS->p->nbdomain ) );
2335*48a54d36SAndroid Build Coastguard Worker 			check( !err );
2336*48a54d36SAndroid Build Coastguard Worker 			if ( !err ) dlog( kDebugLevelInfo, DEBUG_NAME "netbios domain/workgroup \"%s\"\n", inMDNS->p->nbdomain );
2337*48a54d36SAndroid Build Coastguard Worker 		}
2338*48a54d36SAndroid Build Coastguard Worker 
2339*48a54d36SAndroid Build Coastguard Worker 		NetApiBufferFree( joinName );
2340*48a54d36SAndroid Build Coastguard Worker 		joinName = NULL;
2341*48a54d36SAndroid Build Coastguard Worker 	}
2342*48a54d36SAndroid Build Coastguard Worker 
2343*48a54d36SAndroid Build Coastguard Worker 	err = 0;
2344*48a54d36SAndroid Build Coastguard Worker 
2345*48a54d36SAndroid Build Coastguard Worker 	return( err );
2346*48a54d36SAndroid Build Coastguard Worker }
2347*48a54d36SAndroid Build Coastguard Worker 
2348*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2349*48a54d36SAndroid Build Coastguard Worker //	SetupHostName
2350*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2351*48a54d36SAndroid Build Coastguard Worker 
SetupHostName(mDNS * const inMDNS)2352*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus	SetupHostName( mDNS * const inMDNS )
2353*48a54d36SAndroid Build Coastguard Worker {
2354*48a54d36SAndroid Build Coastguard Worker 	mStatus		err = 0;
2355*48a54d36SAndroid Build Coastguard Worker 	char		tempString[ 256 ];
2356*48a54d36SAndroid Build Coastguard Worker 	DWORD		tempStringLen;
2357*48a54d36SAndroid Build Coastguard Worker 	domainlabel tempLabel;
2358*48a54d36SAndroid Build Coastguard Worker 	BOOL		ok;
2359*48a54d36SAndroid Build Coastguard Worker 
2360*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2361*48a54d36SAndroid Build Coastguard Worker 
2362*48a54d36SAndroid Build Coastguard Worker 	// Set up the nice name.
2363*48a54d36SAndroid Build Coastguard Worker 	tempString[ 0 ] = '\0';
2364*48a54d36SAndroid Build Coastguard Worker 
2365*48a54d36SAndroid Build Coastguard Worker 	// use the hostname of the machine
2366*48a54d36SAndroid Build Coastguard Worker 	tempStringLen = sizeof( tempString );
2367*48a54d36SAndroid Build Coastguard Worker 	ok = GetComputerNameExA( ComputerNamePhysicalDnsHostname, tempString, &tempStringLen );
2368*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
2369*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
2370*48a54d36SAndroid Build Coastguard Worker 
2371*48a54d36SAndroid Build Coastguard Worker 	// if we can't get the hostname
2372*48a54d36SAndroid Build Coastguard Worker 	if( err || ( tempString[ 0 ] == '\0' ) )
2373*48a54d36SAndroid Build Coastguard Worker 	{
2374*48a54d36SAndroid Build Coastguard Worker 		// Invalidate name so fall back to a default name.
2375*48a54d36SAndroid Build Coastguard Worker 
2376*48a54d36SAndroid Build Coastguard Worker 		strcpy( tempString, kMDNSDefaultName );
2377*48a54d36SAndroid Build Coastguard Worker 	}
2378*48a54d36SAndroid Build Coastguard Worker 
2379*48a54d36SAndroid Build Coastguard Worker 	tempString[ sizeof( tempString ) - 1 ] = '\0';
2380*48a54d36SAndroid Build Coastguard Worker 	tempLabel.c[ 0 ] = (mDNSu8) (strlen( tempString ) < MAX_DOMAIN_LABEL ? strlen( tempString ) : MAX_DOMAIN_LABEL );
2381*48a54d36SAndroid Build Coastguard Worker 	memcpy( &tempLabel.c[ 1 ], tempString, tempLabel.c[ 0 ] );
2382*48a54d36SAndroid Build Coastguard Worker 
2383*48a54d36SAndroid Build Coastguard Worker 	// Set up the host name.
2384*48a54d36SAndroid Build Coastguard Worker 
2385*48a54d36SAndroid Build Coastguard Worker 	ConvertUTF8PstringToRFC1034HostLabel( tempLabel.c, &inMDNS->hostlabel );
2386*48a54d36SAndroid Build Coastguard Worker 	if( inMDNS->hostlabel.c[ 0 ] == 0 )
2387*48a54d36SAndroid Build Coastguard Worker 	{
2388*48a54d36SAndroid Build Coastguard Worker 		// Nice name has no characters that are representable as an RFC1034 name (e.g. Japanese) so use the default.
2389*48a54d36SAndroid Build Coastguard Worker 
2390*48a54d36SAndroid Build Coastguard Worker 		MakeDomainLabelFromLiteralString( &inMDNS->hostlabel, kMDNSDefaultName );
2391*48a54d36SAndroid Build Coastguard Worker 	}
2392*48a54d36SAndroid Build Coastguard Worker 
2393*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS->hostlabel.c[ 0 ] != 0 );
2394*48a54d36SAndroid Build Coastguard Worker 
2395*48a54d36SAndroid Build Coastguard Worker 	mDNS_SetFQDN( inMDNS );
2396*48a54d36SAndroid Build Coastguard Worker 
2397*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "host name \"%.*s\"\n", inMDNS->hostlabel.c[ 0 ], &inMDNS->hostlabel.c[ 1 ] );
2398*48a54d36SAndroid Build Coastguard Worker 
2399*48a54d36SAndroid Build Coastguard Worker 	return( err );
2400*48a54d36SAndroid Build Coastguard Worker }
2401*48a54d36SAndroid Build Coastguard Worker 
2402*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2403*48a54d36SAndroid Build Coastguard Worker //	SetupName
2404*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2405*48a54d36SAndroid Build Coastguard Worker 
SetupName(mDNS * const inMDNS)2406*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus	SetupName( mDNS * const inMDNS )
2407*48a54d36SAndroid Build Coastguard Worker {
2408*48a54d36SAndroid Build Coastguard Worker 	mStatus		err = 0;
2409*48a54d36SAndroid Build Coastguard Worker 
2410*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2411*48a54d36SAndroid Build Coastguard Worker 
2412*48a54d36SAndroid Build Coastguard Worker 	err = SetupNiceName( inMDNS );
2413*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
2414*48a54d36SAndroid Build Coastguard Worker 
2415*48a54d36SAndroid Build Coastguard Worker 	err = SetupHostName( inMDNS );
2416*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
2417*48a54d36SAndroid Build Coastguard Worker 
2418*48a54d36SAndroid Build Coastguard Worker 	return err;
2419*48a54d36SAndroid Build Coastguard Worker }
2420*48a54d36SAndroid Build Coastguard Worker 
2421*48a54d36SAndroid Build Coastguard Worker 
2422*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2423*48a54d36SAndroid Build Coastguard Worker //	SetupInterfaceList
2424*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2425*48a54d36SAndroid Build Coastguard Worker 
SetupInterfaceList(mDNS * const inMDNS)2426*48a54d36SAndroid Build Coastguard Worker mStatus	SetupInterfaceList( mDNS * const inMDNS )
2427*48a54d36SAndroid Build Coastguard Worker {
2428*48a54d36SAndroid Build Coastguard Worker 	mStatus						err;
2429*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData **		next;
2430*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData *			ifd;
2431*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			addrs;
2432*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			p;
2433*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			loopbackv4;
2434*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			loopbackv6;
2435*48a54d36SAndroid Build Coastguard Worker 	u_int						flagMask;
2436*48a54d36SAndroid Build Coastguard Worker 	u_int						flagTest;
2437*48a54d36SAndroid Build Coastguard Worker 	mDNSBool					foundv4;
2438*48a54d36SAndroid Build Coastguard Worker 	mDNSBool					foundv6;
2439*48a54d36SAndroid Build Coastguard Worker 	mDNSBool					foundUnicastSock4DestAddr;
2440*48a54d36SAndroid Build Coastguard Worker 	mDNSBool					foundUnicastSock6DestAddr;
2441*48a54d36SAndroid Build Coastguard Worker 
2442*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list\n" );
2443*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2444*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS->p );
2445*48a54d36SAndroid Build Coastguard Worker 
2446*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->registeredLoopback4	= mDNSfalse;
2447*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->nextDHCPLeaseExpires = 0x7FFFFFFF;
2448*48a54d36SAndroid Build Coastguard Worker 	addrs							= NULL;
2449*48a54d36SAndroid Build Coastguard Worker 	foundv4							= mDNSfalse;
2450*48a54d36SAndroid Build Coastguard Worker 	foundv6							= mDNSfalse;
2451*48a54d36SAndroid Build Coastguard Worker 	foundUnicastSock4DestAddr		= mDNSfalse;
2452*48a54d36SAndroid Build Coastguard Worker 	foundUnicastSock6DestAddr		= mDNSfalse;
2453*48a54d36SAndroid Build Coastguard Worker 
2454*48a54d36SAndroid Build Coastguard Worker 	// Tear down any existing interfaces that may be set up.
2455*48a54d36SAndroid Build Coastguard Worker 
2456*48a54d36SAndroid Build Coastguard Worker 	TearDownInterfaceList( inMDNS );
2457*48a54d36SAndroid Build Coastguard Worker 
2458*48a54d36SAndroid Build Coastguard Worker 	// Set up the name of this machine.
2459*48a54d36SAndroid Build Coastguard Worker 
2460*48a54d36SAndroid Build Coastguard Worker 	err = SetupName( inMDNS );
2461*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
2462*48a54d36SAndroid Build Coastguard Worker 
2463*48a54d36SAndroid Build Coastguard Worker 	// Set up IPv4 interface(s). We have to set up IPv4 first so any IPv6 interface with an IPv4-routable address
2464*48a54d36SAndroid Build Coastguard Worker 	// can refer to the IPv4 interface when it registers to allow DNS AAAA records over the IPv4 interface.
2465*48a54d36SAndroid Build Coastguard Worker 
2466*48a54d36SAndroid Build Coastguard Worker 	err = getifaddrs( &addrs );
2467*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2468*48a54d36SAndroid Build Coastguard Worker 
2469*48a54d36SAndroid Build Coastguard Worker 	loopbackv4	= NULL;
2470*48a54d36SAndroid Build Coastguard Worker 	loopbackv6	= NULL;
2471*48a54d36SAndroid Build Coastguard Worker 	next		= &inMDNS->p->interfaceList;
2472*48a54d36SAndroid Build Coastguard Worker 
2473*48a54d36SAndroid Build Coastguard Worker 	flagMask = IFF_UP | IFF_MULTICAST;
2474*48a54d36SAndroid Build Coastguard Worker 	flagTest = IFF_UP | IFF_MULTICAST;
2475*48a54d36SAndroid Build Coastguard Worker 
2476*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_ENABLE_IPV4 )
2477*48a54d36SAndroid Build Coastguard Worker 	for( p = addrs; p; p = p->ifa_next )
2478*48a54d36SAndroid Build Coastguard Worker 	{
2479*48a54d36SAndroid Build Coastguard Worker 		if( !p->ifa_addr || ( p->ifa_addr->sa_family != AF_INET ) || ( ( p->ifa_flags & flagMask ) != flagTest ) )
2480*48a54d36SAndroid Build Coastguard Worker 		{
2481*48a54d36SAndroid Build Coastguard Worker 			continue;
2482*48a54d36SAndroid Build Coastguard Worker 		}
2483*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_flags & IFF_LOOPBACK )
2484*48a54d36SAndroid Build Coastguard Worker 		{
2485*48a54d36SAndroid Build Coastguard Worker 			if( !loopbackv4 )
2486*48a54d36SAndroid Build Coastguard Worker 			{
2487*48a54d36SAndroid Build Coastguard Worker 				loopbackv4 = p;
2488*48a54d36SAndroid Build Coastguard Worker 			}
2489*48a54d36SAndroid Build Coastguard Worker 			continue;
2490*48a54d36SAndroid Build Coastguard Worker 		}
2491*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
2492*48a54d36SAndroid Build Coastguard Worker 			p->ifa_name ? p->ifa_name : "<null>", p->ifa_extra.index, p->ifa_addr );
2493*48a54d36SAndroid Build Coastguard Worker 
2494*48a54d36SAndroid Build Coastguard Worker 		err = SetupInterface( inMDNS, p, &ifd );
2495*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
2496*48a54d36SAndroid Build Coastguard Worker 
2497*48a54d36SAndroid Build Coastguard Worker 		// If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
2498*48a54d36SAndroid Build Coastguard Worker 		// register him, but we also want to note that we haven't found a v4 interface
2499*48a54d36SAndroid Build Coastguard Worker 		// so that we register loopback so same host operations work
2500*48a54d36SAndroid Build Coastguard Worker 
2501*48a54d36SAndroid Build Coastguard Worker 		if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
2502*48a54d36SAndroid Build Coastguard Worker 		{
2503*48a54d36SAndroid Build Coastguard Worker 			foundv4 = mDNStrue;
2504*48a54d36SAndroid Build Coastguard Worker 		}
2505*48a54d36SAndroid Build Coastguard Worker 
2506*48a54d36SAndroid Build Coastguard Worker 		if ( p->ifa_dhcpEnabled && ( p->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
2507*48a54d36SAndroid Build Coastguard Worker 		{
2508*48a54d36SAndroid Build Coastguard Worker 			inMDNS->p->nextDHCPLeaseExpires = p->ifa_dhcpLeaseExpires;
2509*48a54d36SAndroid Build Coastguard Worker 		}
2510*48a54d36SAndroid Build Coastguard Worker 
2511*48a54d36SAndroid Build Coastguard Worker 		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
2512*48a54d36SAndroid Build Coastguard Worker 		// of determing the destination address of a packet that is sent to us.
2513*48a54d36SAndroid Build Coastguard Worker 		// For multicast packets, that's easy to determine.  But for the unicast
2514*48a54d36SAndroid Build Coastguard Worker 		// sockets, we'll fake it by taking the address of the first interface
2515*48a54d36SAndroid Build Coastguard Worker 		// that is successfully setup.
2516*48a54d36SAndroid Build Coastguard Worker 
2517*48a54d36SAndroid Build Coastguard Worker 		if ( !foundUnicastSock4DestAddr )
2518*48a54d36SAndroid Build Coastguard Worker 		{
2519*48a54d36SAndroid Build Coastguard Worker 			inMDNS->p->unicastSock4.addr = ifd->interfaceInfo.ip;
2520*48a54d36SAndroid Build Coastguard Worker 			foundUnicastSock4DestAddr = TRUE;
2521*48a54d36SAndroid Build Coastguard Worker 		}
2522*48a54d36SAndroid Build Coastguard Worker 
2523*48a54d36SAndroid Build Coastguard Worker 		*next = ifd;
2524*48a54d36SAndroid Build Coastguard Worker 		next  = &ifd->next;
2525*48a54d36SAndroid Build Coastguard Worker 		++inMDNS->p->interfaceCount;
2526*48a54d36SAndroid Build Coastguard Worker 	}
2527*48a54d36SAndroid Build Coastguard Worker #endif
2528*48a54d36SAndroid Build Coastguard Worker 
2529*48a54d36SAndroid Build Coastguard Worker 	// Set up IPv6 interface(s) after IPv4 is set up (see IPv4 notes above for reasoning).
2530*48a54d36SAndroid Build Coastguard Worker 
2531*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_ENABLE_IPV6 )
2532*48a54d36SAndroid Build Coastguard Worker 	for( p = addrs; p; p = p->ifa_next )
2533*48a54d36SAndroid Build Coastguard Worker 	{
2534*48a54d36SAndroid Build Coastguard Worker 		if( !p->ifa_addr || ( p->ifa_addr->sa_family != AF_INET6 ) || ( ( p->ifa_flags & flagMask ) != flagTest ) )
2535*48a54d36SAndroid Build Coastguard Worker 		{
2536*48a54d36SAndroid Build Coastguard Worker 			continue;
2537*48a54d36SAndroid Build Coastguard Worker 		}
2538*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_flags & IFF_LOOPBACK )
2539*48a54d36SAndroid Build Coastguard Worker 		{
2540*48a54d36SAndroid Build Coastguard Worker 			if( !loopbackv6 )
2541*48a54d36SAndroid Build Coastguard Worker 			{
2542*48a54d36SAndroid Build Coastguard Worker 				loopbackv6 = p;
2543*48a54d36SAndroid Build Coastguard Worker 			}
2544*48a54d36SAndroid Build Coastguard Worker 			continue;
2545*48a54d36SAndroid Build Coastguard Worker 		}
2546*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
2547*48a54d36SAndroid Build Coastguard Worker 			p->ifa_name ? p->ifa_name : "<null>", p->ifa_extra.index, p->ifa_addr );
2548*48a54d36SAndroid Build Coastguard Worker 
2549*48a54d36SAndroid Build Coastguard Worker 		err = SetupInterface( inMDNS, p, &ifd );
2550*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
2551*48a54d36SAndroid Build Coastguard Worker 
2552*48a54d36SAndroid Build Coastguard Worker 		// If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
2553*48a54d36SAndroid Build Coastguard Worker 		// register him, but we also want to note that we haven't found a v4 interface
2554*48a54d36SAndroid Build Coastguard Worker 		// so that we register loopback so same host operations work
2555*48a54d36SAndroid Build Coastguard Worker 
2556*48a54d36SAndroid Build Coastguard Worker 		if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
2557*48a54d36SAndroid Build Coastguard Worker 		{
2558*48a54d36SAndroid Build Coastguard Worker 			foundv6 = mDNStrue;
2559*48a54d36SAndroid Build Coastguard Worker 		}
2560*48a54d36SAndroid Build Coastguard Worker 
2561*48a54d36SAndroid Build Coastguard Worker 		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
2562*48a54d36SAndroid Build Coastguard Worker 		// of determing the destination address of a packet that is sent to us.
2563*48a54d36SAndroid Build Coastguard Worker 		// For multicast packets, that's easy to determine.  But for the unicast
2564*48a54d36SAndroid Build Coastguard Worker 		// sockets, we'll fake it by taking the address of the first interface
2565*48a54d36SAndroid Build Coastguard Worker 		// that is successfully setup.
2566*48a54d36SAndroid Build Coastguard Worker 
2567*48a54d36SAndroid Build Coastguard Worker 		if ( !foundUnicastSock6DestAddr )
2568*48a54d36SAndroid Build Coastguard Worker 		{
2569*48a54d36SAndroid Build Coastguard Worker 			inMDNS->p->unicastSock6.addr = ifd->interfaceInfo.ip;
2570*48a54d36SAndroid Build Coastguard Worker 			foundUnicastSock6DestAddr = TRUE;
2571*48a54d36SAndroid Build Coastguard Worker 		}
2572*48a54d36SAndroid Build Coastguard Worker 
2573*48a54d36SAndroid Build Coastguard Worker 		*next = ifd;
2574*48a54d36SAndroid Build Coastguard Worker 		next  = &ifd->next;
2575*48a54d36SAndroid Build Coastguard Worker 		++inMDNS->p->interfaceCount;
2576*48a54d36SAndroid Build Coastguard Worker 	}
2577*48a54d36SAndroid Build Coastguard Worker #endif
2578*48a54d36SAndroid Build Coastguard Worker 
2579*48a54d36SAndroid Build Coastguard Worker 	// If there are no real interfaces, but there is a loopback interface, use that so same-machine operations work.
2580*48a54d36SAndroid Build Coastguard Worker 
2581*48a54d36SAndroid Build Coastguard Worker #if( !MDNS_WINDOWS_ENABLE_IPV4 && !MDNS_WINDOWS_ENABLE_IPV6 )
2582*48a54d36SAndroid Build Coastguard Worker 
2583*48a54d36SAndroid Build Coastguard Worker 	flagMask |= IFF_LOOPBACK;
2584*48a54d36SAndroid Build Coastguard Worker 	flagTest |= IFF_LOOPBACK;
2585*48a54d36SAndroid Build Coastguard Worker 
2586*48a54d36SAndroid Build Coastguard Worker 	for( p = addrs; p; p = p->ifa_next )
2587*48a54d36SAndroid Build Coastguard Worker 	{
2588*48a54d36SAndroid Build Coastguard Worker 		if( !p->ifa_addr || ( ( p->ifa_flags & flagMask ) != flagTest ) )
2589*48a54d36SAndroid Build Coastguard Worker 		{
2590*48a54d36SAndroid Build Coastguard Worker 			continue;
2591*48a54d36SAndroid Build Coastguard Worker 		}
2592*48a54d36SAndroid Build Coastguard Worker 		if( ( p->ifa_addr->sa_family != AF_INET ) && ( p->ifa_addr->sa_family != AF_INET6 ) )
2593*48a54d36SAndroid Build Coastguard Worker 		{
2594*48a54d36SAndroid Build Coastguard Worker 			continue;
2595*48a54d36SAndroid Build Coastguard Worker 		}
2596*48a54d36SAndroid Build Coastguard Worker 
2597*48a54d36SAndroid Build Coastguard Worker 		v4loopback = p;
2598*48a54d36SAndroid Build Coastguard Worker 		break;
2599*48a54d36SAndroid Build Coastguard Worker 	}
2600*48a54d36SAndroid Build Coastguard Worker 
2601*48a54d36SAndroid Build Coastguard Worker #endif
2602*48a54d36SAndroid Build Coastguard Worker 
2603*48a54d36SAndroid Build Coastguard Worker 	if ( !foundv4 && loopbackv4 )
2604*48a54d36SAndroid Build Coastguard Worker 	{
2605*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
2606*48a54d36SAndroid Build Coastguard Worker 			loopbackv4->ifa_name ? loopbackv4->ifa_name : "<null>", loopbackv4->ifa_extra.index, loopbackv4->ifa_addr );
2607*48a54d36SAndroid Build Coastguard Worker 
2608*48a54d36SAndroid Build Coastguard Worker 		err = SetupInterface( inMDNS, loopbackv4, &ifd );
2609*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
2610*48a54d36SAndroid Build Coastguard Worker 
2611*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->registeredLoopback4 = mDNStrue;
2612*48a54d36SAndroid Build Coastguard Worker 
2613*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_ENABLE_IPV4 )
2614*48a54d36SAndroid Build Coastguard Worker 
2615*48a54d36SAndroid Build Coastguard Worker 		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
2616*48a54d36SAndroid Build Coastguard Worker 		// of determing the destination address of a packet that is sent to us.
2617*48a54d36SAndroid Build Coastguard Worker 		// For multicast packets, that's easy to determine.  But for the unicast
2618*48a54d36SAndroid Build Coastguard Worker 		// sockets, we'll fake it by taking the address of the first interface
2619*48a54d36SAndroid Build Coastguard Worker 		// that is successfully setup.
2620*48a54d36SAndroid Build Coastguard Worker 
2621*48a54d36SAndroid Build Coastguard Worker 		if ( !foundUnicastSock4DestAddr )
2622*48a54d36SAndroid Build Coastguard Worker 		{
2623*48a54d36SAndroid Build Coastguard Worker 			inMDNS->p->unicastSock4.addr = ifd->sock.addr;
2624*48a54d36SAndroid Build Coastguard Worker 			foundUnicastSock4DestAddr = TRUE;
2625*48a54d36SAndroid Build Coastguard Worker 		}
2626*48a54d36SAndroid Build Coastguard Worker #endif
2627*48a54d36SAndroid Build Coastguard Worker 
2628*48a54d36SAndroid Build Coastguard Worker 		*next = ifd;
2629*48a54d36SAndroid Build Coastguard Worker 		next  = &ifd->next;
2630*48a54d36SAndroid Build Coastguard Worker 		++inMDNS->p->interfaceCount;
2631*48a54d36SAndroid Build Coastguard Worker 	}
2632*48a54d36SAndroid Build Coastguard Worker 
2633*48a54d36SAndroid Build Coastguard Worker 	if ( !foundv6 && loopbackv6 )
2634*48a54d36SAndroid Build Coastguard Worker 	{
2635*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
2636*48a54d36SAndroid Build Coastguard Worker 			loopbackv6->ifa_name ? loopbackv6->ifa_name : "<null>", loopbackv6->ifa_extra.index, loopbackv6->ifa_addr );
2637*48a54d36SAndroid Build Coastguard Worker 
2638*48a54d36SAndroid Build Coastguard Worker 		err = SetupInterface( inMDNS, loopbackv6, &ifd );
2639*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
2640*48a54d36SAndroid Build Coastguard Worker 
2641*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_ENABLE_IPV6 )
2642*48a54d36SAndroid Build Coastguard Worker 
2643*48a54d36SAndroid Build Coastguard Worker 		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
2644*48a54d36SAndroid Build Coastguard Worker 		// of determing the destination address of a packet that is sent to us.
2645*48a54d36SAndroid Build Coastguard Worker 		// For multicast packets, that's easy to determine.  But for the unicast
2646*48a54d36SAndroid Build Coastguard Worker 		// sockets, we'll fake it by taking the address of the first interface
2647*48a54d36SAndroid Build Coastguard Worker 		// that is successfully setup.
2648*48a54d36SAndroid Build Coastguard Worker 
2649*48a54d36SAndroid Build Coastguard Worker 		if ( !foundUnicastSock6DestAddr )
2650*48a54d36SAndroid Build Coastguard Worker 		{
2651*48a54d36SAndroid Build Coastguard Worker 			inMDNS->p->unicastSock6.addr = ifd->sock.addr;
2652*48a54d36SAndroid Build Coastguard Worker 			foundUnicastSock6DestAddr = TRUE;
2653*48a54d36SAndroid Build Coastguard Worker 		}
2654*48a54d36SAndroid Build Coastguard Worker #endif
2655*48a54d36SAndroid Build Coastguard Worker 
2656*48a54d36SAndroid Build Coastguard Worker 		*next = ifd;
2657*48a54d36SAndroid Build Coastguard Worker 		next  = &ifd->next;
2658*48a54d36SAndroid Build Coastguard Worker 		++inMDNS->p->interfaceCount;
2659*48a54d36SAndroid Build Coastguard Worker 	}
2660*48a54d36SAndroid Build Coastguard Worker 
2661*48a54d36SAndroid Build Coastguard Worker 	CheckFileShares( inMDNS );
2662*48a54d36SAndroid Build Coastguard Worker 
2663*48a54d36SAndroid Build Coastguard Worker exit:
2664*48a54d36SAndroid Build Coastguard Worker 	if( err )
2665*48a54d36SAndroid Build Coastguard Worker 	{
2666*48a54d36SAndroid Build Coastguard Worker 		TearDownInterfaceList( inMDNS );
2667*48a54d36SAndroid Build Coastguard Worker 	}
2668*48a54d36SAndroid Build Coastguard Worker 	if( addrs )
2669*48a54d36SAndroid Build Coastguard Worker 	{
2670*48a54d36SAndroid Build Coastguard Worker 		freeifaddrs( addrs );
2671*48a54d36SAndroid Build Coastguard Worker 	}
2672*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list done (err=%d %m)\n", err, err );
2673*48a54d36SAndroid Build Coastguard Worker 	return( err );
2674*48a54d36SAndroid Build Coastguard Worker }
2675*48a54d36SAndroid Build Coastguard Worker 
2676*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2677*48a54d36SAndroid Build Coastguard Worker //	TearDownInterfaceList
2678*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2679*48a54d36SAndroid Build Coastguard Worker 
TearDownInterfaceList(mDNS * const inMDNS)2680*48a54d36SAndroid Build Coastguard Worker mStatus	TearDownInterfaceList( mDNS * const inMDNS )
2681*48a54d36SAndroid Build Coastguard Worker {
2682*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData **		p;
2683*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData *		ifd;
2684*48a54d36SAndroid Build Coastguard Worker 
2685*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "tearing down interface list\n" );
2686*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2687*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS->p );
2688*48a54d36SAndroid Build Coastguard Worker 
2689*48a54d36SAndroid Build Coastguard Worker 	// Free any interfaces that were previously marked inactive and are no longer referenced by the mDNS cache.
2690*48a54d36SAndroid Build Coastguard Worker 	// Interfaces are marked inactive, but not deleted immediately if they were still referenced by the mDNS cache
2691*48a54d36SAndroid Build Coastguard Worker 	// so that remove events that occur after an interface goes away can still report the correct interface.
2692*48a54d36SAndroid Build Coastguard Worker 
2693*48a54d36SAndroid Build Coastguard Worker 	p = &inMDNS->p->inactiveInterfaceList;
2694*48a54d36SAndroid Build Coastguard Worker 	while( *p )
2695*48a54d36SAndroid Build Coastguard Worker 	{
2696*48a54d36SAndroid Build Coastguard Worker 		ifd = *p;
2697*48a54d36SAndroid Build Coastguard Worker 		if( NumCacheRecordsForInterfaceID( inMDNS, (mDNSInterfaceID) ifd ) > 0 )
2698*48a54d36SAndroid Build Coastguard Worker 		{
2699*48a54d36SAndroid Build Coastguard Worker 			p = &ifd->next;
2700*48a54d36SAndroid Build Coastguard Worker 			continue;
2701*48a54d36SAndroid Build Coastguard Worker 		}
2702*48a54d36SAndroid Build Coastguard Worker 
2703*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelInfo, DEBUG_NAME "freeing unreferenced, inactive interface %#p %#a\n", ifd, &ifd->interfaceInfo.ip );
2704*48a54d36SAndroid Build Coastguard Worker 		*p = ifd->next;
2705*48a54d36SAndroid Build Coastguard Worker 
2706*48a54d36SAndroid Build Coastguard Worker 		QueueUserAPC( ( PAPCFUNC ) FreeInterface, inMDNS->p->mainThread, ( ULONG_PTR ) ifd );
2707*48a54d36SAndroid Build Coastguard Worker 	}
2708*48a54d36SAndroid Build Coastguard Worker 
2709*48a54d36SAndroid Build Coastguard Worker 	// Tear down all the interfaces.
2710*48a54d36SAndroid Build Coastguard Worker 
2711*48a54d36SAndroid Build Coastguard Worker 	while( inMDNS->p->interfaceList )
2712*48a54d36SAndroid Build Coastguard Worker 	{
2713*48a54d36SAndroid Build Coastguard Worker 		ifd = inMDNS->p->interfaceList;
2714*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->interfaceList = ifd->next;
2715*48a54d36SAndroid Build Coastguard Worker 
2716*48a54d36SAndroid Build Coastguard Worker 		TearDownInterface( inMDNS, ifd );
2717*48a54d36SAndroid Build Coastguard Worker 	}
2718*48a54d36SAndroid Build Coastguard Worker 	inMDNS->p->interfaceCount = 0;
2719*48a54d36SAndroid Build Coastguard Worker 
2720*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "tearing down interface list done\n" );
2721*48a54d36SAndroid Build Coastguard Worker 	return( mStatus_NoError );
2722*48a54d36SAndroid Build Coastguard Worker }
2723*48a54d36SAndroid Build Coastguard Worker 
2724*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2725*48a54d36SAndroid Build Coastguard Worker //	SetupInterface
2726*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2727*48a54d36SAndroid Build Coastguard Worker 
SetupInterface(mDNS * const inMDNS,const struct ifaddrs * inIFA,mDNSInterfaceData ** outIFD)2728*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus	SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inIFA, mDNSInterfaceData **outIFD )
2729*48a54d36SAndroid Build Coastguard Worker {
2730*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData	*	ifd;
2731*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData	*	p;
2732*48a54d36SAndroid Build Coastguard Worker 	mStatus					err;
2733*48a54d36SAndroid Build Coastguard Worker 
2734*48a54d36SAndroid Build Coastguard Worker 	ifd = NULL;
2735*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface\n" );
2736*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2737*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS->p );
2738*48a54d36SAndroid Build Coastguard Worker 	check( inIFA );
2739*48a54d36SAndroid Build Coastguard Worker 	check( inIFA->ifa_addr );
2740*48a54d36SAndroid Build Coastguard Worker 	check( outIFD );
2741*48a54d36SAndroid Build Coastguard Worker 
2742*48a54d36SAndroid Build Coastguard Worker 	// Allocate memory for the interface and initialize it.
2743*48a54d36SAndroid Build Coastguard Worker 
2744*48a54d36SAndroid Build Coastguard Worker 	ifd = (mDNSInterfaceData *) calloc( 1, sizeof( *ifd ) );
2745*48a54d36SAndroid Build Coastguard Worker 	require_action( ifd, exit, err = mStatus_NoMemoryErr );
2746*48a54d36SAndroid Build Coastguard Worker 	ifd->sock.fd		= kInvalidSocketRef;
2747*48a54d36SAndroid Build Coastguard Worker 	ifd->sock.overlapped.pending = FALSE;
2748*48a54d36SAndroid Build Coastguard Worker 	ifd->sock.ifd		= ifd;
2749*48a54d36SAndroid Build Coastguard Worker 	ifd->sock.next		= NULL;
2750*48a54d36SAndroid Build Coastguard Worker 	ifd->sock.m			= inMDNS;
2751*48a54d36SAndroid Build Coastguard Worker 	ifd->index			= inIFA->ifa_extra.index;
2752*48a54d36SAndroid Build Coastguard Worker 	ifd->scopeID		= inIFA->ifa_extra.index;
2753*48a54d36SAndroid Build Coastguard Worker 	check( strlen( inIFA->ifa_name ) < sizeof( ifd->name ) );
2754*48a54d36SAndroid Build Coastguard Worker 	strncpy( ifd->name, inIFA->ifa_name, sizeof( ifd->name ) - 1 );
2755*48a54d36SAndroid Build Coastguard Worker 	ifd->name[ sizeof( ifd->name ) - 1 ] = '\0';
2756*48a54d36SAndroid Build Coastguard Worker 
2757*48a54d36SAndroid Build Coastguard Worker 	strncpy(ifd->interfaceInfo.ifname, inIFA->ifa_name, sizeof(ifd->interfaceInfo.ifname));
2758*48a54d36SAndroid Build Coastguard Worker 	ifd->interfaceInfo.ifname[sizeof(ifd->interfaceInfo.ifname)-1] = 0;
2759*48a54d36SAndroid Build Coastguard Worker 
2760*48a54d36SAndroid Build Coastguard Worker 	// We always send and receive using IPv4, but to reduce traffic, we send and receive using IPv6 only on interfaces
2761*48a54d36SAndroid Build Coastguard Worker 	// that have no routable IPv4 address. Having a routable IPv4 address assigned is a reasonable indicator of being
2762*48a54d36SAndroid Build Coastguard Worker 	// on a large configured network, which means there's a good chance that most or all the other devices on that
2763*48a54d36SAndroid Build Coastguard Worker 	// network should also have v4. By doing this we lose the ability to talk to true v6-only devices on that link,
2764*48a54d36SAndroid Build Coastguard Worker 	// but we cut the packet rate in half. At this time, reducing the packet rate is more important than v6-only
2765*48a54d36SAndroid Build Coastguard Worker 	// devices on a large configured network, so we are willing to make that sacrifice.
2766*48a54d36SAndroid Build Coastguard Worker 
2767*48a54d36SAndroid Build Coastguard Worker 	ifd->interfaceInfo.McastTxRx   = ( ( inIFA->ifa_flags & IFF_MULTICAST ) && !( inIFA->ifa_flags & IFF_POINTTOPOINT ) ) ? mDNStrue : mDNSfalse;
2768*48a54d36SAndroid Build Coastguard Worker 	ifd->interfaceInfo.InterfaceID = NULL;
2769*48a54d36SAndroid Build Coastguard Worker 
2770*48a54d36SAndroid Build Coastguard Worker 	for( p = inMDNS->p->interfaceList; p; p = p->next )
2771*48a54d36SAndroid Build Coastguard Worker 	{
2772*48a54d36SAndroid Build Coastguard Worker 		if ( strcmp( p->name, ifd->name ) == 0 )
2773*48a54d36SAndroid Build Coastguard Worker 		{
2774*48a54d36SAndroid Build Coastguard Worker 			if (!ifd->interfaceInfo.InterfaceID)
2775*48a54d36SAndroid Build Coastguard Worker 			{
2776*48a54d36SAndroid Build Coastguard Worker 				ifd->interfaceInfo.InterfaceID	= (mDNSInterfaceID) p;
2777*48a54d36SAndroid Build Coastguard Worker 			}
2778*48a54d36SAndroid Build Coastguard Worker 
2779*48a54d36SAndroid Build Coastguard Worker 			if ( ( inIFA->ifa_addr->sa_family != AF_INET ) &&
2780*48a54d36SAndroid Build Coastguard Worker 			     ( p->interfaceInfo.ip.type == mDNSAddrType_IPv4 ) &&
2781*48a54d36SAndroid Build Coastguard Worker 			     ( p->interfaceInfo.ip.ip.v4.b[ 0 ] != 169 || p->interfaceInfo.ip.ip.v4.b[ 1 ] != 254 ) )
2782*48a54d36SAndroid Build Coastguard Worker 			{
2783*48a54d36SAndroid Build Coastguard Worker 				ifd->interfaceInfo.McastTxRx = mDNSfalse;
2784*48a54d36SAndroid Build Coastguard Worker 			}
2785*48a54d36SAndroid Build Coastguard Worker 
2786*48a54d36SAndroid Build Coastguard Worker 			break;
2787*48a54d36SAndroid Build Coastguard Worker 		}
2788*48a54d36SAndroid Build Coastguard Worker 	}
2789*48a54d36SAndroid Build Coastguard Worker 
2790*48a54d36SAndroid Build Coastguard Worker 	if ( !ifd->interfaceInfo.InterfaceID )
2791*48a54d36SAndroid Build Coastguard Worker 	{
2792*48a54d36SAndroid Build Coastguard Worker 		ifd->interfaceInfo.InterfaceID = (mDNSInterfaceID) ifd;
2793*48a54d36SAndroid Build Coastguard Worker 	}
2794*48a54d36SAndroid Build Coastguard Worker 
2795*48a54d36SAndroid Build Coastguard Worker 	// Set up a socket for this interface (if needed).
2796*48a54d36SAndroid Build Coastguard Worker 
2797*48a54d36SAndroid Build Coastguard Worker 	if( ifd->interfaceInfo.McastTxRx )
2798*48a54d36SAndroid Build Coastguard Worker 	{
2799*48a54d36SAndroid Build Coastguard Worker 		DWORD size;
2800*48a54d36SAndroid Build Coastguard Worker 
2801*48a54d36SAndroid Build Coastguard Worker 		err = SetupSocket( inMDNS, inIFA->ifa_addr, MulticastDNSPort, &ifd->sock.fd );
2802*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
2803*48a54d36SAndroid Build Coastguard Worker 		ifd->sock.addr = ( inIFA->ifa_addr->sa_family == AF_INET6 ) ? AllDNSLinkGroup_v6 : AllDNSLinkGroup_v4;
2804*48a54d36SAndroid Build Coastguard Worker 		ifd->sock.port = MulticastDNSPort;
2805*48a54d36SAndroid Build Coastguard Worker 
2806*48a54d36SAndroid Build Coastguard Worker 		// Get a ptr to the WSARecvMsg function, if supported. Otherwise, we'll fallback to recvfrom.
2807*48a54d36SAndroid Build Coastguard Worker 
2808*48a54d36SAndroid Build Coastguard Worker 		err = WSAIoctl( ifd->sock.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &ifd->sock.recvMsgPtr, sizeof( ifd->sock.recvMsgPtr ), &size, NULL, NULL );
2809*48a54d36SAndroid Build Coastguard Worker 
2810*48a54d36SAndroid Build Coastguard Worker 		if ( err )
2811*48a54d36SAndroid Build Coastguard Worker 		{
2812*48a54d36SAndroid Build Coastguard Worker 			ifd->sock.recvMsgPtr = NULL;
2813*48a54d36SAndroid Build Coastguard Worker 		}
2814*48a54d36SAndroid Build Coastguard Worker 	}
2815*48a54d36SAndroid Build Coastguard Worker 
2816*48a54d36SAndroid Build Coastguard Worker 	if ( inIFA->ifa_dhcpEnabled && ( inIFA->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
2817*48a54d36SAndroid Build Coastguard Worker 	{
2818*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->nextDHCPLeaseExpires = inIFA->ifa_dhcpLeaseExpires;
2819*48a54d36SAndroid Build Coastguard Worker 	}
2820*48a54d36SAndroid Build Coastguard Worker 
2821*48a54d36SAndroid Build Coastguard Worker 	ifd->interfaceInfo.NetWake = inIFA->ifa_womp;
2822*48a54d36SAndroid Build Coastguard Worker 
2823*48a54d36SAndroid Build Coastguard Worker 	// Register this interface with mDNS.
2824*48a54d36SAndroid Build Coastguard Worker 
2825*48a54d36SAndroid Build Coastguard Worker 	err = SockAddrToMDNSAddr( inIFA->ifa_addr, &ifd->interfaceInfo.ip, NULL );
2826*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2827*48a54d36SAndroid Build Coastguard Worker 
2828*48a54d36SAndroid Build Coastguard Worker 	err = SockAddrToMDNSAddr( inIFA->ifa_netmask, &ifd->interfaceInfo.mask, NULL );
2829*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2830*48a54d36SAndroid Build Coastguard Worker 
2831*48a54d36SAndroid Build Coastguard Worker 	memcpy( ifd->interfaceInfo.MAC.b, inIFA->ifa_physaddr, sizeof( ifd->interfaceInfo.MAC.b ) );
2832*48a54d36SAndroid Build Coastguard Worker 
2833*48a54d36SAndroid Build Coastguard Worker 	ifd->interfaceInfo.Advertise = ( mDNSu8 ) inMDNS->AdvertiseLocalAddresses;
2834*48a54d36SAndroid Build Coastguard Worker 
2835*48a54d36SAndroid Build Coastguard Worker 	if ( ifd->sock.fd != kInvalidSocketRef )
2836*48a54d36SAndroid Build Coastguard Worker 	{
2837*48a54d36SAndroid Build Coastguard Worker 		err = UDPBeginRecv( &ifd->sock );
2838*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
2839*48a54d36SAndroid Build Coastguard Worker 	}
2840*48a54d36SAndroid Build Coastguard Worker 
2841*48a54d36SAndroid Build Coastguard Worker 	err = mDNS_RegisterInterface( inMDNS, &ifd->interfaceInfo, mDNSfalse );
2842*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2843*48a54d36SAndroid Build Coastguard Worker 	ifd->hostRegistered = mDNStrue;
2844*48a54d36SAndroid Build Coastguard Worker 
2845*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "Registered interface %##a with mDNS\n", inIFA->ifa_addr );
2846*48a54d36SAndroid Build Coastguard Worker 
2847*48a54d36SAndroid Build Coastguard Worker 	// Success!
2848*48a54d36SAndroid Build Coastguard Worker 
2849*48a54d36SAndroid Build Coastguard Worker 	*outIFD = ifd;
2850*48a54d36SAndroid Build Coastguard Worker 	ifd = NULL;
2851*48a54d36SAndroid Build Coastguard Worker 
2852*48a54d36SAndroid Build Coastguard Worker exit:
2853*48a54d36SAndroid Build Coastguard Worker 
2854*48a54d36SAndroid Build Coastguard Worker 	if( ifd )
2855*48a54d36SAndroid Build Coastguard Worker 	{
2856*48a54d36SAndroid Build Coastguard Worker 		TearDownInterface( inMDNS, ifd );
2857*48a54d36SAndroid Build Coastguard Worker 	}
2858*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface done (err=%d %m)\n", err, err );
2859*48a54d36SAndroid Build Coastguard Worker 	return( err );
2860*48a54d36SAndroid Build Coastguard Worker }
2861*48a54d36SAndroid Build Coastguard Worker 
2862*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2863*48a54d36SAndroid Build Coastguard Worker //	TearDownInterface
2864*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2865*48a54d36SAndroid Build Coastguard Worker 
TearDownInterface(mDNS * const inMDNS,mDNSInterfaceData * inIFD)2866*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus	TearDownInterface( mDNS * const inMDNS, mDNSInterfaceData *inIFD )
2867*48a54d36SAndroid Build Coastguard Worker {
2868*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2869*48a54d36SAndroid Build Coastguard Worker 	check( inIFD );
2870*48a54d36SAndroid Build Coastguard Worker 
2871*48a54d36SAndroid Build Coastguard Worker 	// Deregister this interface with mDNS.
2872*48a54d36SAndroid Build Coastguard Worker 
2873*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "Deregistering interface %#a with mDNS\n", &inIFD->interfaceInfo.ip );
2874*48a54d36SAndroid Build Coastguard Worker 
2875*48a54d36SAndroid Build Coastguard Worker 	if( inIFD->hostRegistered )
2876*48a54d36SAndroid Build Coastguard Worker 	{
2877*48a54d36SAndroid Build Coastguard Worker 		inIFD->hostRegistered = mDNSfalse;
2878*48a54d36SAndroid Build Coastguard Worker 		mDNS_DeregisterInterface( inMDNS, &inIFD->interfaceInfo, mDNSfalse );
2879*48a54d36SAndroid Build Coastguard Worker 	}
2880*48a54d36SAndroid Build Coastguard Worker 
2881*48a54d36SAndroid Build Coastguard Worker 	// Tear down the multicast socket.
2882*48a54d36SAndroid Build Coastguard Worker 
2883*48a54d36SAndroid Build Coastguard Worker 	UDPCloseSocket( &inIFD->sock );
2884*48a54d36SAndroid Build Coastguard Worker 
2885*48a54d36SAndroid Build Coastguard Worker 	// If the interface is still referenced by items in the mDNS cache then put it on the inactive list. This keeps
2886*48a54d36SAndroid Build Coastguard Worker 	// the InterfaceID valid so remove events report the correct interface. If it is no longer referenced, free it.
2887*48a54d36SAndroid Build Coastguard Worker 
2888*48a54d36SAndroid Build Coastguard Worker 	if( NumCacheRecordsForInterfaceID( inMDNS, (mDNSInterfaceID) inIFD ) > 0 )
2889*48a54d36SAndroid Build Coastguard Worker 	{
2890*48a54d36SAndroid Build Coastguard Worker 		inIFD->next = inMDNS->p->inactiveInterfaceList;
2891*48a54d36SAndroid Build Coastguard Worker 		inMDNS->p->inactiveInterfaceList = inIFD;
2892*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelInfo, DEBUG_NAME "deferring free of interface %#p %#a\n", inIFD, &inIFD->interfaceInfo.ip );
2893*48a54d36SAndroid Build Coastguard Worker 	}
2894*48a54d36SAndroid Build Coastguard Worker 	else
2895*48a54d36SAndroid Build Coastguard Worker 	{
2896*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelInfo, DEBUG_NAME "freeing interface %#p %#a immediately\n", inIFD, &inIFD->interfaceInfo.ip );
2897*48a54d36SAndroid Build Coastguard Worker 		QueueUserAPC( ( PAPCFUNC ) FreeInterface, inMDNS->p->mainThread, ( ULONG_PTR ) inIFD );
2898*48a54d36SAndroid Build Coastguard Worker 	}
2899*48a54d36SAndroid Build Coastguard Worker 
2900*48a54d36SAndroid Build Coastguard Worker 	return( mStatus_NoError );
2901*48a54d36SAndroid Build Coastguard Worker }
2902*48a54d36SAndroid Build Coastguard Worker 
FreeInterface(mDNSInterfaceData * inIFD)2903*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK FreeInterface( mDNSInterfaceData *inIFD )
2904*48a54d36SAndroid Build Coastguard Worker {
2905*48a54d36SAndroid Build Coastguard Worker 	free( inIFD );
2906*48a54d36SAndroid Build Coastguard Worker }
2907*48a54d36SAndroid Build Coastguard Worker 
2908*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2909*48a54d36SAndroid Build Coastguard Worker //	SetupSocket
2910*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2911*48a54d36SAndroid Build Coastguard Worker 
SetupSocket(mDNS * const inMDNS,const struct sockaddr * inAddr,mDNSIPPort port,SocketRef * outSocketRef)2912*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus	SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAddr, mDNSIPPort port, SocketRef *outSocketRef  )
2913*48a54d36SAndroid Build Coastguard Worker {
2914*48a54d36SAndroid Build Coastguard Worker 	mStatus			err;
2915*48a54d36SAndroid Build Coastguard Worker 	SocketRef		sock;
2916*48a54d36SAndroid Build Coastguard Worker 	int				option;
2917*48a54d36SAndroid Build Coastguard Worker 	DWORD			bytesReturned = 0;
2918*48a54d36SAndroid Build Coastguard Worker 	BOOL			behavior = FALSE;
2919*48a54d36SAndroid Build Coastguard Worker 
2920*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inMDNS );
2921*48a54d36SAndroid Build Coastguard Worker 
2922*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "setting up socket %##a\n", inAddr );
2923*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
2924*48a54d36SAndroid Build Coastguard Worker 	check( outSocketRef );
2925*48a54d36SAndroid Build Coastguard Worker 
2926*48a54d36SAndroid Build Coastguard Worker 	// Set up an IPv4 or IPv6 UDP socket.
2927*48a54d36SAndroid Build Coastguard Worker 
2928*48a54d36SAndroid Build Coastguard Worker 	sock = socket( inAddr->sa_family, SOCK_DGRAM, IPPROTO_UDP );
2929*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
2930*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
2931*48a54d36SAndroid Build Coastguard Worker 
2932*48a54d36SAndroid Build Coastguard Worker 	// Turn on reuse address option so multiple servers can listen for Multicast DNS packets,
2933*48a54d36SAndroid Build Coastguard Worker 	// if we're creating a multicast socket
2934*48a54d36SAndroid Build Coastguard Worker 
2935*48a54d36SAndroid Build Coastguard Worker 	if ( port.NotAnInteger )
2936*48a54d36SAndroid Build Coastguard Worker 	{
2937*48a54d36SAndroid Build Coastguard Worker 		option = 1;
2938*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *) &option, sizeof( option ) );
2939*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
2940*48a54d36SAndroid Build Coastguard Worker 	}
2941*48a54d36SAndroid Build Coastguard Worker 
2942*48a54d36SAndroid Build Coastguard Worker 	// <rdar://problem/7894393> Bonjour for Windows broken on Windows XP
2943*48a54d36SAndroid Build Coastguard Worker 	//
2944*48a54d36SAndroid Build Coastguard Worker 	// Not sure why, but the default behavior for sockets is to behave incorrectly
2945*48a54d36SAndroid Build Coastguard Worker 	// when using them in Overlapped I/O mode on XP. According to MSDN:
2946*48a54d36SAndroid Build Coastguard Worker 	//
2947*48a54d36SAndroid Build Coastguard Worker 	// SIO_UDP_CONNRESET (opcode setting: I, T==3)
2948*48a54d36SAndroid Build Coastguard Worker 	//     Windows XP:  Controls whether UDP PORT_UNREACHABLE messages are reported. Set to TRUE to enable reporting.
2949*48a54d36SAndroid Build Coastguard Worker 	//     Set to FALSE to disable reporting.
2950*48a54d36SAndroid Build Coastguard Worker 	//
2951*48a54d36SAndroid Build Coastguard Worker 	// Packet traces from misbehaving Bonjour installations showed that ICMP port unreachable
2952*48a54d36SAndroid Build Coastguard Worker 	// messages were being sent to us after we sent out packets to a multicast address. This is clearly
2953*48a54d36SAndroid Build Coastguard Worker 	// incorrect behavior, but should be harmless. However, after receiving a port unreachable error, WinSock
2954*48a54d36SAndroid Build Coastguard Worker 	// will no longer receive any packets from that socket, which is not harmless. This behavior is only
2955*48a54d36SAndroid Build Coastguard Worker 	// seen on XP.
2956*48a54d36SAndroid Build Coastguard Worker 	//
2957*48a54d36SAndroid Build Coastguard Worker 	// So we turn off port unreachable reporting to make sure our sockets that are reading
2958*48a54d36SAndroid Build Coastguard Worker 	// multicast packets function correctly under all circumstances.
2959*48a54d36SAndroid Build Coastguard Worker 
2960*48a54d36SAndroid Build Coastguard Worker 	err = WSAIoctl( sock, SIO_UDP_CONNRESET, &behavior, sizeof(behavior), NULL, 0, &bytesReturned, NULL, NULL );
2961*48a54d36SAndroid Build Coastguard Worker 	check_translated_errno( err == 0, errno_compat(), kOptionErr );
2962*48a54d36SAndroid Build Coastguard Worker 
2963*48a54d36SAndroid Build Coastguard Worker 	if( inAddr->sa_family == AF_INET )
2964*48a54d36SAndroid Build Coastguard Worker 	{
2965*48a54d36SAndroid Build Coastguard Worker 		mDNSv4Addr				ipv4;
2966*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in		sa4;
2967*48a54d36SAndroid Build Coastguard Worker 		struct ip_mreq			mreqv4;
2968*48a54d36SAndroid Build Coastguard Worker 
2969*48a54d36SAndroid Build Coastguard Worker 		// Bind the socket to the desired port
2970*48a54d36SAndroid Build Coastguard Worker 
2971*48a54d36SAndroid Build Coastguard Worker 		ipv4.NotAnInteger 	= ( (const struct sockaddr_in *) inAddr )->sin_addr.s_addr;
2972*48a54d36SAndroid Build Coastguard Worker 		mDNSPlatformMemZero( &sa4, sizeof( sa4 ) );
2973*48a54d36SAndroid Build Coastguard Worker 		sa4.sin_family 		= AF_INET;
2974*48a54d36SAndroid Build Coastguard Worker 		sa4.sin_port 		= port.NotAnInteger;
2975*48a54d36SAndroid Build Coastguard Worker 		sa4.sin_addr.s_addr	= ipv4.NotAnInteger;
2976*48a54d36SAndroid Build Coastguard Worker 
2977*48a54d36SAndroid Build Coastguard Worker 		err = bind( sock, (struct sockaddr *) &sa4, sizeof( sa4 ) );
2978*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kUnknownErr );
2979*48a54d36SAndroid Build Coastguard Worker 
2980*48a54d36SAndroid Build Coastguard Worker 		// Turn on option to receive destination addresses and receiving interface.
2981*48a54d36SAndroid Build Coastguard Worker 
2982*48a54d36SAndroid Build Coastguard Worker 		option = 1;
2983*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, IPPROTO_IP, IP_PKTINFO, (char *) &option, sizeof( option ) );
2984*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
2985*48a54d36SAndroid Build Coastguard Worker 
2986*48a54d36SAndroid Build Coastguard Worker 		if (port.NotAnInteger)
2987*48a54d36SAndroid Build Coastguard Worker 		{
2988*48a54d36SAndroid Build Coastguard Worker 			// Join the all-DNS multicast group so we receive Multicast DNS packets
2989*48a54d36SAndroid Build Coastguard Worker 
2990*48a54d36SAndroid Build Coastguard Worker 			mreqv4.imr_multiaddr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
2991*48a54d36SAndroid Build Coastguard Worker 			mreqv4.imr_interface.s_addr = ipv4.NotAnInteger;
2992*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreqv4, sizeof( mreqv4 ) );
2993*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
2994*48a54d36SAndroid Build Coastguard Worker 
2995*48a54d36SAndroid Build Coastguard Worker 			// Specify the interface to send multicast packets on this socket.
2996*48a54d36SAndroid Build Coastguard Worker 
2997*48a54d36SAndroid Build Coastguard Worker 			sa4.sin_addr.s_addr = ipv4.NotAnInteger;
2998*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_IF, (char *) &sa4.sin_addr, sizeof( sa4.sin_addr ) );
2999*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
3000*48a54d36SAndroid Build Coastguard Worker 
3001*48a54d36SAndroid Build Coastguard Worker 			// Enable multicast loopback so we receive multicast packets we send (for same-machine operations).
3002*48a54d36SAndroid Build Coastguard Worker 
3003*48a54d36SAndroid Build Coastguard Worker 			option = 1;
3004*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &option, sizeof( option ) );
3005*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
3006*48a54d36SAndroid Build Coastguard Worker 		}
3007*48a54d36SAndroid Build Coastguard Worker 
3008*48a54d36SAndroid Build Coastguard Worker 		// Send unicast packets with TTL 255 (helps against spoofing).
3009*48a54d36SAndroid Build Coastguard Worker 
3010*48a54d36SAndroid Build Coastguard Worker 		option = 255;
3011*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, IPPROTO_IP, IP_TTL, (char *) &option, sizeof( option ) );
3012*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
3013*48a54d36SAndroid Build Coastguard Worker 
3014*48a54d36SAndroid Build Coastguard Worker 		// Send multicast packets with TTL 255 (helps against spoofing).
3015*48a54d36SAndroid Build Coastguard Worker 
3016*48a54d36SAndroid Build Coastguard Worker 		option = 255;
3017*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &option, sizeof( option ) );
3018*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
3019*48a54d36SAndroid Build Coastguard Worker 
3020*48a54d36SAndroid Build Coastguard Worker 	}
3021*48a54d36SAndroid Build Coastguard Worker 	else if( inAddr->sa_family == AF_INET6 )
3022*48a54d36SAndroid Build Coastguard Worker 	{
3023*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in6 *		sa6p;
3024*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in6			sa6;
3025*48a54d36SAndroid Build Coastguard Worker 		struct ipv6_mreq			mreqv6;
3026*48a54d36SAndroid Build Coastguard Worker 
3027*48a54d36SAndroid Build Coastguard Worker 		sa6p = (struct sockaddr_in6 *) inAddr;
3028*48a54d36SAndroid Build Coastguard Worker 
3029*48a54d36SAndroid Build Coastguard Worker 		// Bind the socket to the desired port
3030*48a54d36SAndroid Build Coastguard Worker 
3031*48a54d36SAndroid Build Coastguard Worker 		mDNSPlatformMemZero( &sa6, sizeof( sa6 ) );
3032*48a54d36SAndroid Build Coastguard Worker 		sa6.sin6_family		= AF_INET6;
3033*48a54d36SAndroid Build Coastguard Worker 		sa6.sin6_port		= port.NotAnInteger;
3034*48a54d36SAndroid Build Coastguard Worker 		sa6.sin6_flowinfo	= 0;
3035*48a54d36SAndroid Build Coastguard Worker 		sa6.sin6_addr		= sa6p->sin6_addr;
3036*48a54d36SAndroid Build Coastguard Worker 		sa6.sin6_scope_id	= sa6p->sin6_scope_id;
3037*48a54d36SAndroid Build Coastguard Worker 
3038*48a54d36SAndroid Build Coastguard Worker 		err = bind( sock, (struct sockaddr *) &sa6, sizeof( sa6 ) );
3039*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kUnknownErr );
3040*48a54d36SAndroid Build Coastguard Worker 
3041*48a54d36SAndroid Build Coastguard Worker 		// Turn on option to receive destination addresses and receiving interface.
3042*48a54d36SAndroid Build Coastguard Worker 
3043*48a54d36SAndroid Build Coastguard Worker 		option = 1;
3044*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *) &option, sizeof( option ) );
3045*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
3046*48a54d36SAndroid Build Coastguard Worker 
3047*48a54d36SAndroid Build Coastguard Worker 		// We only want to receive IPv6 packets (not IPv4-mapped IPv6 addresses) because we have a separate socket
3048*48a54d36SAndroid Build Coastguard Worker 		// for IPv4, but the IPv6 stack in Windows currently doesn't support IPv4-mapped IPv6 addresses and doesn't
3049*48a54d36SAndroid Build Coastguard Worker 		// support the IPV6_V6ONLY socket option so the following code would typically not be executed (or needed).
3050*48a54d36SAndroid Build Coastguard Worker 
3051*48a54d36SAndroid Build Coastguard Worker 		#if( defined( IPV6_V6ONLY ) )
3052*48a54d36SAndroid Build Coastguard Worker 			option = 1;
3053*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &option, sizeof( option ) );
3054*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
3055*48a54d36SAndroid Build Coastguard Worker 		#endif
3056*48a54d36SAndroid Build Coastguard Worker 
3057*48a54d36SAndroid Build Coastguard Worker 		if ( port.NotAnInteger )
3058*48a54d36SAndroid Build Coastguard Worker 		{
3059*48a54d36SAndroid Build Coastguard Worker 			// Join the all-DNS multicast group so we receive Multicast DNS packets.
3060*48a54d36SAndroid Build Coastguard Worker 
3061*48a54d36SAndroid Build Coastguard Worker 			mreqv6.ipv6mr_multiaddr = *( (struct in6_addr *) &AllDNSLinkGroup_v6.ip.v6 );
3062*48a54d36SAndroid Build Coastguard Worker 			mreqv6.ipv6mr_interface = sa6p->sin6_scope_id;
3063*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &mreqv6, sizeof( mreqv6 ) );
3064*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
3065*48a54d36SAndroid Build Coastguard Worker 
3066*48a54d36SAndroid Build Coastguard Worker 			// Specify the interface to send multicast packets on this socket.
3067*48a54d36SAndroid Build Coastguard Worker 
3068*48a54d36SAndroid Build Coastguard Worker 			option = (int) sa6p->sin6_scope_id;
3069*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &option, sizeof( option ) );
3070*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
3071*48a54d36SAndroid Build Coastguard Worker 
3072*48a54d36SAndroid Build Coastguard Worker 			// Enable multicast loopback so we receive multicast packets we send (for same-machine operations).
3073*48a54d36SAndroid Build Coastguard Worker 
3074*48a54d36SAndroid Build Coastguard Worker 			option = 1;
3075*48a54d36SAndroid Build Coastguard Worker 			err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &option, sizeof( option ) );
3076*48a54d36SAndroid Build Coastguard Worker 			check_translated_errno( err == 0, errno_compat(), kOptionErr );
3077*48a54d36SAndroid Build Coastguard Worker 		}
3078*48a54d36SAndroid Build Coastguard Worker 
3079*48a54d36SAndroid Build Coastguard Worker 		// Send unicast packets with TTL 255 (helps against spoofing).
3080*48a54d36SAndroid Build Coastguard Worker 
3081*48a54d36SAndroid Build Coastguard Worker 		option = 255;
3082*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (char *) &option, sizeof( option ) );
3083*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
3084*48a54d36SAndroid Build Coastguard Worker 
3085*48a54d36SAndroid Build Coastguard Worker 		// Send multicast packets with TTL 255 (helps against spoofing).
3086*48a54d36SAndroid Build Coastguard Worker 
3087*48a54d36SAndroid Build Coastguard Worker 		option = 255;
3088*48a54d36SAndroid Build Coastguard Worker 		err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &option, sizeof( option ) );
3089*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( err == 0, errno_compat(), kOptionErr );
3090*48a54d36SAndroid Build Coastguard Worker 	}
3091*48a54d36SAndroid Build Coastguard Worker 	else
3092*48a54d36SAndroid Build Coastguard Worker 	{
3093*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelError, DEBUG_NAME "%s: unsupport socket family (%d)\n", __ROUTINE__, inAddr->sa_family );
3094*48a54d36SAndroid Build Coastguard Worker 		err = kUnsupportedErr;
3095*48a54d36SAndroid Build Coastguard Worker 		goto exit;
3096*48a54d36SAndroid Build Coastguard Worker 	}
3097*48a54d36SAndroid Build Coastguard Worker 
3098*48a54d36SAndroid Build Coastguard Worker 	// Success!
3099*48a54d36SAndroid Build Coastguard Worker 
3100*48a54d36SAndroid Build Coastguard Worker 	*outSocketRef = sock;
3101*48a54d36SAndroid Build Coastguard Worker 	sock = kInvalidSocketRef;
3102*48a54d36SAndroid Build Coastguard Worker 	err = mStatus_NoError;
3103*48a54d36SAndroid Build Coastguard Worker 
3104*48a54d36SAndroid Build Coastguard Worker exit:
3105*48a54d36SAndroid Build Coastguard Worker 	if( IsValidSocket( sock ) )
3106*48a54d36SAndroid Build Coastguard Worker 	{
3107*48a54d36SAndroid Build Coastguard Worker 		close_compat( sock );
3108*48a54d36SAndroid Build Coastguard Worker 	}
3109*48a54d36SAndroid Build Coastguard Worker 	return( err );
3110*48a54d36SAndroid Build Coastguard Worker }
3111*48a54d36SAndroid Build Coastguard Worker 
3112*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3113*48a54d36SAndroid Build Coastguard Worker //	SetupSocket
3114*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3115*48a54d36SAndroid Build Coastguard Worker 
SockAddrToMDNSAddr(const struct sockaddr * const inSA,mDNSAddr * outIP,mDNSIPPort * outPort)3116*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus	SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort )
3117*48a54d36SAndroid Build Coastguard Worker {
3118*48a54d36SAndroid Build Coastguard Worker 	mStatus		err;
3119*48a54d36SAndroid Build Coastguard Worker 
3120*48a54d36SAndroid Build Coastguard Worker 	check( inSA );
3121*48a54d36SAndroid Build Coastguard Worker 	check( outIP );
3122*48a54d36SAndroid Build Coastguard Worker 
3123*48a54d36SAndroid Build Coastguard Worker 	if( inSA->sa_family == AF_INET )
3124*48a54d36SAndroid Build Coastguard Worker 	{
3125*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in *		sa4;
3126*48a54d36SAndroid Build Coastguard Worker 
3127*48a54d36SAndroid Build Coastguard Worker 		sa4 						= (struct sockaddr_in *) inSA;
3128*48a54d36SAndroid Build Coastguard Worker 		outIP->type 				= mDNSAddrType_IPv4;
3129*48a54d36SAndroid Build Coastguard Worker 		outIP->ip.v4.NotAnInteger	= sa4->sin_addr.s_addr;
3130*48a54d36SAndroid Build Coastguard Worker 		if( outPort )
3131*48a54d36SAndroid Build Coastguard Worker 		{
3132*48a54d36SAndroid Build Coastguard Worker 			outPort->NotAnInteger	= sa4->sin_port;
3133*48a54d36SAndroid Build Coastguard Worker 		}
3134*48a54d36SAndroid Build Coastguard Worker 		err = mStatus_NoError;
3135*48a54d36SAndroid Build Coastguard Worker 	}
3136*48a54d36SAndroid Build Coastguard Worker 	else if( inSA->sa_family == AF_INET6 )
3137*48a54d36SAndroid Build Coastguard Worker 	{
3138*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in6 *		sa6;
3139*48a54d36SAndroid Build Coastguard Worker 
3140*48a54d36SAndroid Build Coastguard Worker 		sa6 			= (struct sockaddr_in6 *) inSA;
3141*48a54d36SAndroid Build Coastguard Worker 		outIP->type 	= mDNSAddrType_IPv6;
3142*48a54d36SAndroid Build Coastguard Worker 		outIP->ip.v6 	= *( (mDNSv6Addr *) &sa6->sin6_addr );
3143*48a54d36SAndroid Build Coastguard Worker 		if( IN6_IS_ADDR_LINKLOCAL( &sa6->sin6_addr ) )
3144*48a54d36SAndroid Build Coastguard Worker 		{
3145*48a54d36SAndroid Build Coastguard Worker 			outIP->ip.v6.w[ 1 ] = 0;
3146*48a54d36SAndroid Build Coastguard Worker 		}
3147*48a54d36SAndroid Build Coastguard Worker 		if( outPort )
3148*48a54d36SAndroid Build Coastguard Worker 		{
3149*48a54d36SAndroid Build Coastguard Worker 			outPort->NotAnInteger = sa6->sin6_port;
3150*48a54d36SAndroid Build Coastguard Worker 		}
3151*48a54d36SAndroid Build Coastguard Worker 		err = mStatus_NoError;
3152*48a54d36SAndroid Build Coastguard Worker 	}
3153*48a54d36SAndroid Build Coastguard Worker 	else
3154*48a54d36SAndroid Build Coastguard Worker 	{
3155*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelError, DEBUG_NAME "%s: invalid sa_family %d", __ROUTINE__, inSA->sa_family );
3156*48a54d36SAndroid Build Coastguard Worker 		err = mStatus_BadParamErr;
3157*48a54d36SAndroid Build Coastguard Worker 	}
3158*48a54d36SAndroid Build Coastguard Worker 	return( err );
3159*48a54d36SAndroid Build Coastguard Worker }
3160*48a54d36SAndroid Build Coastguard Worker 
3161*48a54d36SAndroid Build Coastguard Worker 
3162*48a54d36SAndroid Build Coastguard Worker #if 0
3163*48a54d36SAndroid Build Coastguard Worker #pragma mark -
3164*48a54d36SAndroid Build Coastguard Worker #endif
3165*48a54d36SAndroid Build Coastguard Worker 
3166*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3167*48a54d36SAndroid Build Coastguard Worker //	UDPBeginRecv
3168*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3169*48a54d36SAndroid Build Coastguard Worker 
UDPBeginRecv(UDPSocket * sock)3170*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus UDPBeginRecv( UDPSocket * sock )
3171*48a54d36SAndroid Build Coastguard Worker {
3172*48a54d36SAndroid Build Coastguard Worker 	DWORD	size;
3173*48a54d36SAndroid Build Coastguard Worker 	DWORD	numTries;
3174*48a54d36SAndroid Build Coastguard Worker 	mStatus	err;
3175*48a54d36SAndroid Build Coastguard Worker 
3176*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
3177*48a54d36SAndroid Build Coastguard Worker 
3178*48a54d36SAndroid Build Coastguard Worker 	require_action( sock != NULL, exit, err = mStatus_BadStateErr );
3179*48a54d36SAndroid Build Coastguard Worker 	check( !sock->overlapped.pending );
3180*48a54d36SAndroid Build Coastguard Worker 
3181*48a54d36SAndroid Build Coastguard Worker 	// Initialize the buffer structure
3182*48a54d36SAndroid Build Coastguard Worker 
3183*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.wbuf.buf	= (char *) &sock->packet;
3184*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.wbuf.len	= (u_long) sizeof( sock->packet );
3185*48a54d36SAndroid Build Coastguard Worker 	sock->srcAddrLen			= sizeof( sock->srcAddr );
3186*48a54d36SAndroid Build Coastguard Worker 
3187*48a54d36SAndroid Build Coastguard Worker 	// Initialize the overlapped structure
3188*48a54d36SAndroid Build Coastguard Worker 
3189*48a54d36SAndroid Build Coastguard Worker 	ZeroMemory( &sock->overlapped.data, sizeof( OVERLAPPED ) );
3190*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.data.hEvent = sock;
3191*48a54d36SAndroid Build Coastguard Worker 
3192*48a54d36SAndroid Build Coastguard Worker 	numTries = 0;
3193*48a54d36SAndroid Build Coastguard Worker 
3194*48a54d36SAndroid Build Coastguard Worker 	do
3195*48a54d36SAndroid Build Coastguard Worker 	{
3196*48a54d36SAndroid Build Coastguard Worker 		if ( sock->recvMsgPtr )
3197*48a54d36SAndroid Build Coastguard Worker 		{
3198*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.name				= ( LPSOCKADDR ) &sock->srcAddr;
3199*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.namelen			= sock->srcAddrLen;
3200*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.lpBuffers		= &sock->overlapped.wbuf;
3201*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.dwBufferCount	= 1;
3202*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.Control.buf		= ( CHAR* ) sock->controlBuffer;
3203*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.Control.len		= sizeof( sock->controlBuffer );
3204*48a54d36SAndroid Build Coastguard Worker 			sock->wmsg.dwFlags			= 0;
3205*48a54d36SAndroid Build Coastguard Worker 
3206*48a54d36SAndroid Build Coastguard Worker 			err = sock->recvMsgPtr( sock->fd, &sock->wmsg, &size, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) UDPEndRecv );
3207*48a54d36SAndroid Build Coastguard Worker 			err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), (OSStatus) WSAGetLastError(), kUnknownErr );
3208*48a54d36SAndroid Build Coastguard Worker 
3209*48a54d36SAndroid Build Coastguard Worker 			// <rdar://problem/7824093> iTunes 9.1 fails to install with Bonjour service on Windows 7 Ultimate
3210*48a54d36SAndroid Build Coastguard Worker 			//
3211*48a54d36SAndroid Build Coastguard Worker 			// There seems to be a bug in some network device drivers that involves calling WSARecvMsg() in
3212*48a54d36SAndroid Build Coastguard Worker 			// overlapped i/o mode. Although all the parameters to WSARecvMsg() are correct, it returns a
3213*48a54d36SAndroid Build Coastguard Worker 			// WSAEFAULT error code when there is no actual error. We have found experientially that falling
3214*48a54d36SAndroid Build Coastguard Worker 			// back to using WSARecvFrom() when this happens will work correctly.
3215*48a54d36SAndroid Build Coastguard Worker 
3216*48a54d36SAndroid Build Coastguard Worker 			if ( err == WSAEFAULT ) sock->recvMsgPtr = NULL;
3217*48a54d36SAndroid Build Coastguard Worker 		}
3218*48a54d36SAndroid Build Coastguard Worker 		else
3219*48a54d36SAndroid Build Coastguard Worker 		{
3220*48a54d36SAndroid Build Coastguard Worker 			DWORD flags = 0;
3221*48a54d36SAndroid Build Coastguard Worker 
3222*48a54d36SAndroid Build Coastguard Worker 			err = WSARecvFrom( sock->fd, &sock->overlapped.wbuf, 1, NULL, &flags, ( LPSOCKADDR ) &sock->srcAddr, &sock->srcAddrLen, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) UDPEndRecv );
3223*48a54d36SAndroid Build Coastguard Worker 			err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), ( OSStatus ) WSAGetLastError(), kUnknownErr );
3224*48a54d36SAndroid Build Coastguard Worker 		}
3225*48a54d36SAndroid Build Coastguard Worker 
3226*48a54d36SAndroid Build Coastguard Worker 		// According to MSDN <http://msdn.microsoft.com/en-us/library/ms741687(VS.85).aspx>:
3227*48a54d36SAndroid Build Coastguard Worker 		//
3228*48a54d36SAndroid Build Coastguard Worker 		// "WSAECONNRESET: For a UDP datagram socket, this error would indicate that a previous
3229*48a54d36SAndroid Build Coastguard Worker 		//                 send operation resulted in an ICMP "Port Unreachable" message."
3230*48a54d36SAndroid Build Coastguard Worker 		//
3231*48a54d36SAndroid Build Coastguard Worker 		// Because this is the case, we want to ignore this error and try again.  Just in case
3232*48a54d36SAndroid Build Coastguard Worker 		// this is some kind of pathological condition, we'll break out of the retry loop
3233*48a54d36SAndroid Build Coastguard Worker 		// after 100 iterations
3234*48a54d36SAndroid Build Coastguard Worker 
3235*48a54d36SAndroid Build Coastguard Worker 		require_action( !err || ( err == WSAECONNRESET ) || ( err == WSAEFAULT ), exit, err = WSAGetLastError() );
3236*48a54d36SAndroid Build Coastguard Worker 	}
3237*48a54d36SAndroid Build Coastguard Worker 	while ( ( ( err == WSAECONNRESET ) || ( err == WSAEFAULT ) ) && ( numTries++ < 100 ) );
3238*48a54d36SAndroid Build Coastguard Worker 
3239*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.pending = TRUE;
3240*48a54d36SAndroid Build Coastguard Worker 
3241*48a54d36SAndroid Build Coastguard Worker exit:
3242*48a54d36SAndroid Build Coastguard Worker 
3243*48a54d36SAndroid Build Coastguard Worker 	if ( err )
3244*48a54d36SAndroid Build Coastguard Worker 	{
3245*48a54d36SAndroid Build Coastguard Worker 		LogMsg( "WSARecvMsg failed (%d)\n", err );
3246*48a54d36SAndroid Build Coastguard Worker 	}
3247*48a54d36SAndroid Build Coastguard Worker 
3248*48a54d36SAndroid Build Coastguard Worker 	return err;
3249*48a54d36SAndroid Build Coastguard Worker }
3250*48a54d36SAndroid Build Coastguard Worker 
3251*48a54d36SAndroid Build Coastguard Worker 
3252*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3253*48a54d36SAndroid Build Coastguard Worker //	UDPEndRecv
3254*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3255*48a54d36SAndroid Build Coastguard Worker 
UDPEndRecv(DWORD err,DWORD bytesTransferred,LPWSAOVERLAPPED overlapped,DWORD flags)3256*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK UDPEndRecv( DWORD err, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags )
3257*48a54d36SAndroid Build Coastguard Worker {
3258*48a54d36SAndroid Build Coastguard Worker 	UDPSocket * sock = NULL;
3259*48a54d36SAndroid Build Coastguard Worker 
3260*48a54d36SAndroid Build Coastguard Worker 	( void ) flags;
3261*48a54d36SAndroid Build Coastguard Worker 
3262*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "%s: err = %d, bytesTransferred = %d\n", __ROUTINE__, err, bytesTransferred );
3263*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( err != WSA_OPERATION_ABORTED, exit, err = ( DWORD ) kUnknownErr );
3264*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
3265*48a54d36SAndroid Build Coastguard Worker 	sock = ( overlapped != NULL ) ? overlapped->hEvent : NULL;
3266*48a54d36SAndroid Build Coastguard Worker 	require_action( sock != NULL, exit, err = ( DWORD ) kUnknownErr );
3267*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
3268*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.error				= err;
3269*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.bytesTransferred	= bytesTransferred;
3270*48a54d36SAndroid Build Coastguard Worker 	check( sock->overlapped.pending );
3271*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.pending			= FALSE;
3272*48a54d36SAndroid Build Coastguard Worker 
3273*48a54d36SAndroid Build Coastguard Worker 	// Translate the source of this packet into mDNS data types
3274*48a54d36SAndroid Build Coastguard Worker 
3275*48a54d36SAndroid Build Coastguard Worker 	SockAddrToMDNSAddr( (struct sockaddr *) &sock->srcAddr, &sock->overlapped.srcAddr, &sock->overlapped.srcPort );
3276*48a54d36SAndroid Build Coastguard Worker 
3277*48a54d36SAndroid Build Coastguard Worker 	// Initialize the destination of this packet. Just in case
3278*48a54d36SAndroid Build Coastguard Worker 	// we can't determine this info because we couldn't call
3279*48a54d36SAndroid Build Coastguard Worker 	// WSARecvMsg (recvMsgPtr)
3280*48a54d36SAndroid Build Coastguard Worker 
3281*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.dstAddr = sock->addr;
3282*48a54d36SAndroid Build Coastguard Worker 	sock->overlapped.dstPort = sock->port;
3283*48a54d36SAndroid Build Coastguard Worker 
3284*48a54d36SAndroid Build Coastguard Worker 	if ( sock->recvMsgPtr )
3285*48a54d36SAndroid Build Coastguard Worker 	{
3286*48a54d36SAndroid Build Coastguard Worker 		LPWSACMSGHDR	header;
3287*48a54d36SAndroid Build Coastguard Worker 		LPWSACMSGHDR	last = NULL;
3288*48a54d36SAndroid Build Coastguard Worker 		int				count = 0;
3289*48a54d36SAndroid Build Coastguard Worker 
3290*48a54d36SAndroid Build Coastguard Worker 		// Parse the control information. Reject packets received on the wrong interface.
3291*48a54d36SAndroid Build Coastguard Worker 
3292*48a54d36SAndroid Build Coastguard Worker 		// <rdar://problem/7832196> INSTALL: Bonjour 2.0 on Windows can not start / stop
3293*48a54d36SAndroid Build Coastguard Worker 		//
3294*48a54d36SAndroid Build Coastguard Worker 		// There seems to be an interaction between Bullguard and this next bit of code.
3295*48a54d36SAndroid Build Coastguard Worker 		// When a user's machine is running Bullguard, the control information that is
3296*48a54d36SAndroid Build Coastguard Worker 		// returned is corrupted, and the code would go into an infinite loop. We'll add
3297*48a54d36SAndroid Build Coastguard Worker 		// two bits of defensive coding here. The first will check that each pointer to
3298*48a54d36SAndroid Build Coastguard Worker 		// the LPWSACMSGHDR that is returned in the for loop is different than the last.
3299*48a54d36SAndroid Build Coastguard Worker 		// This fixes the problem with Bullguard. The second will break out of this loop
3300*48a54d36SAndroid Build Coastguard Worker 		// after 100 iterations, just in case the corruption isn't caught by the first
3301*48a54d36SAndroid Build Coastguard Worker 		// check.
3302*48a54d36SAndroid Build Coastguard Worker 
3303*48a54d36SAndroid Build Coastguard Worker 		for ( header = WSA_CMSG_FIRSTHDR( &sock->wmsg ); header; header = WSA_CMSG_NXTHDR( &sock->wmsg, header ) )
3304*48a54d36SAndroid Build Coastguard Worker 		{
3305*48a54d36SAndroid Build Coastguard Worker 			if ( ( header != last ) && ( ++count < 100 ) )
3306*48a54d36SAndroid Build Coastguard Worker 			{
3307*48a54d36SAndroid Build Coastguard Worker 				last = header;
3308*48a54d36SAndroid Build Coastguard Worker 
3309*48a54d36SAndroid Build Coastguard Worker 				if ( ( header->cmsg_level == IPPROTO_IP ) && ( header->cmsg_type == IP_PKTINFO ) )
3310*48a54d36SAndroid Build Coastguard Worker 				{
3311*48a54d36SAndroid Build Coastguard Worker 					IN_PKTINFO * ipv4PacketInfo;
3312*48a54d36SAndroid Build Coastguard Worker 
3313*48a54d36SAndroid Build Coastguard Worker 					ipv4PacketInfo = (IN_PKTINFO *) WSA_CMSG_DATA( header );
3314*48a54d36SAndroid Build Coastguard Worker 
3315*48a54d36SAndroid Build Coastguard Worker 					if ( sock->ifd != NULL )
3316*48a54d36SAndroid Build Coastguard Worker 					{
3317*48a54d36SAndroid Build Coastguard Worker 						require_action( ipv4PacketInfo->ipi_ifindex == sock->ifd->index, exit, err = ( DWORD ) kMismatchErr );
3318*48a54d36SAndroid Build Coastguard Worker 					}
3319*48a54d36SAndroid Build Coastguard Worker 
3320*48a54d36SAndroid Build Coastguard Worker 					sock->overlapped.dstAddr.type 				= mDNSAddrType_IPv4;
3321*48a54d36SAndroid Build Coastguard Worker 					sock->overlapped.dstAddr.ip.v4.NotAnInteger	= ipv4PacketInfo->ipi_addr.s_addr;
3322*48a54d36SAndroid Build Coastguard Worker 				}
3323*48a54d36SAndroid Build Coastguard Worker 				else if( ( header->cmsg_level == IPPROTO_IPV6 ) && ( header->cmsg_type == IPV6_PKTINFO ) )
3324*48a54d36SAndroid Build Coastguard Worker 				{
3325*48a54d36SAndroid Build Coastguard Worker 					IN6_PKTINFO * ipv6PacketInfo;
3326*48a54d36SAndroid Build Coastguard Worker 
3327*48a54d36SAndroid Build Coastguard Worker 					ipv6PacketInfo = (IN6_PKTINFO *) WSA_CMSG_DATA( header );
3328*48a54d36SAndroid Build Coastguard Worker 
3329*48a54d36SAndroid Build Coastguard Worker 					if ( sock->ifd != NULL )
3330*48a54d36SAndroid Build Coastguard Worker 					{
3331*48a54d36SAndroid Build Coastguard Worker 						require_action( ipv6PacketInfo->ipi6_ifindex == ( sock->ifd->index - kIPv6IfIndexBase ), exit, err = ( DWORD ) kMismatchErr );
3332*48a54d36SAndroid Build Coastguard Worker 					}
3333*48a54d36SAndroid Build Coastguard Worker 
3334*48a54d36SAndroid Build Coastguard Worker 					sock->overlapped.dstAddr.type	= mDNSAddrType_IPv6;
3335*48a54d36SAndroid Build Coastguard Worker 					sock->overlapped.dstAddr.ip.v6	= *( (mDNSv6Addr *) &ipv6PacketInfo->ipi6_addr );
3336*48a54d36SAndroid Build Coastguard Worker 				}
3337*48a54d36SAndroid Build Coastguard Worker 			}
3338*48a54d36SAndroid Build Coastguard Worker 			else
3339*48a54d36SAndroid Build Coastguard Worker 			{
3340*48a54d36SAndroid Build Coastguard Worker 				static BOOL loggedMessage = FALSE;
3341*48a54d36SAndroid Build Coastguard Worker 
3342*48a54d36SAndroid Build Coastguard Worker 				if ( !loggedMessage )
3343*48a54d36SAndroid Build Coastguard Worker 				{
3344*48a54d36SAndroid Build Coastguard Worker 					LogMsg( "UDPEndRecv: WSARecvMsg control information error." );
3345*48a54d36SAndroid Build Coastguard Worker 					loggedMessage = TRUE;
3346*48a54d36SAndroid Build Coastguard Worker 				}
3347*48a54d36SAndroid Build Coastguard Worker 
3348*48a54d36SAndroid Build Coastguard Worker 				break;
3349*48a54d36SAndroid Build Coastguard Worker 			}
3350*48a54d36SAndroid Build Coastguard Worker 		}
3351*48a54d36SAndroid Build Coastguard Worker 	}
3352*48a54d36SAndroid Build Coastguard Worker 
3353*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "packet received\n" );
3354*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "    size      = %d\n", bytesTransferred );
3355*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "    src       = %#a:%u\n", &sock->overlapped.srcAddr, ntohs( sock->overlapped.srcPort.NotAnInteger ) );
3356*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "    dst       = %#a:%u\n", &sock->overlapped.dstAddr, ntohs( sock->overlapped.dstPort.NotAnInteger ) );
3357*48a54d36SAndroid Build Coastguard Worker 
3358*48a54d36SAndroid Build Coastguard Worker 	if ( sock->ifd != NULL )
3359*48a54d36SAndroid Build Coastguard Worker 	{
3360*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelChatty, DEBUG_NAME "    interface = %#a (index=0x%08X)\n", &sock->ifd->interfaceInfo.ip, sock->ifd->index );
3361*48a54d36SAndroid Build Coastguard Worker 	}
3362*48a54d36SAndroid Build Coastguard Worker 
3363*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "\n" );
3364*48a54d36SAndroid Build Coastguard Worker 
3365*48a54d36SAndroid Build Coastguard Worker 	// Queue this socket
3366*48a54d36SAndroid Build Coastguard Worker 
3367*48a54d36SAndroid Build Coastguard Worker 	AddToTail( &gUDPDispatchableSockets, sock );
3368*48a54d36SAndroid Build Coastguard Worker 
3369*48a54d36SAndroid Build Coastguard Worker exit:
3370*48a54d36SAndroid Build Coastguard Worker 
3371*48a54d36SAndroid Build Coastguard Worker 	return;
3372*48a54d36SAndroid Build Coastguard Worker }
3373*48a54d36SAndroid Build Coastguard Worker 
3374*48a54d36SAndroid Build Coastguard Worker 
3375*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3376*48a54d36SAndroid Build Coastguard Worker //	InterfaceListDidChange
3377*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
InterfaceListDidChange(mDNS * const inMDNS)3378*48a54d36SAndroid Build Coastguard Worker void InterfaceListDidChange( mDNS * const inMDNS )
3379*48a54d36SAndroid Build Coastguard Worker {
3380*48a54d36SAndroid Build Coastguard Worker 	mStatus err;
3381*48a54d36SAndroid Build Coastguard Worker 
3382*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "interface list changed\n" );
3383*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
3384*48a54d36SAndroid Build Coastguard Worker 
3385*48a54d36SAndroid Build Coastguard Worker 	// Tear down the existing interfaces and set up new ones using the new IP info.
3386*48a54d36SAndroid Build Coastguard Worker 
3387*48a54d36SAndroid Build Coastguard Worker 	err = TearDownInterfaceList( inMDNS );
3388*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
3389*48a54d36SAndroid Build Coastguard Worker 
3390*48a54d36SAndroid Build Coastguard Worker 	err = SetupInterfaceList( inMDNS );
3391*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
3392*48a54d36SAndroid Build Coastguard Worker 
3393*48a54d36SAndroid Build Coastguard Worker 	err = uDNS_SetupDNSConfig( inMDNS );
3394*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
3395*48a54d36SAndroid Build Coastguard Worker 
3396*48a54d36SAndroid Build Coastguard Worker 	// Inform clients of the change.
3397*48a54d36SAndroid Build Coastguard Worker 
3398*48a54d36SAndroid Build Coastguard Worker 	mDNS_ConfigChanged(inMDNS);
3399*48a54d36SAndroid Build Coastguard Worker 
3400*48a54d36SAndroid Build Coastguard Worker 	// Force mDNS to update.
3401*48a54d36SAndroid Build Coastguard Worker 
3402*48a54d36SAndroid Build Coastguard Worker 	mDNSCoreMachineSleep( inMDNS, mDNSfalse ); // What is this for? Mac OS X does not do this
3403*48a54d36SAndroid Build Coastguard Worker }
3404*48a54d36SAndroid Build Coastguard Worker 
3405*48a54d36SAndroid Build Coastguard Worker 
3406*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3407*48a54d36SAndroid Build Coastguard Worker //	ComputerDescriptionDidChange
3408*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
ComputerDescriptionDidChange(mDNS * const inMDNS)3409*48a54d36SAndroid Build Coastguard Worker void ComputerDescriptionDidChange( mDNS * const inMDNS )
3410*48a54d36SAndroid Build Coastguard Worker {
3411*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "computer description has changed\n" );
3412*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
3413*48a54d36SAndroid Build Coastguard Worker 
3414*48a54d36SAndroid Build Coastguard Worker 	// redo the names
3415*48a54d36SAndroid Build Coastguard Worker 	SetupNiceName( inMDNS );
3416*48a54d36SAndroid Build Coastguard Worker }
3417*48a54d36SAndroid Build Coastguard Worker 
3418*48a54d36SAndroid Build Coastguard Worker 
3419*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3420*48a54d36SAndroid Build Coastguard Worker //	TCPIPConfigDidChange
3421*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
TCPIPConfigDidChange(mDNS * const inMDNS)3422*48a54d36SAndroid Build Coastguard Worker void TCPIPConfigDidChange( mDNS * const inMDNS )
3423*48a54d36SAndroid Build Coastguard Worker {
3424*48a54d36SAndroid Build Coastguard Worker 	mStatus		err;
3425*48a54d36SAndroid Build Coastguard Worker 
3426*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "TCP/IP config has changed\n" );
3427*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
3428*48a54d36SAndroid Build Coastguard Worker 
3429*48a54d36SAndroid Build Coastguard Worker 	err = uDNS_SetupDNSConfig( inMDNS );
3430*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
3431*48a54d36SAndroid Build Coastguard Worker }
3432*48a54d36SAndroid Build Coastguard Worker 
3433*48a54d36SAndroid Build Coastguard Worker 
3434*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3435*48a54d36SAndroid Build Coastguard Worker //	DynDNSConfigDidChange
3436*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
DynDNSConfigDidChange(mDNS * const inMDNS)3437*48a54d36SAndroid Build Coastguard Worker void DynDNSConfigDidChange( mDNS * const inMDNS )
3438*48a54d36SAndroid Build Coastguard Worker {
3439*48a54d36SAndroid Build Coastguard Worker 	mStatus		err;
3440*48a54d36SAndroid Build Coastguard Worker 
3441*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "DynDNS config has changed\n" );
3442*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
3443*48a54d36SAndroid Build Coastguard Worker 
3444*48a54d36SAndroid Build Coastguard Worker 	SetDomainSecrets( inMDNS );
3445*48a54d36SAndroid Build Coastguard Worker 
3446*48a54d36SAndroid Build Coastguard Worker 	err = uDNS_SetupDNSConfig( inMDNS );
3447*48a54d36SAndroid Build Coastguard Worker 	check_noerr( err );
3448*48a54d36SAndroid Build Coastguard Worker }
3449*48a54d36SAndroid Build Coastguard Worker 
3450*48a54d36SAndroid Build Coastguard Worker 
3451*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3452*48a54d36SAndroid Build Coastguard Worker //	FileSharingDidChange
3453*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
FileSharingDidChange(mDNS * const inMDNS)3454*48a54d36SAndroid Build Coastguard Worker void FileSharingDidChange( mDNS * const inMDNS )
3455*48a54d36SAndroid Build Coastguard Worker {
3456*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "File shares has changed\n" );
3457*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
3458*48a54d36SAndroid Build Coastguard Worker 
3459*48a54d36SAndroid Build Coastguard Worker 	CheckFileShares( inMDNS );
3460*48a54d36SAndroid Build Coastguard Worker }
3461*48a54d36SAndroid Build Coastguard Worker 
3462*48a54d36SAndroid Build Coastguard Worker 
3463*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3464*48a54d36SAndroid Build Coastguard Worker //	FilewallDidChange
3465*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
FirewallDidChange(mDNS * const inMDNS)3466*48a54d36SAndroid Build Coastguard Worker void FirewallDidChange( mDNS * const inMDNS )
3467*48a54d36SAndroid Build Coastguard Worker {
3468*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "Firewall has changed\n" );
3469*48a54d36SAndroid Build Coastguard Worker 	check( inMDNS );
3470*48a54d36SAndroid Build Coastguard Worker 
3471*48a54d36SAndroid Build Coastguard Worker 	CheckFileShares( inMDNS );
3472*48a54d36SAndroid Build Coastguard Worker }
3473*48a54d36SAndroid Build Coastguard Worker 
3474*48a54d36SAndroid Build Coastguard Worker 
3475*48a54d36SAndroid Build Coastguard Worker #if 0
3476*48a54d36SAndroid Build Coastguard Worker #pragma mark -
3477*48a54d36SAndroid Build Coastguard Worker #pragma mark == Utilities ==
3478*48a54d36SAndroid Build Coastguard Worker #endif
3479*48a54d36SAndroid Build Coastguard Worker 
3480*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3481*48a54d36SAndroid Build Coastguard Worker //	getifaddrs
3482*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3483*48a54d36SAndroid Build Coastguard Worker 
getifaddrs(struct ifaddrs ** outAddrs)3484*48a54d36SAndroid Build Coastguard Worker mDNSlocal int	getifaddrs( struct ifaddrs **outAddrs )
3485*48a54d36SAndroid Build Coastguard Worker {
3486*48a54d36SAndroid Build Coastguard Worker 	int		err;
3487*48a54d36SAndroid Build Coastguard Worker 
3488*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
3489*48a54d36SAndroid Build Coastguard Worker 
3490*48a54d36SAndroid Build Coastguard Worker 	// Try to the load the GetAdaptersAddresses function from the IP Helpers DLL. This API is only available on Windows
3491*48a54d36SAndroid Build Coastguard Worker 	// XP or later. Looking up the symbol at runtime allows the code to still work on older systems without that API.
3492*48a54d36SAndroid Build Coastguard Worker 
3493*48a54d36SAndroid Build Coastguard Worker 	if( !gIPHelperLibraryInstance )
3494*48a54d36SAndroid Build Coastguard Worker 	{
3495*48a54d36SAndroid Build Coastguard Worker 		gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
3496*48a54d36SAndroid Build Coastguard Worker 		if( gIPHelperLibraryInstance )
3497*48a54d36SAndroid Build Coastguard Worker 		{
3498*48a54d36SAndroid Build Coastguard Worker 			gGetAdaptersAddressesFunctionPtr =
3499*48a54d36SAndroid Build Coastguard Worker 				(GetAdaptersAddressesFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetAdaptersAddresses" );
3500*48a54d36SAndroid Build Coastguard Worker 			if( !gGetAdaptersAddressesFunctionPtr )
3501*48a54d36SAndroid Build Coastguard Worker 			{
3502*48a54d36SAndroid Build Coastguard Worker 				BOOL		ok;
3503*48a54d36SAndroid Build Coastguard Worker 
3504*48a54d36SAndroid Build Coastguard Worker 				ok = FreeLibrary( gIPHelperLibraryInstance );
3505*48a54d36SAndroid Build Coastguard Worker 				check_translated_errno( ok, GetLastError(), kUnknownErr );
3506*48a54d36SAndroid Build Coastguard Worker 				gIPHelperLibraryInstance = NULL;
3507*48a54d36SAndroid Build Coastguard Worker 			}
3508*48a54d36SAndroid Build Coastguard Worker 		}
3509*48a54d36SAndroid Build Coastguard Worker 	}
3510*48a54d36SAndroid Build Coastguard Worker 
3511*48a54d36SAndroid Build Coastguard Worker 	// Use the new IPv6-capable routine if supported. Otherwise, fall back to the old and compatible IPv4-only code.
3512*48a54d36SAndroid Build Coastguard Worker 	// <rdar://problem/4278934>  Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 fails
3513*48a54d36SAndroid Build Coastguard Worker 	// <rdar://problem/6145913>  Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 returns no addrs
3514*48a54d36SAndroid Build Coastguard Worker 
3515*48a54d36SAndroid Build Coastguard Worker 	if( !gGetAdaptersAddressesFunctionPtr || ( ( ( err = getifaddrs_ipv6( outAddrs ) ) != mStatus_NoError ) || ( ( outAddrs != NULL ) && ( *outAddrs == NULL ) ) ) )
3516*48a54d36SAndroid Build Coastguard Worker 	{
3517*48a54d36SAndroid Build Coastguard Worker 		err = getifaddrs_ipv4( outAddrs );
3518*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
3519*48a54d36SAndroid Build Coastguard Worker 	}
3520*48a54d36SAndroid Build Coastguard Worker 
3521*48a54d36SAndroid Build Coastguard Worker #else
3522*48a54d36SAndroid Build Coastguard Worker 
3523*48a54d36SAndroid Build Coastguard Worker 	err = getifaddrs_ipv4( outAddrs );
3524*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
3525*48a54d36SAndroid Build Coastguard Worker 
3526*48a54d36SAndroid Build Coastguard Worker #endif
3527*48a54d36SAndroid Build Coastguard Worker 
3528*48a54d36SAndroid Build Coastguard Worker exit:
3529*48a54d36SAndroid Build Coastguard Worker 	return( err );
3530*48a54d36SAndroid Build Coastguard Worker }
3531*48a54d36SAndroid Build Coastguard Worker 
3532*48a54d36SAndroid Build Coastguard Worker #if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
3533*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3534*48a54d36SAndroid Build Coastguard Worker //	getifaddrs_ipv6
3535*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3536*48a54d36SAndroid Build Coastguard Worker 
getifaddrs_ipv6(struct ifaddrs ** outAddrs)3537*48a54d36SAndroid Build Coastguard Worker mDNSlocal int	getifaddrs_ipv6( struct ifaddrs **outAddrs )
3538*48a54d36SAndroid Build Coastguard Worker {
3539*48a54d36SAndroid Build Coastguard Worker 	DWORD						err;
3540*48a54d36SAndroid Build Coastguard Worker 	int							i;
3541*48a54d36SAndroid Build Coastguard Worker 	DWORD						flags;
3542*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			head;
3543*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs **			next;
3544*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_ADDRESSES *		iaaList;
3545*48a54d36SAndroid Build Coastguard Worker 	ULONG						iaaListSize;
3546*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_ADDRESSES *		iaa;
3547*48a54d36SAndroid Build Coastguard Worker 	size_t						size;
3548*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			ifa;
3549*48a54d36SAndroid Build Coastguard Worker 
3550*48a54d36SAndroid Build Coastguard Worker 	check( gGetAdaptersAddressesFunctionPtr );
3551*48a54d36SAndroid Build Coastguard Worker 
3552*48a54d36SAndroid Build Coastguard Worker 	head	= NULL;
3553*48a54d36SAndroid Build Coastguard Worker 	next	= &head;
3554*48a54d36SAndroid Build Coastguard Worker 	iaaList	= NULL;
3555*48a54d36SAndroid Build Coastguard Worker 
3556*48a54d36SAndroid Build Coastguard Worker 	// Get the list of interfaces. The first call gets the size and the second call gets the actual data.
3557*48a54d36SAndroid Build Coastguard Worker 	// This loops to handle the case where the interface changes in the window after getting the size, but before the
3558*48a54d36SAndroid Build Coastguard Worker 	// second call completes. A limit of 100 retries is enforced to prevent infinite loops if something else is wrong.
3559*48a54d36SAndroid Build Coastguard Worker 
3560*48a54d36SAndroid Build Coastguard Worker 	flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
3561*48a54d36SAndroid Build Coastguard Worker 	i = 0;
3562*48a54d36SAndroid Build Coastguard Worker 	for( ;; )
3563*48a54d36SAndroid Build Coastguard Worker 	{
3564*48a54d36SAndroid Build Coastguard Worker 		iaaListSize = 0;
3565*48a54d36SAndroid Build Coastguard Worker 		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, NULL, &iaaListSize );
3566*48a54d36SAndroid Build Coastguard Worker 		check( err == ERROR_BUFFER_OVERFLOW );
3567*48a54d36SAndroid Build Coastguard Worker 		check( iaaListSize >= sizeof( IP_ADAPTER_ADDRESSES ) );
3568*48a54d36SAndroid Build Coastguard Worker 
3569*48a54d36SAndroid Build Coastguard Worker 		iaaList = (IP_ADAPTER_ADDRESSES *) malloc( iaaListSize );
3570*48a54d36SAndroid Build Coastguard Worker 		require_action( iaaList, exit, err = ERROR_NOT_ENOUGH_MEMORY );
3571*48a54d36SAndroid Build Coastguard Worker 
3572*48a54d36SAndroid Build Coastguard Worker 		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, iaaList, &iaaListSize );
3573*48a54d36SAndroid Build Coastguard Worker 		if( err == ERROR_SUCCESS ) break;
3574*48a54d36SAndroid Build Coastguard Worker 
3575*48a54d36SAndroid Build Coastguard Worker 		free( iaaList );
3576*48a54d36SAndroid Build Coastguard Worker 		iaaList = NULL;
3577*48a54d36SAndroid Build Coastguard Worker 		++i;
3578*48a54d36SAndroid Build Coastguard Worker 		require( i < 100, exit );
3579*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelWarning, "%s: retrying GetAdaptersAddresses after %d failure(s) (%d %m)\n", __ROUTINE__, i, err, err );
3580*48a54d36SAndroid Build Coastguard Worker 	}
3581*48a54d36SAndroid Build Coastguard Worker 
3582*48a54d36SAndroid Build Coastguard Worker 	for( iaa = iaaList; iaa; iaa = iaa->Next )
3583*48a54d36SAndroid Build Coastguard Worker 	{
3584*48a54d36SAndroid Build Coastguard Worker 		int								addrIndex;
3585*48a54d36SAndroid Build Coastguard Worker 		IP_ADAPTER_UNICAST_ADDRESS	*	addr;
3586*48a54d36SAndroid Build Coastguard Worker 		DWORD							ipv6IfIndex;
3587*48a54d36SAndroid Build Coastguard Worker 		IP_ADAPTER_PREFIX			*	firstPrefix;
3588*48a54d36SAndroid Build Coastguard Worker 
3589*48a54d36SAndroid Build Coastguard Worker 		if( iaa->IfIndex > 0xFFFFFF )
3590*48a54d36SAndroid Build Coastguard Worker 		{
3591*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelAlert, DEBUG_NAME "%s: IPv4 ifindex out-of-range (0x%08X)\n", __ROUTINE__, iaa->IfIndex );
3592*48a54d36SAndroid Build Coastguard Worker 		}
3593*48a54d36SAndroid Build Coastguard Worker 		if( iaa->Ipv6IfIndex > 0xFF )
3594*48a54d36SAndroid Build Coastguard Worker 		{
3595*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelAlert, DEBUG_NAME "%s: IPv6 ifindex out-of-range (0x%08X)\n", __ROUTINE__, iaa->Ipv6IfIndex );
3596*48a54d36SAndroid Build Coastguard Worker 		}
3597*48a54d36SAndroid Build Coastguard Worker 
3598*48a54d36SAndroid Build Coastguard Worker 		// For IPv4 interfaces, there seems to be a bug in iphlpapi.dll that causes the
3599*48a54d36SAndroid Build Coastguard Worker 		// following code to crash when iterating through the prefix list.  This seems
3600*48a54d36SAndroid Build Coastguard Worker 		// to occur when iaa->Ipv6IfIndex != 0 when IPv6 is not installed on the host.
3601*48a54d36SAndroid Build Coastguard Worker 		// This shouldn't happen according to Microsoft docs which states:
3602*48a54d36SAndroid Build Coastguard Worker 		//
3603*48a54d36SAndroid Build Coastguard Worker 		//     "Ipv6IfIndex contains 0 if IPv6 is not available on the interface."
3604*48a54d36SAndroid Build Coastguard Worker 		//
3605*48a54d36SAndroid Build Coastguard Worker 		// So the data structure seems to be corrupted when we return from
3606*48a54d36SAndroid Build Coastguard Worker 		// GetAdaptersAddresses(). The bug seems to occur when iaa->Length <
3607*48a54d36SAndroid Build Coastguard Worker 		// sizeof(IP_ADAPTER_ADDRESSES), so when that happens, we'll manually
3608*48a54d36SAndroid Build Coastguard Worker 		// modify iaa to have the correct values.
3609*48a54d36SAndroid Build Coastguard Worker 
3610*48a54d36SAndroid Build Coastguard Worker 		if ( iaa->Length >= sizeof( IP_ADAPTER_ADDRESSES ) )
3611*48a54d36SAndroid Build Coastguard Worker 		{
3612*48a54d36SAndroid Build Coastguard Worker 			ipv6IfIndex = iaa->Ipv6IfIndex;
3613*48a54d36SAndroid Build Coastguard Worker 			firstPrefix = iaa->FirstPrefix;
3614*48a54d36SAndroid Build Coastguard Worker 		}
3615*48a54d36SAndroid Build Coastguard Worker 		else
3616*48a54d36SAndroid Build Coastguard Worker 		{
3617*48a54d36SAndroid Build Coastguard Worker 			ipv6IfIndex	= 0;
3618*48a54d36SAndroid Build Coastguard Worker 			firstPrefix = NULL;
3619*48a54d36SAndroid Build Coastguard Worker 		}
3620*48a54d36SAndroid Build Coastguard Worker 
3621*48a54d36SAndroid Build Coastguard Worker 		// Skip pseudo and tunnel interfaces.
3622*48a54d36SAndroid Build Coastguard Worker 
3623*48a54d36SAndroid Build Coastguard Worker 		if( ( ( ipv6IfIndex == 1 ) && ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
3624*48a54d36SAndroid Build Coastguard Worker 		{
3625*48a54d36SAndroid Build Coastguard Worker 			continue;
3626*48a54d36SAndroid Build Coastguard Worker 		}
3627*48a54d36SAndroid Build Coastguard Worker 
3628*48a54d36SAndroid Build Coastguard Worker 		// Add each address as a separate interface to emulate the way getifaddrs works.
3629*48a54d36SAndroid Build Coastguard Worker 
3630*48a54d36SAndroid Build Coastguard Worker 		for( addrIndex = 0, addr = iaa->FirstUnicastAddress; addr; ++addrIndex, addr = addr->Next )
3631*48a54d36SAndroid Build Coastguard Worker 		{
3632*48a54d36SAndroid Build Coastguard Worker 			int						family;
3633*48a54d36SAndroid Build Coastguard Worker 			int						prefixIndex;
3634*48a54d36SAndroid Build Coastguard Worker 			IP_ADAPTER_PREFIX *		prefix;
3635*48a54d36SAndroid Build Coastguard Worker 			ULONG					prefixLength;
3636*48a54d36SAndroid Build Coastguard Worker 			uint32_t				ipv4Index;
3637*48a54d36SAndroid Build Coastguard Worker 			struct sockaddr_in		ipv4Netmask;
3638*48a54d36SAndroid Build Coastguard Worker 
3639*48a54d36SAndroid Build Coastguard Worker 			family = addr->Address.lpSockaddr->sa_family;
3640*48a54d36SAndroid Build Coastguard Worker 			if( ( family != AF_INET ) && ( family != AF_INET6 ) ) continue;
3641*48a54d36SAndroid Build Coastguard Worker 
3642*48a54d36SAndroid Build Coastguard Worker 			// <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
3643*48a54d36SAndroid Build Coastguard Worker 			// Seems as if the problem here is a buggy implementation of some network interface
3644*48a54d36SAndroid Build Coastguard Worker 			// driver. It is reporting that is has a link-local address when it is actually
3645*48a54d36SAndroid Build Coastguard Worker 			// disconnected. This was causing a problem in AddressToIndexAndMask.
3646*48a54d36SAndroid Build Coastguard Worker 			// The solution is to call AddressToIndexAndMask first, and if unable to lookup
3647*48a54d36SAndroid Build Coastguard Worker 			// the address, to ignore that address.
3648*48a54d36SAndroid Build Coastguard Worker 
3649*48a54d36SAndroid Build Coastguard Worker 			ipv4Index = 0;
3650*48a54d36SAndroid Build Coastguard Worker 			memset( &ipv4Netmask, 0, sizeof( ipv4Netmask ) );
3651*48a54d36SAndroid Build Coastguard Worker 
3652*48a54d36SAndroid Build Coastguard Worker 			if ( family == AF_INET )
3653*48a54d36SAndroid Build Coastguard Worker 			{
3654*48a54d36SAndroid Build Coastguard Worker 				err = AddressToIndexAndMask( addr->Address.lpSockaddr, &ipv4Index, ( struct sockaddr* ) &ipv4Netmask );
3655*48a54d36SAndroid Build Coastguard Worker 
3656*48a54d36SAndroid Build Coastguard Worker 				if ( err )
3657*48a54d36SAndroid Build Coastguard Worker 				{
3658*48a54d36SAndroid Build Coastguard Worker 					err = 0;
3659*48a54d36SAndroid Build Coastguard Worker 					continue;
3660*48a54d36SAndroid Build Coastguard Worker 				}
3661*48a54d36SAndroid Build Coastguard Worker 			}
3662*48a54d36SAndroid Build Coastguard Worker 
3663*48a54d36SAndroid Build Coastguard Worker 			ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
3664*48a54d36SAndroid Build Coastguard Worker 			require_action( ifa, exit, err = WSAENOBUFS );
3665*48a54d36SAndroid Build Coastguard Worker 
3666*48a54d36SAndroid Build Coastguard Worker 			*next = ifa;
3667*48a54d36SAndroid Build Coastguard Worker 			next  = &ifa->ifa_next;
3668*48a54d36SAndroid Build Coastguard Worker 
3669*48a54d36SAndroid Build Coastguard Worker 			// Get the name.
3670*48a54d36SAndroid Build Coastguard Worker 
3671*48a54d36SAndroid Build Coastguard Worker 			size = strlen( iaa->AdapterName ) + 1;
3672*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_name = (char *) malloc( size );
3673*48a54d36SAndroid Build Coastguard Worker 			require_action( ifa->ifa_name, exit, err = WSAENOBUFS );
3674*48a54d36SAndroid Build Coastguard Worker 			memcpy( ifa->ifa_name, iaa->AdapterName, size );
3675*48a54d36SAndroid Build Coastguard Worker 
3676*48a54d36SAndroid Build Coastguard Worker 			// Get interface flags.
3677*48a54d36SAndroid Build Coastguard Worker 
3678*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_flags = 0;
3679*48a54d36SAndroid Build Coastguard Worker 			if( iaa->OperStatus == IfOperStatusUp ) 		ifa->ifa_flags |= IFF_UP;
3680*48a54d36SAndroid Build Coastguard Worker 			if( iaa->IfType == IF_TYPE_SOFTWARE_LOOPBACK )	ifa->ifa_flags |= IFF_LOOPBACK;
3681*48a54d36SAndroid Build Coastguard Worker 			else if ( IsPointToPoint( addr ) )				ifa->ifa_flags |= IFF_POINTTOPOINT;
3682*48a54d36SAndroid Build Coastguard Worker 			if( !( iaa->Flags & IP_ADAPTER_NO_MULTICAST ) )	ifa->ifa_flags |= IFF_MULTICAST;
3683*48a54d36SAndroid Build Coastguard Worker 
3684*48a54d36SAndroid Build Coastguard Worker 
3685*48a54d36SAndroid Build Coastguard Worker 			// <rdar://problem/4045657> Interface index being returned is 512
3686*48a54d36SAndroid Build Coastguard Worker 			//
3687*48a54d36SAndroid Build Coastguard Worker 			// Windows does not have a uniform scheme for IPv4 and IPv6 interface indexes.
3688*48a54d36SAndroid Build Coastguard Worker 			// This code used to shift the IPv4 index up to ensure uniqueness between
3689*48a54d36SAndroid Build Coastguard Worker 			// it and IPv6 indexes.  Although this worked, it was somewhat confusing to developers, who
3690*48a54d36SAndroid Build Coastguard Worker 			// then see interface indexes passed back that don't correspond to anything
3691*48a54d36SAndroid Build Coastguard Worker 			// that is seen in Win32 APIs or command line tools like "route".  As a relatively
3692*48a54d36SAndroid Build Coastguard Worker 			// small percentage of developers are actively using IPv6, it seems to
3693*48a54d36SAndroid Build Coastguard Worker 			// make sense to make our use of IPv4 as confusion free as possible.
3694*48a54d36SAndroid Build Coastguard Worker 			// So now, IPv6 interface indexes will be shifted up by a
3695*48a54d36SAndroid Build Coastguard Worker 			// constant value which will serve to uniquely identify them, and we will
3696*48a54d36SAndroid Build Coastguard Worker 			// leave IPv4 interface indexes unmodified.
3697*48a54d36SAndroid Build Coastguard Worker 
3698*48a54d36SAndroid Build Coastguard Worker 			switch( family )
3699*48a54d36SAndroid Build Coastguard Worker 			{
3700*48a54d36SAndroid Build Coastguard Worker 				case AF_INET:  ifa->ifa_extra.index = iaa->IfIndex; break;
3701*48a54d36SAndroid Build Coastguard Worker 				case AF_INET6: ifa->ifa_extra.index = ipv6IfIndex + kIPv6IfIndexBase;	 break;
3702*48a54d36SAndroid Build Coastguard Worker 				default: break;
3703*48a54d36SAndroid Build Coastguard Worker 			}
3704*48a54d36SAndroid Build Coastguard Worker 
3705*48a54d36SAndroid Build Coastguard Worker 			// Get lease lifetime
3706*48a54d36SAndroid Build Coastguard Worker 
3707*48a54d36SAndroid Build Coastguard Worker 			if ( ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) && ( addr->LeaseLifetime != 0 ) && ( addr->ValidLifetime != 0xFFFFFFFF ) )
3708*48a54d36SAndroid Build Coastguard Worker 			{
3709*48a54d36SAndroid Build Coastguard Worker 				ifa->ifa_dhcpEnabled		= TRUE;
3710*48a54d36SAndroid Build Coastguard Worker 				ifa->ifa_dhcpLeaseExpires	= time( NULL ) + addr->ValidLifetime;
3711*48a54d36SAndroid Build Coastguard Worker 			}
3712*48a54d36SAndroid Build Coastguard Worker 			else
3713*48a54d36SAndroid Build Coastguard Worker 			{
3714*48a54d36SAndroid Build Coastguard Worker 				ifa->ifa_dhcpEnabled		= FALSE;
3715*48a54d36SAndroid Build Coastguard Worker 				ifa->ifa_dhcpLeaseExpires	= 0;
3716*48a54d36SAndroid Build Coastguard Worker 			}
3717*48a54d36SAndroid Build Coastguard Worker 
3718*48a54d36SAndroid Build Coastguard Worker 			if ( iaa->PhysicalAddressLength == sizeof( ifa->ifa_physaddr ) )
3719*48a54d36SAndroid Build Coastguard Worker 			{
3720*48a54d36SAndroid Build Coastguard Worker 				memcpy( ifa->ifa_physaddr, iaa->PhysicalAddress, iaa->PhysicalAddressLength );
3721*48a54d36SAndroid Build Coastguard Worker 			}
3722*48a54d36SAndroid Build Coastguard Worker 
3723*48a54d36SAndroid Build Coastguard Worker 			// Because we don't get notified of womp changes, we're going to just assume
3724*48a54d36SAndroid Build Coastguard Worker 			// that all wired interfaces have it enabled. Before we go to sleep, we'll check
3725*48a54d36SAndroid Build Coastguard Worker 			// if the interface actually supports it, and update mDNS->SystemWakeOnLANEnabled
3726*48a54d36SAndroid Build Coastguard Worker 			// accordingly
3727*48a54d36SAndroid Build Coastguard Worker 
3728*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_womp = ( iaa->IfType == IF_TYPE_ETHERNET_CSMACD ) ? mDNStrue : mDNSfalse;
3729*48a54d36SAndroid Build Coastguard Worker 
3730*48a54d36SAndroid Build Coastguard Worker 			// Get address.
3731*48a54d36SAndroid Build Coastguard Worker 
3732*48a54d36SAndroid Build Coastguard Worker 			switch( family )
3733*48a54d36SAndroid Build Coastguard Worker 			{
3734*48a54d36SAndroid Build Coastguard Worker 				case AF_INET:
3735*48a54d36SAndroid Build Coastguard Worker 				case AF_INET6:
3736*48a54d36SAndroid Build Coastguard Worker 					ifa->ifa_addr = (struct sockaddr *) calloc( 1, (size_t) addr->Address.iSockaddrLength );
3737*48a54d36SAndroid Build Coastguard Worker 					require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
3738*48a54d36SAndroid Build Coastguard Worker 					memcpy( ifa->ifa_addr, addr->Address.lpSockaddr, (size_t) addr->Address.iSockaddrLength );
3739*48a54d36SAndroid Build Coastguard Worker 					break;
3740*48a54d36SAndroid Build Coastguard Worker 
3741*48a54d36SAndroid Build Coastguard Worker 				default:
3742*48a54d36SAndroid Build Coastguard Worker 					break;
3743*48a54d36SAndroid Build Coastguard Worker 			}
3744*48a54d36SAndroid Build Coastguard Worker 			check( ifa->ifa_addr );
3745*48a54d36SAndroid Build Coastguard Worker 
3746*48a54d36SAndroid Build Coastguard Worker 			// Get subnet mask (IPv4)/link prefix (IPv6). It is specified as a bit length (e.g. 24 for 255.255.255.0).
3747*48a54d36SAndroid Build Coastguard Worker 
3748*48a54d36SAndroid Build Coastguard Worker 			prefixLength = 0;
3749*48a54d36SAndroid Build Coastguard Worker 			for( prefixIndex = 0, prefix = firstPrefix; prefix; ++prefixIndex, prefix = prefix->Next )
3750*48a54d36SAndroid Build Coastguard Worker 			{
3751*48a54d36SAndroid Build Coastguard Worker 				if( ( prefix->Address.lpSockaddr->sa_family == family ) && ( prefixIndex == addrIndex ) )
3752*48a54d36SAndroid Build Coastguard Worker 				{
3753*48a54d36SAndroid Build Coastguard Worker 					check_string( prefix->Address.lpSockaddr->sa_family == family, "addr family != netmask family" );
3754*48a54d36SAndroid Build Coastguard Worker 					prefixLength = prefix->PrefixLength;
3755*48a54d36SAndroid Build Coastguard Worker 					break;
3756*48a54d36SAndroid Build Coastguard Worker 				}
3757*48a54d36SAndroid Build Coastguard Worker 			}
3758*48a54d36SAndroid Build Coastguard Worker 			switch( family )
3759*48a54d36SAndroid Build Coastguard Worker 			{
3760*48a54d36SAndroid Build Coastguard Worker 				case AF_INET:
3761*48a54d36SAndroid Build Coastguard Worker 				{
3762*48a54d36SAndroid Build Coastguard Worker 					struct sockaddr_in * sa4;
3763*48a54d36SAndroid Build Coastguard Worker 
3764*48a54d36SAndroid Build Coastguard Worker 					sa4 = (struct sockaddr_in *) calloc( 1, sizeof( *sa4 ) );
3765*48a54d36SAndroid Build Coastguard Worker 					require_action( sa4, exit, err = WSAENOBUFS );
3766*48a54d36SAndroid Build Coastguard Worker 					sa4->sin_family = AF_INET;
3767*48a54d36SAndroid Build Coastguard Worker 					sa4->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr;
3768*48a54d36SAndroid Build Coastguard Worker 
3769*48a54d36SAndroid Build Coastguard Worker 					dlog( kDebugLevelInfo, DEBUG_NAME "%s: IPv4 mask = %s\n", __ROUTINE__, inet_ntoa( sa4->sin_addr ) );
3770*48a54d36SAndroid Build Coastguard Worker 					ifa->ifa_netmask = (struct sockaddr *) sa4;
3771*48a54d36SAndroid Build Coastguard Worker 					break;
3772*48a54d36SAndroid Build Coastguard Worker 				}
3773*48a54d36SAndroid Build Coastguard Worker 
3774*48a54d36SAndroid Build Coastguard Worker 				case AF_INET6:
3775*48a54d36SAndroid Build Coastguard Worker 				{
3776*48a54d36SAndroid Build Coastguard Worker 					struct sockaddr_in6 *		sa6;
3777*48a54d36SAndroid Build Coastguard Worker 					int							len;
3778*48a54d36SAndroid Build Coastguard Worker 					int							maskIndex;
3779*48a54d36SAndroid Build Coastguard Worker 					uint8_t						maskByte;
3780*48a54d36SAndroid Build Coastguard Worker 
3781*48a54d36SAndroid Build Coastguard Worker 					require_action( prefixLength <= 128, exit, err = ERROR_INVALID_DATA );
3782*48a54d36SAndroid Build Coastguard Worker 
3783*48a54d36SAndroid Build Coastguard Worker 					sa6 = (struct sockaddr_in6 *) calloc( 1, sizeof( *sa6 ) );
3784*48a54d36SAndroid Build Coastguard Worker 					require_action( sa6, exit, err = WSAENOBUFS );
3785*48a54d36SAndroid Build Coastguard Worker 					sa6->sin6_family = AF_INET6;
3786*48a54d36SAndroid Build Coastguard Worker 
3787*48a54d36SAndroid Build Coastguard Worker 					if( prefixLength == 0 )
3788*48a54d36SAndroid Build Coastguard Worker 					{
3789*48a54d36SAndroid Build Coastguard Worker 						dlog( kDebugLevelWarning, DEBUG_NAME "%s: IPv6 link prefix 0, defaulting to /128\n", __ROUTINE__ );
3790*48a54d36SAndroid Build Coastguard Worker 						prefixLength = 128;
3791*48a54d36SAndroid Build Coastguard Worker 					}
3792*48a54d36SAndroid Build Coastguard Worker 					maskIndex = 0;
3793*48a54d36SAndroid Build Coastguard Worker 					for( len = (int) prefixLength; len > 0; len -= 8 )
3794*48a54d36SAndroid Build Coastguard Worker 					{
3795*48a54d36SAndroid Build Coastguard Worker 						if( len >= 8 ) maskByte = 0xFF;
3796*48a54d36SAndroid Build Coastguard Worker 						else		   maskByte = (uint8_t)( ( 0xFFU << ( 8 - len ) ) & 0xFFU );
3797*48a54d36SAndroid Build Coastguard Worker 						sa6->sin6_addr.s6_addr[ maskIndex++ ] = maskByte;
3798*48a54d36SAndroid Build Coastguard Worker 					}
3799*48a54d36SAndroid Build Coastguard Worker 					ifa->ifa_netmask = (struct sockaddr *) sa6;
3800*48a54d36SAndroid Build Coastguard Worker 					break;
3801*48a54d36SAndroid Build Coastguard Worker 				}
3802*48a54d36SAndroid Build Coastguard Worker 
3803*48a54d36SAndroid Build Coastguard Worker 				default:
3804*48a54d36SAndroid Build Coastguard Worker 					break;
3805*48a54d36SAndroid Build Coastguard Worker 			}
3806*48a54d36SAndroid Build Coastguard Worker 		}
3807*48a54d36SAndroid Build Coastguard Worker 	}
3808*48a54d36SAndroid Build Coastguard Worker 
3809*48a54d36SAndroid Build Coastguard Worker 	// Success!
3810*48a54d36SAndroid Build Coastguard Worker 
3811*48a54d36SAndroid Build Coastguard Worker 	if( outAddrs )
3812*48a54d36SAndroid Build Coastguard Worker 	{
3813*48a54d36SAndroid Build Coastguard Worker 		*outAddrs = head;
3814*48a54d36SAndroid Build Coastguard Worker 		head = NULL;
3815*48a54d36SAndroid Build Coastguard Worker 	}
3816*48a54d36SAndroid Build Coastguard Worker 	err = ERROR_SUCCESS;
3817*48a54d36SAndroid Build Coastguard Worker 
3818*48a54d36SAndroid Build Coastguard Worker exit:
3819*48a54d36SAndroid Build Coastguard Worker 	if( head )
3820*48a54d36SAndroid Build Coastguard Worker 	{
3821*48a54d36SAndroid Build Coastguard Worker 		freeifaddrs( head );
3822*48a54d36SAndroid Build Coastguard Worker 	}
3823*48a54d36SAndroid Build Coastguard Worker 	if( iaaList )
3824*48a54d36SAndroid Build Coastguard Worker 	{
3825*48a54d36SAndroid Build Coastguard Worker 		free( iaaList );
3826*48a54d36SAndroid Build Coastguard Worker 	}
3827*48a54d36SAndroid Build Coastguard Worker 	return( (int) err );
3828*48a54d36SAndroid Build Coastguard Worker }
3829*48a54d36SAndroid Build Coastguard Worker 
3830*48a54d36SAndroid Build Coastguard Worker #endif	// MDNS_WINDOWS_USE_IPV6_IF_ADDRS
3831*48a54d36SAndroid Build Coastguard Worker 
3832*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3833*48a54d36SAndroid Build Coastguard Worker //	getifaddrs_ipv4
3834*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3835*48a54d36SAndroid Build Coastguard Worker 
getifaddrs_ipv4(struct ifaddrs ** outAddrs)3836*48a54d36SAndroid Build Coastguard Worker mDNSlocal int	getifaddrs_ipv4( struct ifaddrs **outAddrs )
3837*48a54d36SAndroid Build Coastguard Worker {
3838*48a54d36SAndroid Build Coastguard Worker 	int						err;
3839*48a54d36SAndroid Build Coastguard Worker 	SOCKET					sock;
3840*48a54d36SAndroid Build Coastguard Worker 	DWORD					size;
3841*48a54d36SAndroid Build Coastguard Worker 	DWORD					actualSize;
3842*48a54d36SAndroid Build Coastguard Worker 	INTERFACE_INFO *		buffer;
3843*48a54d36SAndroid Build Coastguard Worker 	INTERFACE_INFO *		tempBuffer;
3844*48a54d36SAndroid Build Coastguard Worker 	INTERFACE_INFO *		ifInfo;
3845*48a54d36SAndroid Build Coastguard Worker 	int						n;
3846*48a54d36SAndroid Build Coastguard Worker 	int						i;
3847*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *		head;
3848*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs **		next;
3849*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *		ifa;
3850*48a54d36SAndroid Build Coastguard Worker 
3851*48a54d36SAndroid Build Coastguard Worker 	sock	= INVALID_SOCKET;
3852*48a54d36SAndroid Build Coastguard Worker 	buffer	= NULL;
3853*48a54d36SAndroid Build Coastguard Worker 	head	= NULL;
3854*48a54d36SAndroid Build Coastguard Worker 	next	= &head;
3855*48a54d36SAndroid Build Coastguard Worker 
3856*48a54d36SAndroid Build Coastguard Worker 	// Get the interface list. WSAIoctl is called with SIO_GET_INTERFACE_LIST, but since this does not provide a
3857*48a54d36SAndroid Build Coastguard Worker 	// way to determine the size of the interface list beforehand, we have to start with an initial size guess and
3858*48a54d36SAndroid Build Coastguard Worker 	// call WSAIoctl repeatedly with increasing buffer sizes until it succeeds. Limit this to 100 tries for safety.
3859*48a54d36SAndroid Build Coastguard Worker 
3860*48a54d36SAndroid Build Coastguard Worker 	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
3861*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
3862*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
3863*48a54d36SAndroid Build Coastguard Worker 
3864*48a54d36SAndroid Build Coastguard Worker 	n = 0;
3865*48a54d36SAndroid Build Coastguard Worker 	size = 16 * sizeof( INTERFACE_INFO );
3866*48a54d36SAndroid Build Coastguard Worker 	for( ;; )
3867*48a54d36SAndroid Build Coastguard Worker 	{
3868*48a54d36SAndroid Build Coastguard Worker 		tempBuffer = (INTERFACE_INFO *) realloc( buffer, size );
3869*48a54d36SAndroid Build Coastguard Worker 		require_action( tempBuffer, exit, err = WSAENOBUFS );
3870*48a54d36SAndroid Build Coastguard Worker 		buffer = tempBuffer;
3871*48a54d36SAndroid Build Coastguard Worker 
3872*48a54d36SAndroid Build Coastguard Worker 		err = WSAIoctl( sock, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, size, &actualSize, NULL, NULL );
3873*48a54d36SAndroid Build Coastguard Worker 		if( err == 0 )
3874*48a54d36SAndroid Build Coastguard Worker 		{
3875*48a54d36SAndroid Build Coastguard Worker 			break;
3876*48a54d36SAndroid Build Coastguard Worker 		}
3877*48a54d36SAndroid Build Coastguard Worker 
3878*48a54d36SAndroid Build Coastguard Worker 		++n;
3879*48a54d36SAndroid Build Coastguard Worker 		require_action( n < 100, exit, err = WSAEADDRNOTAVAIL );
3880*48a54d36SAndroid Build Coastguard Worker 
3881*48a54d36SAndroid Build Coastguard Worker 		size += ( 16 * sizeof( INTERFACE_INFO ) );
3882*48a54d36SAndroid Build Coastguard Worker 	}
3883*48a54d36SAndroid Build Coastguard Worker 	check( actualSize <= size );
3884*48a54d36SAndroid Build Coastguard Worker 	check( ( actualSize % sizeof( INTERFACE_INFO ) ) == 0 );
3885*48a54d36SAndroid Build Coastguard Worker 	n = (int)( actualSize / sizeof( INTERFACE_INFO ) );
3886*48a54d36SAndroid Build Coastguard Worker 
3887*48a54d36SAndroid Build Coastguard Worker 	// Process the raw interface list and build a linked list of IPv4 interfaces.
3888*48a54d36SAndroid Build Coastguard Worker 
3889*48a54d36SAndroid Build Coastguard Worker 	for( i = 0; i < n; ++i )
3890*48a54d36SAndroid Build Coastguard Worker 	{
3891*48a54d36SAndroid Build Coastguard Worker 		uint32_t ifIndex;
3892*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in netmask;
3893*48a54d36SAndroid Build Coastguard Worker 
3894*48a54d36SAndroid Build Coastguard Worker 		ifInfo = &buffer[ i ];
3895*48a54d36SAndroid Build Coastguard Worker 		if( ifInfo->iiAddress.Address.sa_family != AF_INET )
3896*48a54d36SAndroid Build Coastguard Worker 		{
3897*48a54d36SAndroid Build Coastguard Worker 			continue;
3898*48a54d36SAndroid Build Coastguard Worker 		}
3899*48a54d36SAndroid Build Coastguard Worker 
3900*48a54d36SAndroid Build Coastguard Worker 		// <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
3901*48a54d36SAndroid Build Coastguard Worker 		// See comment in getifaddrs_ipv6
3902*48a54d36SAndroid Build Coastguard Worker 
3903*48a54d36SAndroid Build Coastguard Worker 		ifIndex = 0;
3904*48a54d36SAndroid Build Coastguard Worker 		memset( &netmask, 0, sizeof( netmask ) );
3905*48a54d36SAndroid Build Coastguard Worker 		err = AddressToIndexAndMask( ( struct sockaddr* ) &ifInfo->iiAddress.AddressIn, &ifIndex, ( struct sockaddr* ) &netmask );
3906*48a54d36SAndroid Build Coastguard Worker 
3907*48a54d36SAndroid Build Coastguard Worker 		if ( err )
3908*48a54d36SAndroid Build Coastguard Worker 		{
3909*48a54d36SAndroid Build Coastguard Worker 			continue;
3910*48a54d36SAndroid Build Coastguard Worker 		}
3911*48a54d36SAndroid Build Coastguard Worker 
3912*48a54d36SAndroid Build Coastguard Worker 		ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
3913*48a54d36SAndroid Build Coastguard Worker 		require_action( ifa, exit, err = WSAENOBUFS );
3914*48a54d36SAndroid Build Coastguard Worker 
3915*48a54d36SAndroid Build Coastguard Worker 		*next = ifa;
3916*48a54d36SAndroid Build Coastguard Worker 		next  = &ifa->ifa_next;
3917*48a54d36SAndroid Build Coastguard Worker 
3918*48a54d36SAndroid Build Coastguard Worker 		// Get the name.
3919*48a54d36SAndroid Build Coastguard Worker 
3920*48a54d36SAndroid Build Coastguard Worker 		ifa->ifa_name = (char *) malloc( 16 );
3921*48a54d36SAndroid Build Coastguard Worker 		require_action( ifa->ifa_name, exit, err = WSAENOBUFS );
3922*48a54d36SAndroid Build Coastguard Worker 		sprintf( ifa->ifa_name, "%d", i + 1 );
3923*48a54d36SAndroid Build Coastguard Worker 
3924*48a54d36SAndroid Build Coastguard Worker 		// Get interface flags.
3925*48a54d36SAndroid Build Coastguard Worker 
3926*48a54d36SAndroid Build Coastguard Worker 		ifa->ifa_flags = (u_int) ifInfo->iiFlags;
3927*48a54d36SAndroid Build Coastguard Worker 
3928*48a54d36SAndroid Build Coastguard Worker 		// Get addresses.
3929*48a54d36SAndroid Build Coastguard Worker 
3930*48a54d36SAndroid Build Coastguard Worker 		if ( ifInfo->iiAddress.Address.sa_family == AF_INET )
3931*48a54d36SAndroid Build Coastguard Worker 		{
3932*48a54d36SAndroid Build Coastguard Worker 			struct sockaddr_in *		sa4;
3933*48a54d36SAndroid Build Coastguard Worker 
3934*48a54d36SAndroid Build Coastguard Worker 			sa4 = &ifInfo->iiAddress.AddressIn;
3935*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_addr = (struct sockaddr *) calloc( 1, sizeof( *sa4 ) );
3936*48a54d36SAndroid Build Coastguard Worker 			require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
3937*48a54d36SAndroid Build Coastguard Worker 			memcpy( ifa->ifa_addr, sa4, sizeof( *sa4 ) );
3938*48a54d36SAndroid Build Coastguard Worker 
3939*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_netmask = (struct sockaddr*) calloc(1, sizeof( *sa4 ) );
3940*48a54d36SAndroid Build Coastguard Worker 			require_action( ifa->ifa_netmask, exit, err = WSAENOBUFS );
3941*48a54d36SAndroid Build Coastguard Worker 
3942*48a54d36SAndroid Build Coastguard Worker 			// <rdar://problem/4076478> Service won't start on Win2K. The address
3943*48a54d36SAndroid Build Coastguard Worker 			// family field was not being initialized.
3944*48a54d36SAndroid Build Coastguard Worker 
3945*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_netmask->sa_family = AF_INET;
3946*48a54d36SAndroid Build Coastguard Worker 			( ( struct sockaddr_in* ) ifa->ifa_netmask )->sin_addr = netmask.sin_addr;
3947*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_extra.index = ifIndex;
3948*48a54d36SAndroid Build Coastguard Worker 		}
3949*48a54d36SAndroid Build Coastguard Worker 		else
3950*48a54d36SAndroid Build Coastguard Worker 		{
3951*48a54d36SAndroid Build Coastguard Worker 			// Emulate an interface index.
3952*48a54d36SAndroid Build Coastguard Worker 
3953*48a54d36SAndroid Build Coastguard Worker 			ifa->ifa_extra.index = (uint32_t)( i + 1 );
3954*48a54d36SAndroid Build Coastguard Worker 		}
3955*48a54d36SAndroid Build Coastguard Worker 	}
3956*48a54d36SAndroid Build Coastguard Worker 
3957*48a54d36SAndroid Build Coastguard Worker 	// Success!
3958*48a54d36SAndroid Build Coastguard Worker 
3959*48a54d36SAndroid Build Coastguard Worker 	if( outAddrs )
3960*48a54d36SAndroid Build Coastguard Worker 	{
3961*48a54d36SAndroid Build Coastguard Worker 		*outAddrs = head;
3962*48a54d36SAndroid Build Coastguard Worker 		head = NULL;
3963*48a54d36SAndroid Build Coastguard Worker 	}
3964*48a54d36SAndroid Build Coastguard Worker 	err = 0;
3965*48a54d36SAndroid Build Coastguard Worker 
3966*48a54d36SAndroid Build Coastguard Worker exit:
3967*48a54d36SAndroid Build Coastguard Worker 
3968*48a54d36SAndroid Build Coastguard Worker 	if( head )
3969*48a54d36SAndroid Build Coastguard Worker 	{
3970*48a54d36SAndroid Build Coastguard Worker 		freeifaddrs( head );
3971*48a54d36SAndroid Build Coastguard Worker 	}
3972*48a54d36SAndroid Build Coastguard Worker 	if( buffer )
3973*48a54d36SAndroid Build Coastguard Worker 	{
3974*48a54d36SAndroid Build Coastguard Worker 		free( buffer );
3975*48a54d36SAndroid Build Coastguard Worker 	}
3976*48a54d36SAndroid Build Coastguard Worker 	if( sock != INVALID_SOCKET )
3977*48a54d36SAndroid Build Coastguard Worker 	{
3978*48a54d36SAndroid Build Coastguard Worker 		closesocket( sock );
3979*48a54d36SAndroid Build Coastguard Worker 	}
3980*48a54d36SAndroid Build Coastguard Worker 	return( err );
3981*48a54d36SAndroid Build Coastguard Worker }
3982*48a54d36SAndroid Build Coastguard Worker 
3983*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3984*48a54d36SAndroid Build Coastguard Worker //	freeifaddrs
3985*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
3986*48a54d36SAndroid Build Coastguard Worker 
freeifaddrs(struct ifaddrs * inIFAs)3987*48a54d36SAndroid Build Coastguard Worker mDNSlocal void	freeifaddrs( struct ifaddrs *inIFAs )
3988*48a54d36SAndroid Build Coastguard Worker {
3989*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *		p;
3990*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *		q;
3991*48a54d36SAndroid Build Coastguard Worker 
3992*48a54d36SAndroid Build Coastguard Worker 	// Free each piece of the structure. Set to null after freeing to handle macro-aliased fields.
3993*48a54d36SAndroid Build Coastguard Worker 
3994*48a54d36SAndroid Build Coastguard Worker 	for( p = inIFAs; p; p = q )
3995*48a54d36SAndroid Build Coastguard Worker 	{
3996*48a54d36SAndroid Build Coastguard Worker 		q = p->ifa_next;
3997*48a54d36SAndroid Build Coastguard Worker 
3998*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_name )
3999*48a54d36SAndroid Build Coastguard Worker 		{
4000*48a54d36SAndroid Build Coastguard Worker 			free( p->ifa_name );
4001*48a54d36SAndroid Build Coastguard Worker 			p->ifa_name = NULL;
4002*48a54d36SAndroid Build Coastguard Worker 		}
4003*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_addr )
4004*48a54d36SAndroid Build Coastguard Worker 		{
4005*48a54d36SAndroid Build Coastguard Worker 			free( p->ifa_addr );
4006*48a54d36SAndroid Build Coastguard Worker 			p->ifa_addr = NULL;
4007*48a54d36SAndroid Build Coastguard Worker 		}
4008*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_netmask )
4009*48a54d36SAndroid Build Coastguard Worker 		{
4010*48a54d36SAndroid Build Coastguard Worker 			free( p->ifa_netmask );
4011*48a54d36SAndroid Build Coastguard Worker 			p->ifa_netmask = NULL;
4012*48a54d36SAndroid Build Coastguard Worker 		}
4013*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_broadaddr )
4014*48a54d36SAndroid Build Coastguard Worker 		{
4015*48a54d36SAndroid Build Coastguard Worker 			free( p->ifa_broadaddr );
4016*48a54d36SAndroid Build Coastguard Worker 			p->ifa_broadaddr = NULL;
4017*48a54d36SAndroid Build Coastguard Worker 		}
4018*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_dstaddr )
4019*48a54d36SAndroid Build Coastguard Worker 		{
4020*48a54d36SAndroid Build Coastguard Worker 			free( p->ifa_dstaddr );
4021*48a54d36SAndroid Build Coastguard Worker 			p->ifa_dstaddr = NULL;
4022*48a54d36SAndroid Build Coastguard Worker 		}
4023*48a54d36SAndroid Build Coastguard Worker 		if( p->ifa_data )
4024*48a54d36SAndroid Build Coastguard Worker 		{
4025*48a54d36SAndroid Build Coastguard Worker 			free( p->ifa_data );
4026*48a54d36SAndroid Build Coastguard Worker 			p->ifa_data = NULL;
4027*48a54d36SAndroid Build Coastguard Worker 		}
4028*48a54d36SAndroid Build Coastguard Worker 		free( p );
4029*48a54d36SAndroid Build Coastguard Worker 	}
4030*48a54d36SAndroid Build Coastguard Worker }
4031*48a54d36SAndroid Build Coastguard Worker 
4032*48a54d36SAndroid Build Coastguard Worker 
4033*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4034*48a54d36SAndroid Build Coastguard Worker //	GetPrimaryInterface
4035*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4036*48a54d36SAndroid Build Coastguard Worker 
4037*48a54d36SAndroid Build Coastguard Worker mDNSlocal DWORD
GetPrimaryInterface()4038*48a54d36SAndroid Build Coastguard Worker GetPrimaryInterface()
4039*48a54d36SAndroid Build Coastguard Worker {
4040*48a54d36SAndroid Build Coastguard Worker 	PMIB_IPFORWARDTABLE	pIpForwardTable	= NULL;
4041*48a54d36SAndroid Build Coastguard Worker 	DWORD				dwSize			= 0;
4042*48a54d36SAndroid Build Coastguard Worker 	BOOL				bOrder			= FALSE;
4043*48a54d36SAndroid Build Coastguard Worker 	OSStatus			err;
4044*48a54d36SAndroid Build Coastguard Worker 	DWORD				index			= 0;
4045*48a54d36SAndroid Build Coastguard Worker 	DWORD				metric			= 0;
4046*48a54d36SAndroid Build Coastguard Worker 	unsigned long int	i;
4047*48a54d36SAndroid Build Coastguard Worker 
4048*48a54d36SAndroid Build Coastguard Worker 	// Find out how big our buffer needs to be.
4049*48a54d36SAndroid Build Coastguard Worker 
4050*48a54d36SAndroid Build Coastguard Worker 	err = GetIpForwardTable(NULL, &dwSize, bOrder);
4051*48a54d36SAndroid Build Coastguard Worker 	require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
4052*48a54d36SAndroid Build Coastguard Worker 
4053*48a54d36SAndroid Build Coastguard Worker 	// Allocate the memory for the table
4054*48a54d36SAndroid Build Coastguard Worker 
4055*48a54d36SAndroid Build Coastguard Worker 	pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
4056*48a54d36SAndroid Build Coastguard Worker 	require_action( pIpForwardTable, exit, err = kNoMemoryErr );
4057*48a54d36SAndroid Build Coastguard Worker 
4058*48a54d36SAndroid Build Coastguard Worker 	// Now get the table.
4059*48a54d36SAndroid Build Coastguard Worker 
4060*48a54d36SAndroid Build Coastguard Worker 	err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
4061*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4062*48a54d36SAndroid Build Coastguard Worker 
4063*48a54d36SAndroid Build Coastguard Worker 
4064*48a54d36SAndroid Build Coastguard Worker 	// Search for the row in the table we want.
4065*48a54d36SAndroid Build Coastguard Worker 
4066*48a54d36SAndroid Build Coastguard Worker 	for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
4067*48a54d36SAndroid Build Coastguard Worker 	{
4068*48a54d36SAndroid Build Coastguard Worker 		// Look for a default route
4069*48a54d36SAndroid Build Coastguard Worker 
4070*48a54d36SAndroid Build Coastguard Worker 		if ( pIpForwardTable->table[i].dwForwardDest == 0 )
4071*48a54d36SAndroid Build Coastguard Worker 		{
4072*48a54d36SAndroid Build Coastguard Worker 			if ( index && ( pIpForwardTable->table[i].dwForwardMetric1 >= metric ) )
4073*48a54d36SAndroid Build Coastguard Worker 			{
4074*48a54d36SAndroid Build Coastguard Worker 				continue;
4075*48a54d36SAndroid Build Coastguard Worker 			}
4076*48a54d36SAndroid Build Coastguard Worker 
4077*48a54d36SAndroid Build Coastguard Worker 			index	= pIpForwardTable->table[i].dwForwardIfIndex;
4078*48a54d36SAndroid Build Coastguard Worker 			metric	= pIpForwardTable->table[i].dwForwardMetric1;
4079*48a54d36SAndroid Build Coastguard Worker 		}
4080*48a54d36SAndroid Build Coastguard Worker 	}
4081*48a54d36SAndroid Build Coastguard Worker 
4082*48a54d36SAndroid Build Coastguard Worker exit:
4083*48a54d36SAndroid Build Coastguard Worker 
4084*48a54d36SAndroid Build Coastguard Worker 	if ( pIpForwardTable != NULL )
4085*48a54d36SAndroid Build Coastguard Worker 	{
4086*48a54d36SAndroid Build Coastguard Worker 		free( pIpForwardTable );
4087*48a54d36SAndroid Build Coastguard Worker 	}
4088*48a54d36SAndroid Build Coastguard Worker 
4089*48a54d36SAndroid Build Coastguard Worker 	return index;
4090*48a54d36SAndroid Build Coastguard Worker }
4091*48a54d36SAndroid Build Coastguard Worker 
4092*48a54d36SAndroid Build Coastguard Worker 
4093*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4094*48a54d36SAndroid Build Coastguard Worker //	AddressToIndexAndMask
4095*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4096*48a54d36SAndroid Build Coastguard Worker 
4097*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus
AddressToIndexAndMask(struct sockaddr * addr,uint32_t * ifIndex,struct sockaddr * mask)4098*48a54d36SAndroid Build Coastguard Worker AddressToIndexAndMask( struct sockaddr * addr, uint32_t * ifIndex, struct sockaddr * mask  )
4099*48a54d36SAndroid Build Coastguard Worker {
4100*48a54d36SAndroid Build Coastguard Worker 	// Before calling AddIPAddress we use GetIpAddrTable to get
4101*48a54d36SAndroid Build Coastguard Worker 	// an adapter to which we can add the IP.
4102*48a54d36SAndroid Build Coastguard Worker 
4103*48a54d36SAndroid Build Coastguard Worker 	PMIB_IPADDRTABLE	pIPAddrTable	= NULL;
4104*48a54d36SAndroid Build Coastguard Worker 	DWORD				dwSize			= 0;
4105*48a54d36SAndroid Build Coastguard Worker 	mStatus				err				= mStatus_UnknownErr;
4106*48a54d36SAndroid Build Coastguard Worker 	DWORD				i;
4107*48a54d36SAndroid Build Coastguard Worker 
4108*48a54d36SAndroid Build Coastguard Worker 	// For now, this is only for IPv4 addresses.  That is why we can safely cast
4109*48a54d36SAndroid Build Coastguard Worker 	// addr's to sockaddr_in.
4110*48a54d36SAndroid Build Coastguard Worker 
4111*48a54d36SAndroid Build Coastguard Worker 	require_action( addr->sa_family == AF_INET, exit, err = mStatus_UnknownErr );
4112*48a54d36SAndroid Build Coastguard Worker 
4113*48a54d36SAndroid Build Coastguard Worker 	// Make an initial call to GetIpAddrTable to get the
4114*48a54d36SAndroid Build Coastguard Worker 	// necessary size into the dwSize variable
4115*48a54d36SAndroid Build Coastguard Worker 
4116*48a54d36SAndroid Build Coastguard Worker 	for ( i = 0; i < 100; i++ )
4117*48a54d36SAndroid Build Coastguard Worker 	{
4118*48a54d36SAndroid Build Coastguard Worker 		err = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
4119*48a54d36SAndroid Build Coastguard Worker 
4120*48a54d36SAndroid Build Coastguard Worker 		if ( err != ERROR_INSUFFICIENT_BUFFER )
4121*48a54d36SAndroid Build Coastguard Worker 		{
4122*48a54d36SAndroid Build Coastguard Worker 			break;
4123*48a54d36SAndroid Build Coastguard Worker 		}
4124*48a54d36SAndroid Build Coastguard Worker 
4125*48a54d36SAndroid Build Coastguard Worker 		pIPAddrTable = (MIB_IPADDRTABLE *) realloc( pIPAddrTable, dwSize );
4126*48a54d36SAndroid Build Coastguard Worker 		require_action( pIPAddrTable, exit, err = WSAENOBUFS );
4127*48a54d36SAndroid Build Coastguard Worker 	}
4128*48a54d36SAndroid Build Coastguard Worker 
4129*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4130*48a54d36SAndroid Build Coastguard Worker 	err = mStatus_UnknownErr;
4131*48a54d36SAndroid Build Coastguard Worker 
4132*48a54d36SAndroid Build Coastguard Worker 	for ( i = 0; i < pIPAddrTable->dwNumEntries; i++ )
4133*48a54d36SAndroid Build Coastguard Worker 	{
4134*48a54d36SAndroid Build Coastguard Worker 		if ( ( ( struct sockaddr_in* ) addr )->sin_addr.s_addr == pIPAddrTable->table[i].dwAddr )
4135*48a54d36SAndroid Build Coastguard Worker 		{
4136*48a54d36SAndroid Build Coastguard Worker 			*ifIndex											= pIPAddrTable->table[i].dwIndex;
4137*48a54d36SAndroid Build Coastguard Worker 			( ( struct sockaddr_in*) mask )->sin_addr.s_addr	= pIPAddrTable->table[i].dwMask;
4138*48a54d36SAndroid Build Coastguard Worker 			err													= mStatus_NoError;
4139*48a54d36SAndroid Build Coastguard Worker 			break;
4140*48a54d36SAndroid Build Coastguard Worker 		}
4141*48a54d36SAndroid Build Coastguard Worker 	}
4142*48a54d36SAndroid Build Coastguard Worker 
4143*48a54d36SAndroid Build Coastguard Worker exit:
4144*48a54d36SAndroid Build Coastguard Worker 
4145*48a54d36SAndroid Build Coastguard Worker 	if ( pIPAddrTable )
4146*48a54d36SAndroid Build Coastguard Worker 	{
4147*48a54d36SAndroid Build Coastguard Worker 		free( pIPAddrTable );
4148*48a54d36SAndroid Build Coastguard Worker 	}
4149*48a54d36SAndroid Build Coastguard Worker 
4150*48a54d36SAndroid Build Coastguard Worker 	return err;
4151*48a54d36SAndroid Build Coastguard Worker }
4152*48a54d36SAndroid Build Coastguard Worker 
4153*48a54d36SAndroid Build Coastguard Worker 
4154*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4155*48a54d36SAndroid Build Coastguard Worker //	CanReceiveUnicast
4156*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4157*48a54d36SAndroid Build Coastguard Worker 
CanReceiveUnicast(void)4158*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNSBool	CanReceiveUnicast( void )
4159*48a54d36SAndroid Build Coastguard Worker {
4160*48a54d36SAndroid Build Coastguard Worker 	mDNSBool				ok;
4161*48a54d36SAndroid Build Coastguard Worker 	SocketRef				sock;
4162*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in		addr;
4163*48a54d36SAndroid Build Coastguard Worker 
4164*48a54d36SAndroid Build Coastguard Worker 	// Try to bind to the port without the SO_REUSEADDR option to test if someone else has already bound to it.
4165*48a54d36SAndroid Build Coastguard Worker 
4166*48a54d36SAndroid Build Coastguard Worker 	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
4167*48a54d36SAndroid Build Coastguard Worker 	check_translated_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
4168*48a54d36SAndroid Build Coastguard Worker 	ok = IsValidSocket( sock );
4169*48a54d36SAndroid Build Coastguard Worker 	if( ok )
4170*48a54d36SAndroid Build Coastguard Worker 	{
4171*48a54d36SAndroid Build Coastguard Worker 		mDNSPlatformMemZero( &addr, sizeof( addr ) );
4172*48a54d36SAndroid Build Coastguard Worker 		addr.sin_family			= AF_INET;
4173*48a54d36SAndroid Build Coastguard Worker 		addr.sin_port			= MulticastDNSPort.NotAnInteger;
4174*48a54d36SAndroid Build Coastguard Worker 		addr.sin_addr.s_addr	= htonl( INADDR_ANY );
4175*48a54d36SAndroid Build Coastguard Worker 
4176*48a54d36SAndroid Build Coastguard Worker 		ok = ( bind( sock, (struct sockaddr *) &addr, sizeof( addr ) ) == 0 );
4177*48a54d36SAndroid Build Coastguard Worker 		close_compat( sock );
4178*48a54d36SAndroid Build Coastguard Worker 	}
4179*48a54d36SAndroid Build Coastguard Worker 
4180*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelInfo, DEBUG_NAME "Unicast UDP responses %s\n", ok ? "okay" : "*not allowed*" );
4181*48a54d36SAndroid Build Coastguard Worker 	return( ok );
4182*48a54d36SAndroid Build Coastguard Worker }
4183*48a54d36SAndroid Build Coastguard Worker 
4184*48a54d36SAndroid Build Coastguard Worker 
4185*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4186*48a54d36SAndroid Build Coastguard Worker //	IsPointToPoint
4187*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4188*48a54d36SAndroid Build Coastguard Worker 
IsPointToPoint(IP_ADAPTER_UNICAST_ADDRESS * addr)4189*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNSBool IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr )
4190*48a54d36SAndroid Build Coastguard Worker {
4191*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs	*	addrs	=	NULL;
4192*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs	*	p		=	NULL;
4193*48a54d36SAndroid Build Coastguard Worker 	OSStatus			err;
4194*48a54d36SAndroid Build Coastguard Worker 	mDNSBool			ret		=	mDNSfalse;
4195*48a54d36SAndroid Build Coastguard Worker 
4196*48a54d36SAndroid Build Coastguard Worker 	// For now, only works for IPv4 interfaces
4197*48a54d36SAndroid Build Coastguard Worker 
4198*48a54d36SAndroid Build Coastguard Worker 	if ( addr->Address.lpSockaddr->sa_family == AF_INET )
4199*48a54d36SAndroid Build Coastguard Worker 	{
4200*48a54d36SAndroid Build Coastguard Worker 		// The getifaddrs_ipv4 call will give us correct information regarding IFF_POINTTOPOINT flags.
4201*48a54d36SAndroid Build Coastguard Worker 
4202*48a54d36SAndroid Build Coastguard Worker 		err = getifaddrs_ipv4( &addrs );
4203*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
4204*48a54d36SAndroid Build Coastguard Worker 
4205*48a54d36SAndroid Build Coastguard Worker 		for ( p = addrs; p; p = p->ifa_next )
4206*48a54d36SAndroid Build Coastguard Worker 		{
4207*48a54d36SAndroid Build Coastguard Worker 			if ( ( addr->Address.lpSockaddr->sa_family == p->ifa_addr->sa_family ) &&
4208*48a54d36SAndroid Build Coastguard Worker 			     ( ( ( struct sockaddr_in* ) addr->Address.lpSockaddr )->sin_addr.s_addr == ( ( struct sockaddr_in* ) p->ifa_addr )->sin_addr.s_addr ) )
4209*48a54d36SAndroid Build Coastguard Worker 			{
4210*48a54d36SAndroid Build Coastguard Worker 				ret = ( p->ifa_flags & IFF_POINTTOPOINT ) ? mDNStrue : mDNSfalse;
4211*48a54d36SAndroid Build Coastguard Worker 				break;
4212*48a54d36SAndroid Build Coastguard Worker 			}
4213*48a54d36SAndroid Build Coastguard Worker 		}
4214*48a54d36SAndroid Build Coastguard Worker 	}
4215*48a54d36SAndroid Build Coastguard Worker 
4216*48a54d36SAndroid Build Coastguard Worker exit:
4217*48a54d36SAndroid Build Coastguard Worker 
4218*48a54d36SAndroid Build Coastguard Worker 	if ( addrs )
4219*48a54d36SAndroid Build Coastguard Worker 	{
4220*48a54d36SAndroid Build Coastguard Worker 		freeifaddrs( addrs );
4221*48a54d36SAndroid Build Coastguard Worker 	}
4222*48a54d36SAndroid Build Coastguard Worker 
4223*48a54d36SAndroid Build Coastguard Worker 	return ret;
4224*48a54d36SAndroid Build Coastguard Worker }
4225*48a54d36SAndroid Build Coastguard Worker 
4226*48a54d36SAndroid Build Coastguard Worker 
4227*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4228*48a54d36SAndroid Build Coastguard Worker //	GetWindowsVersionString
4229*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4230*48a54d36SAndroid Build Coastguard Worker 
GetWindowsVersionString(char * inBuffer,size_t inBufferSize)4231*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus	GetWindowsVersionString( char *inBuffer, size_t inBufferSize )
4232*48a54d36SAndroid Build Coastguard Worker {
4233*48a54d36SAndroid Build Coastguard Worker #if( !defined( VER_PLATFORM_WIN32_CE ) )
4234*48a54d36SAndroid Build Coastguard Worker 	#define VER_PLATFORM_WIN32_CE		3
4235*48a54d36SAndroid Build Coastguard Worker #endif
4236*48a54d36SAndroid Build Coastguard Worker 
4237*48a54d36SAndroid Build Coastguard Worker 	OSStatus				err;
4238*48a54d36SAndroid Build Coastguard Worker 	OSVERSIONINFO			osInfo;
4239*48a54d36SAndroid Build Coastguard Worker 	BOOL					ok;
4240*48a54d36SAndroid Build Coastguard Worker 	const char *			versionString;
4241*48a54d36SAndroid Build Coastguard Worker 	DWORD					platformID;
4242*48a54d36SAndroid Build Coastguard Worker 	DWORD					majorVersion;
4243*48a54d36SAndroid Build Coastguard Worker 	DWORD					minorVersion;
4244*48a54d36SAndroid Build Coastguard Worker 	DWORD					buildNumber;
4245*48a54d36SAndroid Build Coastguard Worker 
4246*48a54d36SAndroid Build Coastguard Worker 	versionString = "unknown Windows version";
4247*48a54d36SAndroid Build Coastguard Worker 
4248*48a54d36SAndroid Build Coastguard Worker 	osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
4249*48a54d36SAndroid Build Coastguard Worker 	ok = GetVersionEx( &osInfo );
4250*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
4251*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4252*48a54d36SAndroid Build Coastguard Worker 
4253*48a54d36SAndroid Build Coastguard Worker 	platformID		= osInfo.dwPlatformId;
4254*48a54d36SAndroid Build Coastguard Worker 	majorVersion	= osInfo.dwMajorVersion;
4255*48a54d36SAndroid Build Coastguard Worker 	minorVersion	= osInfo.dwMinorVersion;
4256*48a54d36SAndroid Build Coastguard Worker 	buildNumber		= osInfo.dwBuildNumber & 0xFFFF;
4257*48a54d36SAndroid Build Coastguard Worker 
4258*48a54d36SAndroid Build Coastguard Worker 	if( ( platformID == VER_PLATFORM_WIN32_WINDOWS ) && ( majorVersion == 4 ) )
4259*48a54d36SAndroid Build Coastguard Worker 	{
4260*48a54d36SAndroid Build Coastguard Worker 		if( ( minorVersion < 10 ) && ( buildNumber == 950 ) )
4261*48a54d36SAndroid Build Coastguard Worker 		{
4262*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 95";
4263*48a54d36SAndroid Build Coastguard Worker 		}
4264*48a54d36SAndroid Build Coastguard Worker 		else if( ( minorVersion < 10 ) && ( ( buildNumber > 950 ) && ( buildNumber <= 1080 ) ) )
4265*48a54d36SAndroid Build Coastguard Worker 		{
4266*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 95 SP1";
4267*48a54d36SAndroid Build Coastguard Worker 		}
4268*48a54d36SAndroid Build Coastguard Worker 		else if( ( minorVersion < 10 ) && ( buildNumber > 1080 ) )
4269*48a54d36SAndroid Build Coastguard Worker 		{
4270*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 95 OSR2";
4271*48a54d36SAndroid Build Coastguard Worker 		}
4272*48a54d36SAndroid Build Coastguard Worker 		else if( ( minorVersion == 10 ) && ( buildNumber == 1998 ) )
4273*48a54d36SAndroid Build Coastguard Worker 		{
4274*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 98";
4275*48a54d36SAndroid Build Coastguard Worker 		}
4276*48a54d36SAndroid Build Coastguard Worker 		else if( ( minorVersion == 10 ) && ( ( buildNumber > 1998 ) && ( buildNumber < 2183 ) ) )
4277*48a54d36SAndroid Build Coastguard Worker 		{
4278*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 98 SP1";
4279*48a54d36SAndroid Build Coastguard Worker 		}
4280*48a54d36SAndroid Build Coastguard Worker 		else if( ( minorVersion == 10 ) && ( buildNumber >= 2183 ) )
4281*48a54d36SAndroid Build Coastguard Worker 		{
4282*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 98 SE";
4283*48a54d36SAndroid Build Coastguard Worker 		}
4284*48a54d36SAndroid Build Coastguard Worker 		else if( minorVersion == 90 )
4285*48a54d36SAndroid Build Coastguard Worker 		{
4286*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows ME";
4287*48a54d36SAndroid Build Coastguard Worker 		}
4288*48a54d36SAndroid Build Coastguard Worker 	}
4289*48a54d36SAndroid Build Coastguard Worker 	else if( platformID == VER_PLATFORM_WIN32_NT )
4290*48a54d36SAndroid Build Coastguard Worker 	{
4291*48a54d36SAndroid Build Coastguard Worker 		if( ( majorVersion == 3 ) && ( minorVersion == 51 ) )
4292*48a54d36SAndroid Build Coastguard Worker 		{
4293*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows NT 3.51";
4294*48a54d36SAndroid Build Coastguard Worker 		}
4295*48a54d36SAndroid Build Coastguard Worker 		else if( ( majorVersion == 4 ) && ( minorVersion == 0 ) )
4296*48a54d36SAndroid Build Coastguard Worker 		{
4297*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows NT 4";
4298*48a54d36SAndroid Build Coastguard Worker 		}
4299*48a54d36SAndroid Build Coastguard Worker 		else if( ( majorVersion == 5 ) && ( minorVersion == 0 ) )
4300*48a54d36SAndroid Build Coastguard Worker 		{
4301*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows 2000";
4302*48a54d36SAndroid Build Coastguard Worker 		}
4303*48a54d36SAndroid Build Coastguard Worker 		else if( ( majorVersion == 5 ) && ( minorVersion == 1 ) )
4304*48a54d36SAndroid Build Coastguard Worker 		{
4305*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows XP";
4306*48a54d36SAndroid Build Coastguard Worker 		}
4307*48a54d36SAndroid Build Coastguard Worker 		else if( ( majorVersion == 5 ) && ( minorVersion == 2 ) )
4308*48a54d36SAndroid Build Coastguard Worker 		{
4309*48a54d36SAndroid Build Coastguard Worker 			versionString	= "Windows Server 2003";
4310*48a54d36SAndroid Build Coastguard Worker 		}
4311*48a54d36SAndroid Build Coastguard Worker 	}
4312*48a54d36SAndroid Build Coastguard Worker 	else if( platformID == VER_PLATFORM_WIN32_CE )
4313*48a54d36SAndroid Build Coastguard Worker 	{
4314*48a54d36SAndroid Build Coastguard Worker 		versionString		= "Windows CE";
4315*48a54d36SAndroid Build Coastguard Worker 	}
4316*48a54d36SAndroid Build Coastguard Worker 
4317*48a54d36SAndroid Build Coastguard Worker exit:
4318*48a54d36SAndroid Build Coastguard Worker 	if( inBuffer && ( inBufferSize > 0 ) )
4319*48a54d36SAndroid Build Coastguard Worker 	{
4320*48a54d36SAndroid Build Coastguard Worker 		inBufferSize -= 1;
4321*48a54d36SAndroid Build Coastguard Worker 		strncpy( inBuffer, versionString, inBufferSize );
4322*48a54d36SAndroid Build Coastguard Worker 		inBuffer[ inBufferSize ] = '\0';
4323*48a54d36SAndroid Build Coastguard Worker 	}
4324*48a54d36SAndroid Build Coastguard Worker 	return( err );
4325*48a54d36SAndroid Build Coastguard Worker }
4326*48a54d36SAndroid Build Coastguard Worker 
4327*48a54d36SAndroid Build Coastguard Worker 
4328*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4329*48a54d36SAndroid Build Coastguard Worker //	RegQueryString
4330*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4331*48a54d36SAndroid Build Coastguard Worker 
4332*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus
RegQueryString(HKEY key,LPCSTR valueName,LPSTR * string,DWORD * stringLen,DWORD * enabled)4333*48a54d36SAndroid Build Coastguard Worker RegQueryString( HKEY key, LPCSTR valueName, LPSTR * string, DWORD * stringLen, DWORD * enabled )
4334*48a54d36SAndroid Build Coastguard Worker {
4335*48a54d36SAndroid Build Coastguard Worker 	DWORD	type;
4336*48a54d36SAndroid Build Coastguard Worker 	int		i;
4337*48a54d36SAndroid Build Coastguard Worker 	mStatus err;
4338*48a54d36SAndroid Build Coastguard Worker 
4339*48a54d36SAndroid Build Coastguard Worker 	*stringLen	= MAX_ESCAPED_DOMAIN_NAME;
4340*48a54d36SAndroid Build Coastguard Worker 	*string		= NULL;
4341*48a54d36SAndroid Build Coastguard Worker 	i			= 0;
4342*48a54d36SAndroid Build Coastguard Worker 
4343*48a54d36SAndroid Build Coastguard Worker 	do
4344*48a54d36SAndroid Build Coastguard Worker 	{
4345*48a54d36SAndroid Build Coastguard Worker 		if ( *string )
4346*48a54d36SAndroid Build Coastguard Worker 		{
4347*48a54d36SAndroid Build Coastguard Worker 			free( *string );
4348*48a54d36SAndroid Build Coastguard Worker 		}
4349*48a54d36SAndroid Build Coastguard Worker 
4350*48a54d36SAndroid Build Coastguard Worker 		*string = (char*) malloc( *stringLen );
4351*48a54d36SAndroid Build Coastguard Worker 		require_action( *string, exit, err = mStatus_NoMemoryErr );
4352*48a54d36SAndroid Build Coastguard Worker 
4353*48a54d36SAndroid Build Coastguard Worker 		err = RegQueryValueExA( key, valueName, 0, &type, (LPBYTE) *string, stringLen );
4354*48a54d36SAndroid Build Coastguard Worker 
4355*48a54d36SAndroid Build Coastguard Worker 		i++;
4356*48a54d36SAndroid Build Coastguard Worker 	}
4357*48a54d36SAndroid Build Coastguard Worker 	while ( ( err == ERROR_MORE_DATA ) && ( i < 100 ) );
4358*48a54d36SAndroid Build Coastguard Worker 
4359*48a54d36SAndroid Build Coastguard Worker 	require_noerr_quiet( err, exit );
4360*48a54d36SAndroid Build Coastguard Worker 
4361*48a54d36SAndroid Build Coastguard Worker 	if ( enabled )
4362*48a54d36SAndroid Build Coastguard Worker 	{
4363*48a54d36SAndroid Build Coastguard Worker 		DWORD dwSize = sizeof( DWORD );
4364*48a54d36SAndroid Build Coastguard Worker 
4365*48a54d36SAndroid Build Coastguard Worker 		err = RegQueryValueEx( key, TEXT("Enabled"), NULL, NULL, (LPBYTE) enabled, &dwSize );
4366*48a54d36SAndroid Build Coastguard Worker 		check_noerr( err );
4367*48a54d36SAndroid Build Coastguard Worker 
4368*48a54d36SAndroid Build Coastguard Worker 		err = kNoErr;
4369*48a54d36SAndroid Build Coastguard Worker 	}
4370*48a54d36SAndroid Build Coastguard Worker 
4371*48a54d36SAndroid Build Coastguard Worker exit:
4372*48a54d36SAndroid Build Coastguard Worker 
4373*48a54d36SAndroid Build Coastguard Worker 	return err;
4374*48a54d36SAndroid Build Coastguard Worker }
4375*48a54d36SAndroid Build Coastguard Worker 
4376*48a54d36SAndroid Build Coastguard Worker 
4377*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4378*48a54d36SAndroid Build Coastguard Worker //	StringToAddress
4379*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4380*48a54d36SAndroid Build Coastguard Worker 
StringToAddress(mDNSAddr * ip,LPSTR string)4381*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus StringToAddress( mDNSAddr * ip, LPSTR string )
4382*48a54d36SAndroid Build Coastguard Worker {
4383*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in6 sa6;
4384*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in	sa4;
4385*48a54d36SAndroid Build Coastguard Worker 	INT					dwSize;
4386*48a54d36SAndroid Build Coastguard Worker 	mStatus				err;
4387*48a54d36SAndroid Build Coastguard Worker 
4388*48a54d36SAndroid Build Coastguard Worker 	sa6.sin6_family	= AF_INET6;
4389*48a54d36SAndroid Build Coastguard Worker 	dwSize			= sizeof( sa6 );
4390*48a54d36SAndroid Build Coastguard Worker 
4391*48a54d36SAndroid Build Coastguard Worker 	err = WSAStringToAddressA( string, AF_INET6, NULL, (struct sockaddr*) &sa6, &dwSize );
4392*48a54d36SAndroid Build Coastguard Worker 
4393*48a54d36SAndroid Build Coastguard Worker 	if ( err == mStatus_NoError )
4394*48a54d36SAndroid Build Coastguard Worker 	{
4395*48a54d36SAndroid Build Coastguard Worker 		err = SetupAddr( ip, (struct sockaddr*) &sa6 );
4396*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
4397*48a54d36SAndroid Build Coastguard Worker 	}
4398*48a54d36SAndroid Build Coastguard Worker 	else
4399*48a54d36SAndroid Build Coastguard Worker 	{
4400*48a54d36SAndroid Build Coastguard Worker 		sa4.sin_family = AF_INET;
4401*48a54d36SAndroid Build Coastguard Worker 		dwSize = sizeof( sa4 );
4402*48a54d36SAndroid Build Coastguard Worker 
4403*48a54d36SAndroid Build Coastguard Worker 		err = WSAStringToAddressA( string, AF_INET, NULL, (struct sockaddr*) &sa4, &dwSize );
4404*48a54d36SAndroid Build Coastguard Worker 		err = translate_errno( err == 0, WSAGetLastError(), kUnknownErr );
4405*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
4406*48a54d36SAndroid Build Coastguard Worker 
4407*48a54d36SAndroid Build Coastguard Worker 		err = SetupAddr( ip, (struct sockaddr*) &sa4 );
4408*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
4409*48a54d36SAndroid Build Coastguard Worker 	}
4410*48a54d36SAndroid Build Coastguard Worker 
4411*48a54d36SAndroid Build Coastguard Worker exit:
4412*48a54d36SAndroid Build Coastguard Worker 
4413*48a54d36SAndroid Build Coastguard Worker 	return err;
4414*48a54d36SAndroid Build Coastguard Worker }
4415*48a54d36SAndroid Build Coastguard Worker 
4416*48a54d36SAndroid Build Coastguard Worker 
4417*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4418*48a54d36SAndroid Build Coastguard Worker //	myGetIfAddrs
4419*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4420*48a54d36SAndroid Build Coastguard Worker 
4421*48a54d36SAndroid Build Coastguard Worker mDNSlocal struct ifaddrs*
myGetIfAddrs(int refresh)4422*48a54d36SAndroid Build Coastguard Worker myGetIfAddrs(int refresh)
4423*48a54d36SAndroid Build Coastguard Worker {
4424*48a54d36SAndroid Build Coastguard Worker 	static struct ifaddrs *ifa = NULL;
4425*48a54d36SAndroid Build Coastguard Worker 
4426*48a54d36SAndroid Build Coastguard Worker 	if (refresh && ifa)
4427*48a54d36SAndroid Build Coastguard Worker 	{
4428*48a54d36SAndroid Build Coastguard Worker 		freeifaddrs(ifa);
4429*48a54d36SAndroid Build Coastguard Worker 		ifa = NULL;
4430*48a54d36SAndroid Build Coastguard Worker 	}
4431*48a54d36SAndroid Build Coastguard Worker 
4432*48a54d36SAndroid Build Coastguard Worker 	if (ifa == NULL)
4433*48a54d36SAndroid Build Coastguard Worker 	{
4434*48a54d36SAndroid Build Coastguard Worker 		getifaddrs(&ifa);
4435*48a54d36SAndroid Build Coastguard Worker 	}
4436*48a54d36SAndroid Build Coastguard Worker 
4437*48a54d36SAndroid Build Coastguard Worker 	return ifa;
4438*48a54d36SAndroid Build Coastguard Worker }
4439*48a54d36SAndroid Build Coastguard Worker 
4440*48a54d36SAndroid Build Coastguard Worker 
4441*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4442*48a54d36SAndroid Build Coastguard Worker //	TCHARtoUTF8
4443*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4444*48a54d36SAndroid Build Coastguard Worker 
4445*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus
TCHARtoUTF8(const TCHAR * inString,char * inBuffer,size_t inBufferSize)4446*48a54d36SAndroid Build Coastguard Worker TCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize )
4447*48a54d36SAndroid Build Coastguard Worker {
4448*48a54d36SAndroid Build Coastguard Worker #if( defined( UNICODE ) || defined( _UNICODE ) )
4449*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
4450*48a54d36SAndroid Build Coastguard Worker 	int				len;
4451*48a54d36SAndroid Build Coastguard Worker 
4452*48a54d36SAndroid Build Coastguard Worker 	len = WideCharToMultiByte( CP_UTF8, 0, inString, -1, inBuffer, (int) inBufferSize, NULL, NULL );
4453*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
4454*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4455*48a54d36SAndroid Build Coastguard Worker 
4456*48a54d36SAndroid Build Coastguard Worker exit:
4457*48a54d36SAndroid Build Coastguard Worker 	return( err );
4458*48a54d36SAndroid Build Coastguard Worker #else
4459*48a54d36SAndroid Build Coastguard Worker 	return( WindowsLatin1toUTF8( inString, inBuffer, inBufferSize ) );
4460*48a54d36SAndroid Build Coastguard Worker #endif
4461*48a54d36SAndroid Build Coastguard Worker }
4462*48a54d36SAndroid Build Coastguard Worker 
4463*48a54d36SAndroid Build Coastguard Worker 
4464*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4465*48a54d36SAndroid Build Coastguard Worker //	WindowsLatin1toUTF8
4466*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4467*48a54d36SAndroid Build Coastguard Worker 
4468*48a54d36SAndroid Build Coastguard Worker mDNSlocal OSStatus
WindowsLatin1toUTF8(const char * inString,char * inBuffer,size_t inBufferSize)4469*48a54d36SAndroid Build Coastguard Worker WindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize )
4470*48a54d36SAndroid Build Coastguard Worker {
4471*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
4472*48a54d36SAndroid Build Coastguard Worker 	WCHAR *			utf16;
4473*48a54d36SAndroid Build Coastguard Worker 	int				len;
4474*48a54d36SAndroid Build Coastguard Worker 
4475*48a54d36SAndroid Build Coastguard Worker 	utf16 = NULL;
4476*48a54d36SAndroid Build Coastguard Worker 
4477*48a54d36SAndroid Build Coastguard Worker 	// Windows doesn't support going directly from Latin-1 to UTF-8 so we have to go from Latin-1 to UTF-16 first.
4478*48a54d36SAndroid Build Coastguard Worker 
4479*48a54d36SAndroid Build Coastguard Worker 	len = MultiByteToWideChar( CP_ACP, 0, inString, -1, NULL, 0 );
4480*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
4481*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4482*48a54d36SAndroid Build Coastguard Worker 
4483*48a54d36SAndroid Build Coastguard Worker 	utf16 = (WCHAR *) malloc( len * sizeof( *utf16 ) );
4484*48a54d36SAndroid Build Coastguard Worker 	require_action( utf16, exit, err = kNoMemoryErr );
4485*48a54d36SAndroid Build Coastguard Worker 
4486*48a54d36SAndroid Build Coastguard Worker 	len = MultiByteToWideChar( CP_ACP, 0, inString, -1, utf16, len );
4487*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
4488*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4489*48a54d36SAndroid Build Coastguard Worker 
4490*48a54d36SAndroid Build Coastguard Worker 	// Now convert the temporary UTF-16 to UTF-8.
4491*48a54d36SAndroid Build Coastguard Worker 
4492*48a54d36SAndroid Build Coastguard Worker 	len = WideCharToMultiByte( CP_UTF8, 0, utf16, -1, inBuffer, (int) inBufferSize, NULL, NULL );
4493*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
4494*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4495*48a54d36SAndroid Build Coastguard Worker 
4496*48a54d36SAndroid Build Coastguard Worker exit:
4497*48a54d36SAndroid Build Coastguard Worker 	if( utf16 ) free( utf16 );
4498*48a54d36SAndroid Build Coastguard Worker 	return( err );
4499*48a54d36SAndroid Build Coastguard Worker }
4500*48a54d36SAndroid Build Coastguard Worker 
4501*48a54d36SAndroid Build Coastguard Worker 
4502*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4503*48a54d36SAndroid Build Coastguard Worker //	TCPCloseSocket
4504*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4505*48a54d36SAndroid Build Coastguard Worker 
4506*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
TCPCloseSocket(TCPSocket * sock)4507*48a54d36SAndroid Build Coastguard Worker TCPCloseSocket( TCPSocket * sock )
4508*48a54d36SAndroid Build Coastguard Worker {
4509*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "closing TCPSocket 0x%x:%d\n", sock, sock->fd );
4510*48a54d36SAndroid Build Coastguard Worker 
4511*48a54d36SAndroid Build Coastguard Worker 	RemoveFromList( &gTCPDispatchableSockets, sock );
4512*48a54d36SAndroid Build Coastguard Worker 
4513*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
4514*48a54d36SAndroid Build Coastguard Worker 	{
4515*48a54d36SAndroid Build Coastguard Worker 		closesocket( sock->fd );
4516*48a54d36SAndroid Build Coastguard Worker 		sock->fd = INVALID_SOCKET;
4517*48a54d36SAndroid Build Coastguard Worker 	}
4518*48a54d36SAndroid Build Coastguard Worker }
4519*48a54d36SAndroid Build Coastguard Worker 
4520*48a54d36SAndroid Build Coastguard Worker 
4521*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4522*48a54d36SAndroid Build Coastguard Worker //	TCPFreeSocket
4523*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4524*48a54d36SAndroid Build Coastguard Worker 
4525*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK
TCPFreeSocket(TCPSocket * sock)4526*48a54d36SAndroid Build Coastguard Worker TCPFreeSocket( TCPSocket *sock )
4527*48a54d36SAndroid Build Coastguard Worker {
4528*48a54d36SAndroid Build Coastguard Worker 	check( sock );
4529*48a54d36SAndroid Build Coastguard Worker 
4530*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "freeing TCPSocket 0x%x:%d\n", sock, sock->fd );
4531*48a54d36SAndroid Build Coastguard Worker 
4532*48a54d36SAndroid Build Coastguard Worker 	if ( sock->connectEvent )
4533*48a54d36SAndroid Build Coastguard Worker 	{
4534*48a54d36SAndroid Build Coastguard Worker 		CloseHandle( sock->connectEvent );
4535*48a54d36SAndroid Build Coastguard Worker 		sock->connectEvent = NULL;
4536*48a54d36SAndroid Build Coastguard Worker 	}
4537*48a54d36SAndroid Build Coastguard Worker 
4538*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
4539*48a54d36SAndroid Build Coastguard Worker 	{
4540*48a54d36SAndroid Build Coastguard Worker 		closesocket( sock->fd );
4541*48a54d36SAndroid Build Coastguard Worker 		sock->fd = INVALID_SOCKET;
4542*48a54d36SAndroid Build Coastguard Worker 	}
4543*48a54d36SAndroid Build Coastguard Worker 
4544*48a54d36SAndroid Build Coastguard Worker 	free( sock );
4545*48a54d36SAndroid Build Coastguard Worker }
4546*48a54d36SAndroid Build Coastguard Worker 
4547*48a54d36SAndroid Build Coastguard Worker 
4548*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4549*48a54d36SAndroid Build Coastguard Worker //  UDPCloseSocket
4550*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4551*48a54d36SAndroid Build Coastguard Worker 
4552*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
UDPCloseSocket(UDPSocket * sock)4553*48a54d36SAndroid Build Coastguard Worker UDPCloseSocket( UDPSocket * sock )
4554*48a54d36SAndroid Build Coastguard Worker {
4555*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "closing UDPSocket %d\n", sock->fd );
4556*48a54d36SAndroid Build Coastguard Worker 
4557*48a54d36SAndroid Build Coastguard Worker 	RemoveFromList( &gUDPDispatchableSockets, sock );
4558*48a54d36SAndroid Build Coastguard Worker 
4559*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
4560*48a54d36SAndroid Build Coastguard Worker 	{
4561*48a54d36SAndroid Build Coastguard Worker 		closesocket( sock->fd );
4562*48a54d36SAndroid Build Coastguard Worker 		sock->fd = INVALID_SOCKET;
4563*48a54d36SAndroid Build Coastguard Worker 	}
4564*48a54d36SAndroid Build Coastguard Worker }
4565*48a54d36SAndroid Build Coastguard Worker 
4566*48a54d36SAndroid Build Coastguard Worker 
4567*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4568*48a54d36SAndroid Build Coastguard Worker //  UDPFreeSocket
4569*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4570*48a54d36SAndroid Build Coastguard Worker 
4571*48a54d36SAndroid Build Coastguard Worker mDNSlocal void CALLBACK
UDPFreeSocket(UDPSocket * sock)4572*48a54d36SAndroid Build Coastguard Worker UDPFreeSocket( UDPSocket * sock )
4573*48a54d36SAndroid Build Coastguard Worker {
4574*48a54d36SAndroid Build Coastguard Worker     check( sock );
4575*48a54d36SAndroid Build Coastguard Worker 
4576*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelChatty, DEBUG_NAME "freeing UDPSocket %d\n", sock->fd );
4577*48a54d36SAndroid Build Coastguard Worker 
4578*48a54d36SAndroid Build Coastguard Worker     if ( sock->fd != INVALID_SOCKET )
4579*48a54d36SAndroid Build Coastguard Worker     {
4580*48a54d36SAndroid Build Coastguard Worker         closesocket( sock->fd );
4581*48a54d36SAndroid Build Coastguard Worker 		sock->fd = INVALID_SOCKET;
4582*48a54d36SAndroid Build Coastguard Worker     }
4583*48a54d36SAndroid Build Coastguard Worker 
4584*48a54d36SAndroid Build Coastguard Worker     free( sock );
4585*48a54d36SAndroid Build Coastguard Worker }
4586*48a54d36SAndroid Build Coastguard Worker 
4587*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4588*48a54d36SAndroid Build Coastguard Worker //	SetupAddr
4589*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
4590*48a54d36SAndroid Build Coastguard Worker 
SetupAddr(mDNSAddr * ip,const struct sockaddr * const sa)4591*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
4592*48a54d36SAndroid Build Coastguard Worker 	{
4593*48a54d36SAndroid Build Coastguard Worker 	if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
4594*48a54d36SAndroid Build Coastguard Worker 
4595*48a54d36SAndroid Build Coastguard Worker 	if (sa->sa_family == AF_INET)
4596*48a54d36SAndroid Build Coastguard Worker 		{
4597*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
4598*48a54d36SAndroid Build Coastguard Worker 		ip->type = mDNSAddrType_IPv4;
4599*48a54d36SAndroid Build Coastguard Worker 		ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
4600*48a54d36SAndroid Build Coastguard Worker 		return(mStatus_NoError);
4601*48a54d36SAndroid Build Coastguard Worker 		}
4602*48a54d36SAndroid Build Coastguard Worker 
4603*48a54d36SAndroid Build Coastguard Worker 	if (sa->sa_family == AF_INET6)
4604*48a54d36SAndroid Build Coastguard Worker 		{
4605*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
4606*48a54d36SAndroid Build Coastguard Worker 		ip->type = mDNSAddrType_IPv6;
4607*48a54d36SAndroid Build Coastguard Worker 		if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.u.Word[1] = 0;
4608*48a54d36SAndroid Build Coastguard Worker 		ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
4609*48a54d36SAndroid Build Coastguard Worker 		return(mStatus_NoError);
4610*48a54d36SAndroid Build Coastguard Worker 		}
4611*48a54d36SAndroid Build Coastguard Worker 
4612*48a54d36SAndroid Build Coastguard Worker 	LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
4613*48a54d36SAndroid Build Coastguard Worker 	return(mStatus_Invalid);
4614*48a54d36SAndroid Build Coastguard Worker 	}
4615*48a54d36SAndroid Build Coastguard Worker 
4616*48a54d36SAndroid Build Coastguard Worker 
GetDDNSFQDN(domainname * const fqdn)4617*48a54d36SAndroid Build Coastguard Worker mDNSlocal void GetDDNSFQDN( domainname *const fqdn )
4618*48a54d36SAndroid Build Coastguard Worker {
4619*48a54d36SAndroid Build Coastguard Worker 	LPSTR		name = NULL;
4620*48a54d36SAndroid Build Coastguard Worker 	DWORD		dwSize;
4621*48a54d36SAndroid Build Coastguard Worker 	DWORD		enabled;
4622*48a54d36SAndroid Build Coastguard Worker 	HKEY		key = NULL;
4623*48a54d36SAndroid Build Coastguard Worker 	OSStatus	err;
4624*48a54d36SAndroid Build Coastguard Worker 
4625*48a54d36SAndroid Build Coastguard Worker 	check( fqdn );
4626*48a54d36SAndroid Build Coastguard Worker 
4627*48a54d36SAndroid Build Coastguard Worker 	// Initialize
4628*48a54d36SAndroid Build Coastguard Worker 
4629*48a54d36SAndroid Build Coastguard Worker 	fqdn->c[0] = '\0';
4630*48a54d36SAndroid Build Coastguard Worker 
4631*48a54d36SAndroid Build Coastguard Worker 	// Get info from Bonjour registry key
4632*48a54d36SAndroid Build Coastguard Worker 
4633*48a54d36SAndroid Build Coastguard Worker 	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
4634*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4635*48a54d36SAndroid Build Coastguard Worker 
4636*48a54d36SAndroid Build Coastguard Worker 	err = RegQueryString( key, "", &name, &dwSize, &enabled );
4637*48a54d36SAndroid Build Coastguard Worker 	if ( !err && ( name[0] != '\0' ) && enabled )
4638*48a54d36SAndroid Build Coastguard Worker 	{
4639*48a54d36SAndroid Build Coastguard Worker 		if ( !MakeDomainNameFromDNSNameString( fqdn, name ) || !fqdn->c[0] )
4640*48a54d36SAndroid Build Coastguard Worker 		{
4641*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelError, "bad DDNS host name in registry: %s", name[0] ? name : "(unknown)");
4642*48a54d36SAndroid Build Coastguard Worker 		}
4643*48a54d36SAndroid Build Coastguard Worker 	}
4644*48a54d36SAndroid Build Coastguard Worker 
4645*48a54d36SAndroid Build Coastguard Worker exit:
4646*48a54d36SAndroid Build Coastguard Worker 
4647*48a54d36SAndroid Build Coastguard Worker 	if ( key )
4648*48a54d36SAndroid Build Coastguard Worker 	{
4649*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( key );
4650*48a54d36SAndroid Build Coastguard Worker 		key = NULL;
4651*48a54d36SAndroid Build Coastguard Worker 	}
4652*48a54d36SAndroid Build Coastguard Worker 
4653*48a54d36SAndroid Build Coastguard Worker 	if ( name )
4654*48a54d36SAndroid Build Coastguard Worker 	{
4655*48a54d36SAndroid Build Coastguard Worker 		free( name );
4656*48a54d36SAndroid Build Coastguard Worker 		name = NULL;
4657*48a54d36SAndroid Build Coastguard Worker 	}
4658*48a54d36SAndroid Build Coastguard Worker }
4659*48a54d36SAndroid Build Coastguard Worker 
4660*48a54d36SAndroid Build Coastguard Worker 
4661*48a54d36SAndroid Build Coastguard Worker #ifdef UNICODE
GetDDNSDomains(DNameListElem ** domains,LPCWSTR lpSubKey)4662*48a54d36SAndroid Build Coastguard Worker mDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey )
4663*48a54d36SAndroid Build Coastguard Worker #else
4664*48a54d36SAndroid Build Coastguard Worker mDNSlocal void GetDDNSConfig( DNameListElem ** domains, LPCSTR lpSubKey )
4665*48a54d36SAndroid Build Coastguard Worker #endif
4666*48a54d36SAndroid Build Coastguard Worker {
4667*48a54d36SAndroid Build Coastguard Worker 	char		subKeyName[kRegistryMaxKeyLength + 1];
4668*48a54d36SAndroid Build Coastguard Worker 	DWORD		cSubKeys = 0;
4669*48a54d36SAndroid Build Coastguard Worker 	DWORD		cbMaxSubKey;
4670*48a54d36SAndroid Build Coastguard Worker 	DWORD		cchMaxClass;
4671*48a54d36SAndroid Build Coastguard Worker 	DWORD		dwSize;
4672*48a54d36SAndroid Build Coastguard Worker 	HKEY		key = NULL;
4673*48a54d36SAndroid Build Coastguard Worker 	HKEY		subKey = NULL;
4674*48a54d36SAndroid Build Coastguard Worker 	domainname	dname;
4675*48a54d36SAndroid Build Coastguard Worker 	DWORD		i;
4676*48a54d36SAndroid Build Coastguard Worker 	OSStatus	err;
4677*48a54d36SAndroid Build Coastguard Worker 
4678*48a54d36SAndroid Build Coastguard Worker 	check( domains );
4679*48a54d36SAndroid Build Coastguard Worker 
4680*48a54d36SAndroid Build Coastguard Worker 	// Initialize
4681*48a54d36SAndroid Build Coastguard Worker 
4682*48a54d36SAndroid Build Coastguard Worker 	*domains = NULL;
4683*48a54d36SAndroid Build Coastguard Worker 
4684*48a54d36SAndroid Build Coastguard Worker 	err = RegCreateKey( HKEY_LOCAL_MACHINE, lpSubKey, &key );
4685*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4686*48a54d36SAndroid Build Coastguard Worker 
4687*48a54d36SAndroid Build Coastguard Worker 	// Get information about this node
4688*48a54d36SAndroid Build Coastguard Worker 
4689*48a54d36SAndroid Build Coastguard Worker 	err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
4690*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
4691*48a54d36SAndroid Build Coastguard Worker 
4692*48a54d36SAndroid Build Coastguard Worker 	for ( i = 0; i < cSubKeys; i++)
4693*48a54d36SAndroid Build Coastguard Worker 	{
4694*48a54d36SAndroid Build Coastguard Worker 		DWORD enabled;
4695*48a54d36SAndroid Build Coastguard Worker 
4696*48a54d36SAndroid Build Coastguard Worker 		dwSize = kRegistryMaxKeyLength;
4697*48a54d36SAndroid Build Coastguard Worker 
4698*48a54d36SAndroid Build Coastguard Worker 		err = RegEnumKeyExA( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
4699*48a54d36SAndroid Build Coastguard Worker 
4700*48a54d36SAndroid Build Coastguard Worker 		if ( !err )
4701*48a54d36SAndroid Build Coastguard Worker 		{
4702*48a54d36SAndroid Build Coastguard Worker 			err = RegOpenKeyExA( key, subKeyName, 0, KEY_READ, &subKey );
4703*48a54d36SAndroid Build Coastguard Worker 			require_noerr( err, exit );
4704*48a54d36SAndroid Build Coastguard Worker 
4705*48a54d36SAndroid Build Coastguard Worker 			dwSize = sizeof( DWORD );
4706*48a54d36SAndroid Build Coastguard Worker 			err = RegQueryValueExA( subKey, "Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
4707*48a54d36SAndroid Build Coastguard Worker 
4708*48a54d36SAndroid Build Coastguard Worker 			if ( !err && ( subKeyName[0] != '\0' ) && enabled )
4709*48a54d36SAndroid Build Coastguard Worker 			{
4710*48a54d36SAndroid Build Coastguard Worker 				if ( !MakeDomainNameFromDNSNameString( &dname, subKeyName ) || !dname.c[0] )
4711*48a54d36SAndroid Build Coastguard Worker 				{
4712*48a54d36SAndroid Build Coastguard Worker 					dlog( kDebugLevelError, "bad DDNS domain in registry: %s", subKeyName[0] ? subKeyName : "(unknown)");
4713*48a54d36SAndroid Build Coastguard Worker 				}
4714*48a54d36SAndroid Build Coastguard Worker 				else
4715*48a54d36SAndroid Build Coastguard Worker 				{
4716*48a54d36SAndroid Build Coastguard Worker 					DNameListElem * domain = (DNameListElem*) malloc( sizeof( DNameListElem ) );
4717*48a54d36SAndroid Build Coastguard Worker 					require_action( domain, exit, err = mStatus_NoMemoryErr );
4718*48a54d36SAndroid Build Coastguard Worker 
4719*48a54d36SAndroid Build Coastguard Worker 					AssignDomainName(&domain->name, &dname);
4720*48a54d36SAndroid Build Coastguard Worker 					domain->next = *domains;
4721*48a54d36SAndroid Build Coastguard Worker 
4722*48a54d36SAndroid Build Coastguard Worker 					*domains = domain;
4723*48a54d36SAndroid Build Coastguard Worker 				}
4724*48a54d36SAndroid Build Coastguard Worker 			}
4725*48a54d36SAndroid Build Coastguard Worker 
4726*48a54d36SAndroid Build Coastguard Worker 			RegCloseKey( subKey );
4727*48a54d36SAndroid Build Coastguard Worker 			subKey = NULL;
4728*48a54d36SAndroid Build Coastguard Worker 		}
4729*48a54d36SAndroid Build Coastguard Worker 	}
4730*48a54d36SAndroid Build Coastguard Worker 
4731*48a54d36SAndroid Build Coastguard Worker exit:
4732*48a54d36SAndroid Build Coastguard Worker 
4733*48a54d36SAndroid Build Coastguard Worker 	if ( subKey )
4734*48a54d36SAndroid Build Coastguard Worker 	{
4735*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( subKey );
4736*48a54d36SAndroid Build Coastguard Worker 	}
4737*48a54d36SAndroid Build Coastguard Worker 
4738*48a54d36SAndroid Build Coastguard Worker 	if ( key )
4739*48a54d36SAndroid Build Coastguard Worker 	{
4740*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( key );
4741*48a54d36SAndroid Build Coastguard Worker 	}
4742*48a54d36SAndroid Build Coastguard Worker }
4743*48a54d36SAndroid Build Coastguard Worker 
4744*48a54d36SAndroid Build Coastguard Worker 
SetDomainSecret(mDNS * const m,const domainname * inDomain)4745*48a54d36SAndroid Build Coastguard Worker mDNSlocal void SetDomainSecret( mDNS * const m, const domainname * inDomain )
4746*48a54d36SAndroid Build Coastguard Worker {
4747*48a54d36SAndroid Build Coastguard Worker 	char					domainUTF8[ 256 ];
4748*48a54d36SAndroid Build Coastguard Worker 	DomainAuthInfo			*foundInList;
4749*48a54d36SAndroid Build Coastguard Worker 	DomainAuthInfo			*ptr;
4750*48a54d36SAndroid Build Coastguard Worker 	char					outDomain[ 256 ];
4751*48a54d36SAndroid Build Coastguard Worker 	char					outKey[ 256 ];
4752*48a54d36SAndroid Build Coastguard Worker 	char					outSecret[ 256 ];
4753*48a54d36SAndroid Build Coastguard Worker 	OSStatus				err;
4754*48a54d36SAndroid Build Coastguard Worker 
4755*48a54d36SAndroid Build Coastguard Worker 	ConvertDomainNameToCString( inDomain, domainUTF8 );
4756*48a54d36SAndroid Build Coastguard Worker 
4757*48a54d36SAndroid Build Coastguard Worker 	// If we're able to find a secret for this domain
4758*48a54d36SAndroid Build Coastguard Worker 
4759*48a54d36SAndroid Build Coastguard Worker 	if ( LsaGetSecret( domainUTF8, outDomain, sizeof( outDomain ), outKey, sizeof( outKey ), outSecret, sizeof( outSecret ) ) )
4760*48a54d36SAndroid Build Coastguard Worker 	{
4761*48a54d36SAndroid Build Coastguard Worker 		domainname domain;
4762*48a54d36SAndroid Build Coastguard Worker 		domainname key;
4763*48a54d36SAndroid Build Coastguard Worker 
4764*48a54d36SAndroid Build Coastguard Worker 		// Tell the core about this secret
4765*48a54d36SAndroid Build Coastguard Worker 
4766*48a54d36SAndroid Build Coastguard Worker 		MakeDomainNameFromDNSNameString( &domain, outDomain );
4767*48a54d36SAndroid Build Coastguard Worker 		MakeDomainNameFromDNSNameString( &key, outKey );
4768*48a54d36SAndroid Build Coastguard Worker 
4769*48a54d36SAndroid Build Coastguard Worker 		for (foundInList = m->AuthInfoList; foundInList; foundInList = foundInList->next)
4770*48a54d36SAndroid Build Coastguard Worker 			if (SameDomainName(&foundInList->domain, &domain ) ) break;
4771*48a54d36SAndroid Build Coastguard Worker 
4772*48a54d36SAndroid Build Coastguard Worker 		ptr = foundInList;
4773*48a54d36SAndroid Build Coastguard Worker 
4774*48a54d36SAndroid Build Coastguard Worker 		if (!ptr)
4775*48a54d36SAndroid Build Coastguard Worker 		{
4776*48a54d36SAndroid Build Coastguard Worker 			ptr = (DomainAuthInfo*)malloc(sizeof(DomainAuthInfo));
4777*48a54d36SAndroid Build Coastguard Worker 			require_action( ptr, exit, err = mStatus_NoMemoryErr );
4778*48a54d36SAndroid Build Coastguard Worker 		}
4779*48a54d36SAndroid Build Coastguard Worker 
4780*48a54d36SAndroid Build Coastguard Worker 		err = mDNS_SetSecretForDomain(m, ptr, &domain, &key, outSecret, NULL, 0, NULL );
4781*48a54d36SAndroid Build Coastguard Worker 		require_action( err != mStatus_BadParamErr, exit, if (!foundInList ) mDNSPlatformMemFree( ptr ) );
4782*48a54d36SAndroid Build Coastguard Worker 
4783*48a54d36SAndroid Build Coastguard Worker 		debugf("Setting shared secret for zone %s with key %##s", outDomain, key.c);
4784*48a54d36SAndroid Build Coastguard Worker 	}
4785*48a54d36SAndroid Build Coastguard Worker 
4786*48a54d36SAndroid Build Coastguard Worker exit:
4787*48a54d36SAndroid Build Coastguard Worker 
4788*48a54d36SAndroid Build Coastguard Worker 	return;
4789*48a54d36SAndroid Build Coastguard Worker }
4790*48a54d36SAndroid Build Coastguard Worker 
4791*48a54d36SAndroid Build Coastguard Worker 
4792*48a54d36SAndroid Build Coastguard Worker mDNSlocal VOID CALLBACK
CheckFileSharesProc(LPVOID arg,DWORD dwTimerLowValue,DWORD dwTimerHighValue)4793*48a54d36SAndroid Build Coastguard Worker CheckFileSharesProc( LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue )
4794*48a54d36SAndroid Build Coastguard Worker {
4795*48a54d36SAndroid Build Coastguard Worker 	mDNS * const m = ( mDNS * const ) arg;
4796*48a54d36SAndroid Build Coastguard Worker 
4797*48a54d36SAndroid Build Coastguard Worker 	( void ) dwTimerLowValue;
4798*48a54d36SAndroid Build Coastguard Worker 	( void ) dwTimerHighValue;
4799*48a54d36SAndroid Build Coastguard Worker 
4800*48a54d36SAndroid Build Coastguard Worker 	CheckFileShares( m );
4801*48a54d36SAndroid Build Coastguard Worker }
4802*48a54d36SAndroid Build Coastguard Worker 
4803*48a54d36SAndroid Build Coastguard Worker 
4804*48a54d36SAndroid Build Coastguard Worker mDNSlocal unsigned __stdcall
SMBRegistrationThread(void * arg)4805*48a54d36SAndroid Build Coastguard Worker SMBRegistrationThread( void * arg )
4806*48a54d36SAndroid Build Coastguard Worker {
4807*48a54d36SAndroid Build Coastguard Worker 	mDNS * const m = ( mDNS * const ) arg;
4808*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef sref = NULL;
4809*48a54d36SAndroid Build Coastguard Worker 	HANDLE		handles[ 3 ];
4810*48a54d36SAndroid Build Coastguard Worker 	mDNSu8		txtBuf[ 256 ];
4811*48a54d36SAndroid Build Coastguard Worker 	mDNSu8	*	txtPtr;
4812*48a54d36SAndroid Build Coastguard Worker 	size_t		keyLen;
4813*48a54d36SAndroid Build Coastguard Worker 	size_t		valLen;
4814*48a54d36SAndroid Build Coastguard Worker 	mDNSIPPort	port = { { SMBPortAsNumber >> 8, SMBPortAsNumber & 0xFF } };
4815*48a54d36SAndroid Build Coastguard Worker 	DNSServiceErrorType err;
4816*48a54d36SAndroid Build Coastguard Worker 
4817*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( arg );
4818*48a54d36SAndroid Build Coastguard Worker 
4819*48a54d36SAndroid Build Coastguard Worker 	handles[ 0 ] = gSMBThreadStopEvent;
4820*48a54d36SAndroid Build Coastguard Worker 	handles[ 1 ] = gSMBThreadRegisterEvent;
4821*48a54d36SAndroid Build Coastguard Worker 	handles[ 2 ] = gSMBThreadDeregisterEvent;
4822*48a54d36SAndroid Build Coastguard Worker 
4823*48a54d36SAndroid Build Coastguard Worker 	memset( txtBuf, 0, sizeof( txtBuf )  );
4824*48a54d36SAndroid Build Coastguard Worker 	txtPtr = txtBuf;
4825*48a54d36SAndroid Build Coastguard Worker 	keyLen = strlen( "netbios=" );
4826*48a54d36SAndroid Build Coastguard Worker 	valLen = strlen( m->p->nbname );
4827*48a54d36SAndroid Build Coastguard Worker 	require_action( valLen < 32, exit, err = kUnknownErr );	// This should never happen, but check to avoid further memory corruption
4828*48a54d36SAndroid Build Coastguard Worker 	*txtPtr++ = ( mDNSu8 ) ( keyLen + valLen );
4829*48a54d36SAndroid Build Coastguard Worker 	memcpy( txtPtr, "netbios=", keyLen );
4830*48a54d36SAndroid Build Coastguard Worker 	txtPtr += keyLen;
4831*48a54d36SAndroid Build Coastguard Worker 	if ( valLen ) { memcpy( txtPtr, m->p->nbname, valLen ); txtPtr += ( mDNSu8 ) valLen; }
4832*48a54d36SAndroid Build Coastguard Worker 	keyLen = strlen( "domain=" );
4833*48a54d36SAndroid Build Coastguard Worker 	valLen = strlen( m->p->nbdomain );
4834*48a54d36SAndroid Build Coastguard Worker 	require_action( valLen < 32, exit, err = kUnknownErr );	// This should never happen, but check to avoid further memory corruption
4835*48a54d36SAndroid Build Coastguard Worker 	*txtPtr++ = ( mDNSu8 )( keyLen + valLen );
4836*48a54d36SAndroid Build Coastguard Worker 	memcpy( txtPtr, "domain=", keyLen );
4837*48a54d36SAndroid Build Coastguard Worker 	txtPtr += keyLen;
4838*48a54d36SAndroid Build Coastguard Worker 	if ( valLen ) { memcpy( txtPtr, m->p->nbdomain, valLen ); txtPtr += valLen; }
4839*48a54d36SAndroid Build Coastguard Worker 
4840*48a54d36SAndroid Build Coastguard Worker 	for ( ;; )
4841*48a54d36SAndroid Build Coastguard Worker 	{
4842*48a54d36SAndroid Build Coastguard Worker 		DWORD ret;
4843*48a54d36SAndroid Build Coastguard Worker 
4844*48a54d36SAndroid Build Coastguard Worker 		ret = WaitForMultipleObjects( 3, handles, FALSE, INFINITE );
4845*48a54d36SAndroid Build Coastguard Worker 
4846*48a54d36SAndroid Build Coastguard Worker 		if ( ret != WAIT_FAILED )
4847*48a54d36SAndroid Build Coastguard Worker 		{
4848*48a54d36SAndroid Build Coastguard Worker 			if ( ret == kSMBStopEvent )
4849*48a54d36SAndroid Build Coastguard Worker 			{
4850*48a54d36SAndroid Build Coastguard Worker 				break;
4851*48a54d36SAndroid Build Coastguard Worker 			}
4852*48a54d36SAndroid Build Coastguard Worker 			else if ( ret == kSMBRegisterEvent )
4853*48a54d36SAndroid Build Coastguard Worker 			{
4854*48a54d36SAndroid Build Coastguard Worker 				err = gDNSServiceRegister( &sref, 0, 0, NULL, "_smb._tcp,_file", NULL, NULL, ( uint16_t ) port.NotAnInteger, ( mDNSu16 )( txtPtr - txtBuf ), txtBuf, NULL, NULL );
4855*48a54d36SAndroid Build Coastguard Worker 
4856*48a54d36SAndroid Build Coastguard Worker 				if ( err )
4857*48a54d36SAndroid Build Coastguard Worker 				{
4858*48a54d36SAndroid Build Coastguard Worker 					LogMsg( "SMBRegistrationThread: DNSServiceRegister returned %d\n", err );
4859*48a54d36SAndroid Build Coastguard Worker 					sref = NULL;
4860*48a54d36SAndroid Build Coastguard Worker 					break;
4861*48a54d36SAndroid Build Coastguard Worker 				}
4862*48a54d36SAndroid Build Coastguard Worker 			}
4863*48a54d36SAndroid Build Coastguard Worker 			else if ( ret == kSMBDeregisterEvent )
4864*48a54d36SAndroid Build Coastguard Worker 			{
4865*48a54d36SAndroid Build Coastguard Worker 				if ( sref )
4866*48a54d36SAndroid Build Coastguard Worker 				{
4867*48a54d36SAndroid Build Coastguard Worker 					gDNSServiceRefDeallocate( sref );
4868*48a54d36SAndroid Build Coastguard Worker 					sref = NULL;
4869*48a54d36SAndroid Build Coastguard Worker 				}
4870*48a54d36SAndroid Build Coastguard Worker 			}
4871*48a54d36SAndroid Build Coastguard Worker 		}
4872*48a54d36SAndroid Build Coastguard Worker 		else
4873*48a54d36SAndroid Build Coastguard Worker 		{
4874*48a54d36SAndroid Build Coastguard Worker 			LogMsg( "SMBRegistrationThread:  WaitForMultipleObjects returned %d\n", GetLastError() );
4875*48a54d36SAndroid Build Coastguard Worker 			break;
4876*48a54d36SAndroid Build Coastguard Worker 		}
4877*48a54d36SAndroid Build Coastguard Worker 	}
4878*48a54d36SAndroid Build Coastguard Worker 
4879*48a54d36SAndroid Build Coastguard Worker exit:
4880*48a54d36SAndroid Build Coastguard Worker 
4881*48a54d36SAndroid Build Coastguard Worker 	if ( sref != NULL )
4882*48a54d36SAndroid Build Coastguard Worker 	{
4883*48a54d36SAndroid Build Coastguard Worker 		gDNSServiceRefDeallocate( sref );
4884*48a54d36SAndroid Build Coastguard Worker 		sref = NULL;
4885*48a54d36SAndroid Build Coastguard Worker 	}
4886*48a54d36SAndroid Build Coastguard Worker 
4887*48a54d36SAndroid Build Coastguard Worker 	SetEvent( gSMBThreadQuitEvent );
4888*48a54d36SAndroid Build Coastguard Worker 	_endthreadex( 0 );
4889*48a54d36SAndroid Build Coastguard Worker 	return 0;
4890*48a54d36SAndroid Build Coastguard Worker }
4891*48a54d36SAndroid Build Coastguard Worker 
4892*48a54d36SAndroid Build Coastguard Worker 
4893*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
CheckFileShares(mDNS * const m)4894*48a54d36SAndroid Build Coastguard Worker CheckFileShares( mDNS * const m )
4895*48a54d36SAndroid Build Coastguard Worker {
4896*48a54d36SAndroid Build Coastguard Worker 	PSHARE_INFO_1	bufPtr = ( PSHARE_INFO_1 ) NULL;
4897*48a54d36SAndroid Build Coastguard Worker 	DWORD			entriesRead = 0;
4898*48a54d36SAndroid Build Coastguard Worker 	DWORD			totalEntries = 0;
4899*48a54d36SAndroid Build Coastguard Worker 	DWORD			resume = 0;
4900*48a54d36SAndroid Build Coastguard Worker 	mDNSBool		advertise = mDNSfalse;
4901*48a54d36SAndroid Build Coastguard Worker 	mDNSBool		fileSharing = mDNSfalse;
4902*48a54d36SAndroid Build Coastguard Worker 	mDNSBool		printSharing = mDNSfalse;
4903*48a54d36SAndroid Build Coastguard Worker 	HKEY			key = NULL;
4904*48a54d36SAndroid Build Coastguard Worker 	BOOL			retry = FALSE;
4905*48a54d36SAndroid Build Coastguard Worker 	NET_API_STATUS  res;
4906*48a54d36SAndroid Build Coastguard Worker 	mStatus			err;
4907*48a54d36SAndroid Build Coastguard Worker 
4908*48a54d36SAndroid Build Coastguard Worker 	check( m );
4909*48a54d36SAndroid Build Coastguard Worker 
4910*48a54d36SAndroid Build Coastguard Worker 	// Only do this if we're not shutting down
4911*48a54d36SAndroid Build Coastguard Worker 
4912*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( m->AdvertiseLocalAddresses && !m->ShutdownTime, exit, err = kNoErr );
4913*48a54d36SAndroid Build Coastguard Worker 
4914*48a54d36SAndroid Build Coastguard Worker 	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Services\\SMB", &key );
4915*48a54d36SAndroid Build Coastguard Worker 
4916*48a54d36SAndroid Build Coastguard Worker 	if ( !err )
4917*48a54d36SAndroid Build Coastguard Worker 	{
4918*48a54d36SAndroid Build Coastguard Worker 		DWORD dwSize = sizeof( DWORD );
4919*48a54d36SAndroid Build Coastguard Worker 		RegQueryValueEx( key, L"Advertise", NULL, NULL, (LPBYTE) &advertise, &dwSize );
4920*48a54d36SAndroid Build Coastguard Worker 	}
4921*48a54d36SAndroid Build Coastguard Worker 
4922*48a54d36SAndroid Build Coastguard Worker 	if ( advertise && mDNSIsFileAndPrintSharingEnabled( &retry ) )
4923*48a54d36SAndroid Build Coastguard Worker 	{
4924*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelTrace, DEBUG_NAME "Sharing is enabled\n" );
4925*48a54d36SAndroid Build Coastguard Worker 
4926*48a54d36SAndroid Build Coastguard Worker 		res = NetShareEnum( NULL, 1, ( LPBYTE* )&bufPtr, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resume );
4927*48a54d36SAndroid Build Coastguard Worker 
4928*48a54d36SAndroid Build Coastguard Worker 		if ( ( res == ERROR_SUCCESS ) || ( res == ERROR_MORE_DATA ) )
4929*48a54d36SAndroid Build Coastguard Worker 		{
4930*48a54d36SAndroid Build Coastguard Worker 			PSHARE_INFO_1 p = bufPtr;
4931*48a54d36SAndroid Build Coastguard Worker 			DWORD i;
4932*48a54d36SAndroid Build Coastguard Worker 
4933*48a54d36SAndroid Build Coastguard Worker 			for( i = 0; i < entriesRead; i++ )
4934*48a54d36SAndroid Build Coastguard Worker 			{
4935*48a54d36SAndroid Build Coastguard Worker 				// We are only interested if the user is sharing anything other
4936*48a54d36SAndroid Build Coastguard Worker 				// than the built-in "print$" source
4937*48a54d36SAndroid Build Coastguard Worker 
4938*48a54d36SAndroid Build Coastguard Worker 				if ( ( p->shi1_type == STYPE_DISKTREE ) && ( wcscmp( p->shi1_netname, TEXT( "print$" ) ) != 0 ) )
4939*48a54d36SAndroid Build Coastguard Worker 				{
4940*48a54d36SAndroid Build Coastguard Worker 					fileSharing = mDNStrue;
4941*48a54d36SAndroid Build Coastguard Worker 				}
4942*48a54d36SAndroid Build Coastguard Worker 				else if ( p->shi1_type == STYPE_PRINTQ )
4943*48a54d36SAndroid Build Coastguard Worker 				{
4944*48a54d36SAndroid Build Coastguard Worker 					printSharing = mDNStrue;
4945*48a54d36SAndroid Build Coastguard Worker 				}
4946*48a54d36SAndroid Build Coastguard Worker 
4947*48a54d36SAndroid Build Coastguard Worker 				p++;
4948*48a54d36SAndroid Build Coastguard Worker 			}
4949*48a54d36SAndroid Build Coastguard Worker 
4950*48a54d36SAndroid Build Coastguard Worker 			NetApiBufferFree( bufPtr );
4951*48a54d36SAndroid Build Coastguard Worker 			bufPtr = NULL;
4952*48a54d36SAndroid Build Coastguard Worker 			retry = FALSE;
4953*48a54d36SAndroid Build Coastguard Worker 		}
4954*48a54d36SAndroid Build Coastguard Worker 		else if ( res == NERR_ServerNotStarted )
4955*48a54d36SAndroid Build Coastguard Worker 		{
4956*48a54d36SAndroid Build Coastguard Worker 			retry = TRUE;
4957*48a54d36SAndroid Build Coastguard Worker 		}
4958*48a54d36SAndroid Build Coastguard Worker 	}
4959*48a54d36SAndroid Build Coastguard Worker 
4960*48a54d36SAndroid Build Coastguard Worker 	if ( retry )
4961*48a54d36SAndroid Build Coastguard Worker 	{
4962*48a54d36SAndroid Build Coastguard Worker 		__int64			qwTimeout;
4963*48a54d36SAndroid Build Coastguard Worker 		LARGE_INTEGER   liTimeout;
4964*48a54d36SAndroid Build Coastguard Worker 
4965*48a54d36SAndroid Build Coastguard Worker 		qwTimeout = -m->p->checkFileSharesTimeout * 10000000;
4966*48a54d36SAndroid Build Coastguard Worker 		liTimeout.LowPart  = ( DWORD )( qwTimeout & 0xFFFFFFFF );
4967*48a54d36SAndroid Build Coastguard Worker 		liTimeout.HighPart = ( LONG )( qwTimeout >> 32 );
4968*48a54d36SAndroid Build Coastguard Worker 
4969*48a54d36SAndroid Build Coastguard Worker 		SetWaitableTimer( m->p->checkFileSharesTimer, &liTimeout, 0, CheckFileSharesProc, m, FALSE );
4970*48a54d36SAndroid Build Coastguard Worker 	}
4971*48a54d36SAndroid Build Coastguard Worker 
4972*48a54d36SAndroid Build Coastguard Worker 	if ( !m->p->smbFileSharing && fileSharing )
4973*48a54d36SAndroid Build Coastguard Worker 	{
4974*48a54d36SAndroid Build Coastguard Worker 		if ( !gSMBThread )
4975*48a54d36SAndroid Build Coastguard Worker 		{
4976*48a54d36SAndroid Build Coastguard Worker 			if ( !gDNSSDLibrary )
4977*48a54d36SAndroid Build Coastguard Worker 			{
4978*48a54d36SAndroid Build Coastguard Worker 				gDNSSDLibrary = LoadLibrary( TEXT( "dnssd.dll" ) );
4979*48a54d36SAndroid Build Coastguard Worker 				require_action( gDNSSDLibrary, exit, err = GetLastError() );
4980*48a54d36SAndroid Build Coastguard Worker 			}
4981*48a54d36SAndroid Build Coastguard Worker 
4982*48a54d36SAndroid Build Coastguard Worker 			if ( !gDNSServiceRegister )
4983*48a54d36SAndroid Build Coastguard Worker 			{
4984*48a54d36SAndroid Build Coastguard Worker 				gDNSServiceRegister = ( DNSServiceRegisterFunc ) GetProcAddress( gDNSSDLibrary, "DNSServiceRegister" );
4985*48a54d36SAndroid Build Coastguard Worker 				require_action( gDNSServiceRegister, exit, err = GetLastError() );
4986*48a54d36SAndroid Build Coastguard Worker 			}
4987*48a54d36SAndroid Build Coastguard Worker 
4988*48a54d36SAndroid Build Coastguard Worker 			if ( !gDNSServiceRefDeallocate )
4989*48a54d36SAndroid Build Coastguard Worker 			{
4990*48a54d36SAndroid Build Coastguard Worker 				gDNSServiceRefDeallocate = ( DNSServiceRefDeallocateFunc ) GetProcAddress( gDNSSDLibrary, "DNSServiceRefDeallocate" );
4991*48a54d36SAndroid Build Coastguard Worker 				require_action( gDNSServiceRefDeallocate, exit, err = GetLastError() );
4992*48a54d36SAndroid Build Coastguard Worker 			}
4993*48a54d36SAndroid Build Coastguard Worker 
4994*48a54d36SAndroid Build Coastguard Worker 			if ( !gSMBThreadRegisterEvent )
4995*48a54d36SAndroid Build Coastguard Worker 			{
4996*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadRegisterEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
4997*48a54d36SAndroid Build Coastguard Worker 				require_action( gSMBThreadRegisterEvent != NULL, exit, err = GetLastError() );
4998*48a54d36SAndroid Build Coastguard Worker 			}
4999*48a54d36SAndroid Build Coastguard Worker 
5000*48a54d36SAndroid Build Coastguard Worker 			if ( !gSMBThreadDeregisterEvent )
5001*48a54d36SAndroid Build Coastguard Worker 			{
5002*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadDeregisterEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
5003*48a54d36SAndroid Build Coastguard Worker 				require_action( gSMBThreadDeregisterEvent != NULL, exit, err = GetLastError() );
5004*48a54d36SAndroid Build Coastguard Worker 			}
5005*48a54d36SAndroid Build Coastguard Worker 
5006*48a54d36SAndroid Build Coastguard Worker 			if ( !gSMBThreadStopEvent )
5007*48a54d36SAndroid Build Coastguard Worker 			{
5008*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadStopEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
5009*48a54d36SAndroid Build Coastguard Worker 				require_action( gSMBThreadStopEvent != NULL, exit, err = GetLastError() );
5010*48a54d36SAndroid Build Coastguard Worker 			}
5011*48a54d36SAndroid Build Coastguard Worker 
5012*48a54d36SAndroid Build Coastguard Worker 			if ( !gSMBThreadQuitEvent )
5013*48a54d36SAndroid Build Coastguard Worker 			{
5014*48a54d36SAndroid Build Coastguard Worker 				gSMBThreadQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
5015*48a54d36SAndroid Build Coastguard Worker 				require_action( gSMBThreadQuitEvent != NULL, exit, err = GetLastError() );
5016*48a54d36SAndroid Build Coastguard Worker 			}
5017*48a54d36SAndroid Build Coastguard Worker 
5018*48a54d36SAndroid Build Coastguard Worker 			gSMBThread = ( HANDLE ) _beginthreadex( NULL, 0, SMBRegistrationThread, m, 0, NULL );
5019*48a54d36SAndroid Build Coastguard Worker 			require_action( gSMBThread != NULL, exit, err = GetLastError() );
5020*48a54d36SAndroid Build Coastguard Worker 		}
5021*48a54d36SAndroid Build Coastguard Worker 
5022*48a54d36SAndroid Build Coastguard Worker 		SetEvent( gSMBThreadRegisterEvent );
5023*48a54d36SAndroid Build Coastguard Worker 
5024*48a54d36SAndroid Build Coastguard Worker 		m->p->smbFileSharing = mDNStrue;
5025*48a54d36SAndroid Build Coastguard Worker 	}
5026*48a54d36SAndroid Build Coastguard Worker 	else if ( m->p->smbFileSharing && !fileSharing )
5027*48a54d36SAndroid Build Coastguard Worker 	{
5028*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelTrace, DEBUG_NAME "deregistering smb type\n" );
5029*48a54d36SAndroid Build Coastguard Worker 
5030*48a54d36SAndroid Build Coastguard Worker 		if ( gSMBThreadDeregisterEvent != NULL )
5031*48a54d36SAndroid Build Coastguard Worker 		{
5032*48a54d36SAndroid Build Coastguard Worker 			SetEvent( gSMBThreadDeregisterEvent );
5033*48a54d36SAndroid Build Coastguard Worker 		}
5034*48a54d36SAndroid Build Coastguard Worker 
5035*48a54d36SAndroid Build Coastguard Worker 		m->p->smbFileSharing = mDNSfalse;
5036*48a54d36SAndroid Build Coastguard Worker 	}
5037*48a54d36SAndroid Build Coastguard Worker 
5038*48a54d36SAndroid Build Coastguard Worker exit:
5039*48a54d36SAndroid Build Coastguard Worker 
5040*48a54d36SAndroid Build Coastguard Worker 	if ( key )
5041*48a54d36SAndroid Build Coastguard Worker 	{
5042*48a54d36SAndroid Build Coastguard Worker 		RegCloseKey( key );
5043*48a54d36SAndroid Build Coastguard Worker 	}
5044*48a54d36SAndroid Build Coastguard Worker }
5045*48a54d36SAndroid Build Coastguard Worker 
5046*48a54d36SAndroid Build Coastguard Worker 
5047*48a54d36SAndroid Build Coastguard Worker BOOL
IsWOMPEnabled(mDNS * const m)5048*48a54d36SAndroid Build Coastguard Worker IsWOMPEnabled( mDNS * const m )
5049*48a54d36SAndroid Build Coastguard Worker {
5050*48a54d36SAndroid Build Coastguard Worker 	BOOL enabled;
5051*48a54d36SAndroid Build Coastguard Worker 
5052*48a54d36SAndroid Build Coastguard Worker 	mDNSInterfaceData * ifd;
5053*48a54d36SAndroid Build Coastguard Worker 
5054*48a54d36SAndroid Build Coastguard Worker 	enabled = FALSE;
5055*48a54d36SAndroid Build Coastguard Worker 
5056*48a54d36SAndroid Build Coastguard Worker 	for( ifd = m->p->interfaceList; ifd; ifd = ifd->next )
5057*48a54d36SAndroid Build Coastguard Worker 	{
5058*48a54d36SAndroid Build Coastguard Worker 		if ( IsWOMPEnabledForAdapter( ifd->name ) )
5059*48a54d36SAndroid Build Coastguard Worker 		{
5060*48a54d36SAndroid Build Coastguard Worker 			enabled = TRUE;
5061*48a54d36SAndroid Build Coastguard Worker 			break;
5062*48a54d36SAndroid Build Coastguard Worker 		}
5063*48a54d36SAndroid Build Coastguard Worker 	}
5064*48a54d36SAndroid Build Coastguard Worker 
5065*48a54d36SAndroid Build Coastguard Worker 	return enabled;
5066*48a54d36SAndroid Build Coastguard Worker }
5067*48a54d36SAndroid Build Coastguard Worker 
5068*48a54d36SAndroid Build Coastguard Worker 
5069*48a54d36SAndroid Build Coastguard Worker mDNSlocal mDNSu8
IsWOMPEnabledForAdapter(const char * adapterName)5070*48a54d36SAndroid Build Coastguard Worker IsWOMPEnabledForAdapter( const char * adapterName )
5071*48a54d36SAndroid Build Coastguard Worker {
5072*48a54d36SAndroid Build Coastguard Worker 	char						fileName[80];
5073*48a54d36SAndroid Build Coastguard Worker 	NDIS_OID					oid;
5074*48a54d36SAndroid Build Coastguard Worker     DWORD						count;
5075*48a54d36SAndroid Build Coastguard Worker     HANDLE						handle	= INVALID_HANDLE_VALUE;
5076*48a54d36SAndroid Build Coastguard Worker 	NDIS_PNP_CAPABILITIES	*	pNPC	= NULL;
5077*48a54d36SAndroid Build Coastguard Worker 	int							err;
5078*48a54d36SAndroid Build Coastguard Worker 	mDNSu8						ok		= TRUE;
5079*48a54d36SAndroid Build Coastguard Worker 
5080*48a54d36SAndroid Build Coastguard Worker 	require_action( adapterName != NULL, exit, ok = FALSE );
5081*48a54d36SAndroid Build Coastguard Worker 
5082*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "IsWOMPEnabledForAdapter: %s\n", adapterName );
5083*48a54d36SAndroid Build Coastguard Worker 
5084*48a54d36SAndroid Build Coastguard Worker     // Construct a device name to pass to CreateFile
5085*48a54d36SAndroid Build Coastguard Worker 
5086*48a54d36SAndroid Build Coastguard Worker 	strncpy_s( fileName, sizeof( fileName ), DEVICE_PREFIX, strlen( DEVICE_PREFIX ) );
5087*48a54d36SAndroid Build Coastguard Worker 	strcat_s( fileName, sizeof( fileName ), adapterName );
5088*48a54d36SAndroid Build Coastguard Worker     handle = CreateFileA( fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, INVALID_HANDLE_VALUE );
5089*48a54d36SAndroid Build Coastguard Worker 	require_action ( handle != INVALID_HANDLE_VALUE, exit, ok = FALSE );
5090*48a54d36SAndroid Build Coastguard Worker 
5091*48a54d36SAndroid Build Coastguard Worker 	// We successfully opened the driver, format the IOCTL to pass the driver.
5092*48a54d36SAndroid Build Coastguard Worker 
5093*48a54d36SAndroid Build Coastguard Worker 	oid = OID_PNP_CAPABILITIES;
5094*48a54d36SAndroid Build Coastguard Worker 	pNPC = ( NDIS_PNP_CAPABILITIES * ) malloc( sizeof( NDIS_PNP_CAPABILITIES ) );
5095*48a54d36SAndroid Build Coastguard Worker 	require_action( pNPC != NULL, exit, ok = FALSE );
5096*48a54d36SAndroid Build Coastguard Worker 	ok = ( mDNSu8 ) DeviceIoControl( handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof( oid ), pNPC, sizeof( NDIS_PNP_CAPABILITIES ), &count, NULL );
5097*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( ok, GetLastError(), kUnknownErr );
5098*48a54d36SAndroid Build Coastguard Worker 	require_action( !err, exit, ok = FALSE );
5099*48a54d36SAndroid Build Coastguard Worker 	ok = ( mDNSu8 ) ( ( count == sizeof( NDIS_PNP_CAPABILITIES ) ) && ( pNPC->Flags & NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE ) );
5100*48a54d36SAndroid Build Coastguard Worker 
5101*48a54d36SAndroid Build Coastguard Worker exit:
5102*48a54d36SAndroid Build Coastguard Worker 
5103*48a54d36SAndroid Build Coastguard Worker 	if ( pNPC != NULL )
5104*48a54d36SAndroid Build Coastguard Worker 	{
5105*48a54d36SAndroid Build Coastguard Worker 		free( pNPC );
5106*48a54d36SAndroid Build Coastguard Worker 	}
5107*48a54d36SAndroid Build Coastguard Worker 
5108*48a54d36SAndroid Build Coastguard Worker     if ( handle != INVALID_HANDLE_VALUE )
5109*48a54d36SAndroid Build Coastguard Worker     {
5110*48a54d36SAndroid Build Coastguard Worker 		CloseHandle( handle );
5111*48a54d36SAndroid Build Coastguard Worker     }
5112*48a54d36SAndroid Build Coastguard Worker 
5113*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, DEBUG_NAME "IsWOMPEnabledForAdapter returns %s\n", ok ? "true" : "false" );
5114*48a54d36SAndroid Build Coastguard Worker 
5115*48a54d36SAndroid Build Coastguard Worker 	return ( mDNSu8 ) ok;
5116*48a54d36SAndroid Build Coastguard Worker }
5117*48a54d36SAndroid Build Coastguard Worker 
5118*48a54d36SAndroid Build Coastguard Worker 
5119*48a54d36SAndroid Build Coastguard Worker void
DispatchSocketEvents(mDNS * const inMDNS)5120*48a54d36SAndroid Build Coastguard Worker DispatchSocketEvents( mDNS * const inMDNS )
5121*48a54d36SAndroid Build Coastguard Worker {
5122*48a54d36SAndroid Build Coastguard Worker 	UDPSocket * udpSock;
5123*48a54d36SAndroid Build Coastguard Worker 	TCPSocket * tcpSock;
5124*48a54d36SAndroid Build Coastguard Worker 
5125*48a54d36SAndroid Build Coastguard Worker 	while ( ( udpSock = ( UDPSocket* ) gUDPDispatchableSockets.Head ) != NULL )
5126*48a54d36SAndroid Build Coastguard Worker 	{
5127*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelChatty, DEBUG_NAME "%s: calling DispatchUDPEvent on socket %d, error = %d, bytesTransferred = %d\n",
5128*48a54d36SAndroid Build Coastguard Worker 		                                     __ROUTINE__, udpSock->fd, udpSock->overlapped.error, udpSock->overlapped.bytesTransferred );
5129*48a54d36SAndroid Build Coastguard Worker 		RemoveFromList( &gUDPDispatchableSockets, udpSock );
5130*48a54d36SAndroid Build Coastguard Worker 		DispatchUDPEvent( inMDNS, udpSock );
5131*48a54d36SAndroid Build Coastguard Worker 	}
5132*48a54d36SAndroid Build Coastguard Worker 
5133*48a54d36SAndroid Build Coastguard Worker 	while ( ( tcpSock = ( TCPSocket* ) gTCPDispatchableSockets.Head ) != NULL )
5134*48a54d36SAndroid Build Coastguard Worker 	{
5135*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelChatty, DEBUG_NAME "%s: calling DispatchTCPEvent on socket %d, error = %d, bytesTransferred = %d\n",
5136*48a54d36SAndroid Build Coastguard Worker 		                                     __ROUTINE__, tcpSock->fd, tcpSock->overlapped.error, tcpSock->overlapped.bytesTransferred );
5137*48a54d36SAndroid Build Coastguard Worker 		RemoveFromList( &gTCPDispatchableSockets, tcpSock );
5138*48a54d36SAndroid Build Coastguard Worker 		DispatchTCPEvent( inMDNS, tcpSock );
5139*48a54d36SAndroid Build Coastguard Worker 	}
5140*48a54d36SAndroid Build Coastguard Worker }
5141*48a54d36SAndroid Build Coastguard Worker 
5142*48a54d36SAndroid Build Coastguard Worker 
5143*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
DispatchUDPEvent(mDNS * const inMDNS,UDPSocket * sock)5144*48a54d36SAndroid Build Coastguard Worker DispatchUDPEvent( mDNS * const inMDNS, UDPSocket * sock )
5145*48a54d36SAndroid Build Coastguard Worker {
5146*48a54d36SAndroid Build Coastguard Worker 	( void ) inMDNS;
5147*48a54d36SAndroid Build Coastguard Worker 
5148*48a54d36SAndroid Build Coastguard Worker 	// If we've closed the socket, then we want to ignore
5149*48a54d36SAndroid Build Coastguard Worker 	// this read.  The packet might have been queued before
5150*48a54d36SAndroid Build Coastguard Worker 	// the socket was closed.
5151*48a54d36SAndroid Build Coastguard Worker 
5152*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
5153*48a54d36SAndroid Build Coastguard Worker 	{
5154*48a54d36SAndroid Build Coastguard Worker 		const mDNSInterfaceID	iid = sock->ifd ? sock->ifd->interfaceInfo.InterfaceID : NULL;
5155*48a54d36SAndroid Build Coastguard Worker 		mDNSu8				*	end = ( (mDNSu8 *) &sock->packet ) + sock->overlapped.bytesTransferred;
5156*48a54d36SAndroid Build Coastguard Worker 
5157*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelChatty, DEBUG_NAME "calling mDNSCoreReceive on socket: %d\n", sock->fd );
5158*48a54d36SAndroid Build Coastguard Worker 		mDNSCoreReceive( sock->m, &sock->packet, end, &sock->overlapped.srcAddr, sock->overlapped.srcPort, &sock->overlapped.dstAddr, sock->overlapped.dstPort, iid );
5159*48a54d36SAndroid Build Coastguard Worker 	}
5160*48a54d36SAndroid Build Coastguard Worker 
5161*48a54d36SAndroid Build Coastguard Worker 	// If the socket is still good, then start up another asynchronous read
5162*48a54d36SAndroid Build Coastguard Worker 
5163*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
5164*48a54d36SAndroid Build Coastguard Worker 	{
5165*48a54d36SAndroid Build Coastguard Worker 		int err = UDPBeginRecv( sock );
5166*48a54d36SAndroid Build Coastguard Worker 		check_noerr( err );
5167*48a54d36SAndroid Build Coastguard Worker 	}
5168*48a54d36SAndroid Build Coastguard Worker }
5169*48a54d36SAndroid Build Coastguard Worker 
5170*48a54d36SAndroid Build Coastguard Worker 
5171*48a54d36SAndroid Build Coastguard Worker mDNSlocal void
DispatchTCPEvent(mDNS * const inMDNS,TCPSocket * sock)5172*48a54d36SAndroid Build Coastguard Worker DispatchTCPEvent( mDNS * const inMDNS, TCPSocket * sock )
5173*48a54d36SAndroid Build Coastguard Worker {
5174*48a54d36SAndroid Build Coastguard Worker 	( void ) inMDNS;
5175*48a54d36SAndroid Build Coastguard Worker 
5176*48a54d36SAndroid Build Coastguard Worker 	if ( sock->fd != INVALID_SOCKET )
5177*48a54d36SAndroid Build Coastguard Worker 	{
5178*48a54d36SAndroid Build Coastguard Worker 		sock->eptr += sock->overlapped.bytesTransferred;
5179*48a54d36SAndroid Build Coastguard Worker 		sock->lastError = sock->overlapped.error;
5180*48a54d36SAndroid Build Coastguard Worker 
5181*48a54d36SAndroid Build Coastguard Worker 		if ( !sock->overlapped.error && !sock->overlapped.bytesTransferred )
5182*48a54d36SAndroid Build Coastguard Worker 		{
5183*48a54d36SAndroid Build Coastguard Worker 			sock->closed = TRUE;
5184*48a54d36SAndroid Build Coastguard Worker 		}
5185*48a54d36SAndroid Build Coastguard Worker 
5186*48a54d36SAndroid Build Coastguard Worker 		if ( sock->readEventHandler != NULL )
5187*48a54d36SAndroid Build Coastguard Worker 		{
5188*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelChatty, DEBUG_NAME "calling TCP read handler  on socket: %d\n", sock->fd );
5189*48a54d36SAndroid Build Coastguard Worker 			sock->readEventHandler( sock );
5190*48a54d36SAndroid Build Coastguard Worker 		}
5191*48a54d36SAndroid Build Coastguard Worker 	}
5192*48a54d36SAndroid Build Coastguard Worker 
5193*48a54d36SAndroid Build Coastguard Worker 	// If the socket is still good, then start up another asynchronous read
5194*48a54d36SAndroid Build Coastguard Worker 
5195*48a54d36SAndroid Build Coastguard Worker 	if ( !sock->closed && ( sock->fd != INVALID_SOCKET ) )
5196*48a54d36SAndroid Build Coastguard Worker 	{
5197*48a54d36SAndroid Build Coastguard Worker 		int err = TCPBeginRecv( sock );
5198*48a54d36SAndroid Build Coastguard Worker 		check_noerr( err );
5199*48a54d36SAndroid Build Coastguard Worker 	}
5200*48a54d36SAndroid Build Coastguard Worker }
5201