2 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 Change History (most recent first):
27 $Log: mDNSMacOS9.c,v $
28 Revision 1.19 2003/08/18 23:09:20 cheshire
29 <rdar://problem/3382647> mDNSResponder divide by zero in mDNSPlatformTimeNow()
31 Revision 1.18 2003/08/12 19:56:24 cheshire
36 #include <LowMem.h> // For LMGetCurApName()
37 #include <TextUtils.h> // For smSystemScript
38 #include <UnicodeConverter.h> // For ConvertFromPStringToUnicode()
41 #include <stdarg.h> // For va_list support
43 #include "mDNSClientAPI.h" // Defines the interface provided to the client layer above
44 #include "mDNSPlatformFunctions.h" // Defines the interface to the supporting layer below
46 #include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform
48 // ***************************************************************************
51 static const TSetBooleanOption kReusePortOption
=
52 { sizeof(TSetBooleanOption
), INET_IP
, IP_REUSEPORT
, 0, true };
54 // IP_RCVDSTADDR gives error #-3151 (kOTBadOptionErr)
55 static const TSetBooleanOption kRcvDestAddrOption
=
56 { sizeof(TSetBooleanOption
), INET_IP
, IP_REUSEPORT
, 0, true };
58 static const TIPAddMulticastOption kAddLinkMulticastOption
=
59 { sizeof(TIPAddMulticastOption
), INET_IP
, IP_ADD_MEMBERSHIP
, 0, { 224, 0, 0,251 }, { 0,0,0,0 } };
61 static const TIPAddMulticastOption kAddAdminMulticastOption
=
62 { sizeof(TIPAddMulticastOption
), INET_IP
, IP_ADD_MEMBERSHIP
, 0, { 239,255,255,251 }, { 0,0,0,0 } };
64 // Bind endpoint to port number. Don't specify any specific IP address --
65 // we want to receive unicasts on all interfaces, as well as multicasts.
66 typedef struct { OTAddressType fAddressType
; mDNSIPPort fPort
; mDNSv4Addr fHost
; UInt8 fUnused
[8]; } mDNSInetAddress
;
67 //static const mDNSInetAddress mDNSPortInetAddress = { AF_INET, { 0,0 }, { 0,0,0,0 } }; // For testing legacy client support
68 #define MulticastDNSPortAsNumber 5353
69 static const mDNSInetAddress mDNSPortInetAddress
= { AF_INET
, { MulticastDNSPortAsNumber
>> 8, MulticastDNSPortAsNumber
& 0xFF }, { 0,0,0,0 } };
70 static const TBind mDNSbindReq
= { sizeof(mDNSPortInetAddress
), sizeof(mDNSPortInetAddress
), (UInt8
*)&mDNSPortInetAddress
, 0 };
72 static const TNetbuf zeroTNetbuf
= { 0 };
74 // ***************************************************************************
78 mDNSexport
void debugf_(const char *format
, ...)
80 unsigned char buffer
[256];
83 buffer
[0] = (unsigned char)mDNS_vsnprintf((char*)buffer
+1, 255, format
, ptr
);
85 #if __ONLYSYSTEMTASK__
86 buffer
[1+buffer
[0]] = 0;
87 fprintf(stderr
, "%s\n", buffer
+1);
95 mDNSexport
void LogMsg(const char *format
, ...)
97 unsigned char buffer
[256];
100 buffer
[0] = (unsigned char)mDNS_vsnprintf((char*)buffer
+1, 255, format
, ptr
);
102 #if __ONLYSYSTEMTASK__
103 buffer
[1+buffer
[0]] = 0;
104 fprintf(stderr
, "%s\n", buffer
+1);
111 mDNSexport mStatus
mDNSPlatformSendUDP(const mDNS
*const m
, const DNSMessage
*const msg
, const mDNSu8
*const end
,
112 mDNSInterfaceID InterfaceID
, mDNSIPPort srcPort
, const mDNSAddr
*dst
, mDNSIPPort dstPort
)
114 // Note: If we did multi-homing, we'd have to use the InterfaceID parameter to specify from which interface to send this response
115 #pragma unused(InterfaceID, srcPort)
117 InetAddress InetDest
;
120 InetDest
.fAddressType
= AF_INET
;
121 InetDest
.fPort
= dstPort
.NotAnInteger
;
122 InetDest
.fHost
= dst
->ip
.v4
.NotAnInteger
;
124 senddata
.addr
.maxlen
= sizeof(InetDest
);
125 senddata
.addr
.len
= sizeof(InetDest
);
126 senddata
.addr
.buf
= (UInt8
*)&InetDest
;
127 senddata
.opt
= zeroTNetbuf
;
128 senddata
.udata
.maxlen
= (UInt32
)((UInt8
*)end
- (UInt8
*)msg
);
129 senddata
.udata
.len
= (UInt32
)((UInt8
*)end
- (UInt8
*)msg
);
130 senddata
.udata
.buf
= (UInt8
*)msg
;
132 return(OTSndUData(m
->p
->ep
, &senddata
));
135 mDNSlocal OSStatus
readpacket(mDNS
*m
)
137 mDNSAddr senderaddr
, destaddr
;
138 mDNSInterfaceID interface
;
139 mDNSIPPort senderport
;
147 recvdata
.addr
.maxlen
= sizeof(sender
);
148 recvdata
.addr
.len
= 0;
149 recvdata
.addr
.buf
= (UInt8
*)&sender
;
150 recvdata
.opt
.maxlen
= sizeof(options
);
151 recvdata
.opt
.len
= 0;
152 recvdata
.opt
.buf
= (UInt8
*)&options
;
153 recvdata
.udata
.maxlen
= sizeof(packet
);
154 recvdata
.udata
.len
= 0;
155 recvdata
.udata
.buf
= (UInt8
*)&packet
;
157 err
= OTRcvUData(m
->p
->ep
, &recvdata
, &flags
);
158 if (err
&& err
!= kOTNoDataErr
) debugf("OTRcvUData error %d", err
);
160 if (err
) return(err
);
162 senderaddr
.type
= mDNSAddrType_IPv4
;
163 senderaddr
.ip
.v4
.NotAnInteger
= sender
.fHost
;
164 senderport
.NotAnInteger
= sender
.fPort
;
165 destaddr
.type
= mDNSAddrType_IPv4
;
166 destaddr
.ip
.v4
= AllDNSLinkGroup
; // For now, until I work out how to get the dest address, assume it was sent to AllDNSLinkGroup
167 interface
= m
->HostInterfaces
->InterfaceID
;
169 if (recvdata
.opt
.len
) debugf("readpacket: got some option data at %X, len %d", options
, recvdata
.opt
.len
);
171 if (flags
& T_MORE
) debugf("ERROR: OTRcvUData() buffer too small (T_MORE set)");
172 else if (recvdata
.addr
.len
< sizeof(InetAddress
)) debugf("ERROR: recvdata.addr.len (%d) too short", recvdata
.addr
.len
);
173 else if (recvdata
.udata
.len
< sizeof(DNSMessageHeader
)) debugf("ERROR: recvdata.udata.len (%d) too short", recvdata
.udata
.len
);
174 else mDNSCoreReceive(m
, &packet
, recvdata
.udata
.buf
+ recvdata
.udata
.len
, &senderaddr
, senderport
, &destaddr
, MulticastDNSPort
, interface
, 255);
180 mDNSlocal
void mDNSOptionManagement(mDNS
*const m
)
184 // Make sure the length in the TNetbuf agrees with the length in the TOptionHeader
185 m
->p
->optReq
.opt
.len
= m
->p
->optBlock
.h
.len
;
186 err
= OTOptionManagement(m
->p
->ep
, &m
->p
->optReq
, NULL
);
187 if (err
) debugf("OTOptionManagement failed %d", err
);
190 mDNSlocal
void mDNSinitComplete(mDNS
*const m
, mStatus result
)
192 m
->mDNSPlatformStatus
= result
;
193 mDNSCoreInitComplete(m
, mStatus_NoError
);
196 mDNSlocal
pascal void mDNSNotifier(void *contextPtr
, OTEventCode code
, OTResult result
, void *cookie
)
198 mDNS
*const m
= (mDNS
*const)contextPtr
;
199 if (!m
) debugf("mDNSNotifier FATAL ERROR! No context");
205 InetInterfaceInfo interfaceinfo
;
206 if (result
) { debugf("T_OPENCOMPLETE failed %d", result
); mDNSinitComplete(m
, result
); return; }
207 //debugf("T_OPENCOMPLETE");
208 m
->p
->ep
= (EndpointRef
)cookie
;
209 //debugf("OTInetGetInterfaceInfo");
210 // (In future may want to loop over all interfaces instead of just using kDefaultInetInterface)
211 err
= OTInetGetInterfaceInfo(&interfaceinfo
, kDefaultInetInterface
);
212 if (err
) { debugf("OTInetGetInterfaceInfo failed %d", err
); mDNSinitComplete(m
, err
); return; }
214 // Make our basic standard host resource records (address, PTR, etc.)
215 m
->p
->interface
.ip
.type
= mDNSAddrType_IPv4
;
216 m
->p
->interface
.ip
.ip
.v4
.NotAnInteger
= interfaceinfo
.fAddress
;
217 m
->p
->interface
.Advertise
= m
->AdvertiseLocalAddresses
;
218 m
->p
->interface
.InterfaceID
= (mDNSInterfaceID
)&m
->p
->interface
;
219 mDNS_RegisterInterface(m
, &m
->p
->interface
);
222 case T_OPTMGMTCOMPLETE
:
223 if (result
) { debugf("T_OPTMGMTCOMPLETE failed %d", result
); mDNSinitComplete(m
, result
); return; }
224 //debugf("T_OPTMGMTCOMPLETE");
225 switch (++m
->p
->mOTstate
)
227 case mOT_ReusePort
: m
->p
->optBlock
.b
= kReusePortOption
; mDNSOptionManagement(m
); break;
228 case mOT_RcvDestAddr
: m
->p
->optBlock
.b
= kRcvDestAddrOption
; mDNSOptionManagement(m
); break;
229 case mOT_LLScope
: m
->p
->optBlock
.m
= kAddLinkMulticastOption
; mDNSOptionManagement(m
); break;
230 case mOT_AdminScope
: m
->p
->optBlock
.m
= kAddAdminMulticastOption
; mDNSOptionManagement(m
); break;
231 case mOT_Bind
: OTBind(m
->p
->ep
, (TBind
*)&mDNSbindReq
, NULL
); break;
236 if (result
) { debugf("T_BINDCOMPLETE failed %d", result
); return; }
237 if (m
->p
->mOTstate
!= mOT_Bind
) { debugf("T_BINDCOMPLETE in wrong mDNS state %d", m
->p
->mOTstate
); return; }
239 //debugf("T_BINDCOMPLETE");
240 mDNSinitComplete(m
, mStatus_NoError
);
245 while (readpacket(m
) == kOTNoError
) continue; // Read packets until we run out
248 case kOTProviderWillClose
:
249 case kOTProviderIsClosed
: // Machine is going to sleep, shutting down, or reconfiguring IP
250 if (m
->p
->ep
) { OTCloseProvider(m
->p
->ep
); m
->p
->ep
= NULL
; }
251 break; // Do we need to do anything?
253 default: debugf("mDNSNotifier: Unexpected OTEventCode %X", code
);
258 #if __ONLYSYSTEMTASK__
260 static Boolean ONLYSYSTEMTASKevent
;
261 static void *ONLYSYSTEMTASKcontextPtr
;
262 static OTEventCode ONLYSYSTEMTASKcode
;
263 static OTResult ONLYSYSTEMTASKresult
;
264 static void *ONLYSYSTEMTASKcookie
;
266 mDNSlocal
pascal void CallmDNSNotifier(void *contextPtr
, OTEventCode code
, OTResult result
, void *cookie
)
268 ONLYSYSTEMTASKcontextPtr
= contextPtr
;
269 ONLYSYSTEMTASKcode
= code
;
270 ONLYSYSTEMTASKresult
= result
;
271 ONLYSYSTEMTASKcookie
= cookie
;
276 mDNSlocal
pascal void CallmDNSNotifier(void *contextPtr
, OTEventCode code
, OTResult result
, void *cookie
)
278 mDNS
*const m
= (mDNS
*const)contextPtr
;
279 if (!m
) debugf("mDNSNotifier FATAL ERROR! No context");
281 // Increment m->p->nesting to indicate to mDNSPlatformLock that there's no need
282 // to call OTEnterNotifier() (because we're already in OTNotifier context)
283 if (m
->p
->nesting
) DebugStr("\pCallmDNSNotifier ERROR! OTEnterNotifier is supposed to suppress notifier callbacks");
285 mDNSNotifier(contextPtr
, code
, result
, cookie
);
287 ScheduleNextTimerCallback(m
);
292 mDNSlocal OSStatus
mDNSOpenEndpoint(const mDNS
*const m
)
295 TEndpointInfo endpointinfo
;
296 // m->optReq is pre-set to point to the shared m->optBlock
297 // m->optBlock is filled in by each OTOptionManagement call
298 m
->p
->optReq
.opt
.maxlen
= sizeof(m
->p
->optBlock
);
299 m
->p
->optReq
.opt
.len
= sizeof(m
->p
->optBlock
);
300 m
->p
->optReq
.opt
.buf
= (UInt8
*)&m
->p
->optBlock
;
301 m
->p
->optReq
.flags
= T_NEGOTIATE
;
303 // Open an endpoint and start answering queries
304 //printf("Opening endpoint now...\n");
306 m
->p
->mOTstate
= mOT_Start
;
307 // err = OTAsyncOpenEndpoint(OTCreateConfiguration("udp(RxICMP=1)"), 0, &endpointinfo, CallmDNSNotifier, (void*)m); // works
308 // err = OTAsyncOpenEndpoint(OTCreateConfiguration("udp(RxICMP)"), 0, &endpointinfo, CallmDNSNotifier, (void*)m); // -3151 bad option
309 // err = OTAsyncOpenEndpoint(OTCreateConfiguration("udp,ip(RxICMP=1)"), 0, &endpointinfo, CallmDNSNotifier, (void*)m); // -3151
310 // err = OTAsyncOpenEndpoint(OTCreateConfiguration("udp,ip"), 0, &endpointinfo, CallmDNSNotifier, (void*)m); // works
311 // err = OTAsyncOpenEndpoint(OTCreateConfiguration("udp,rawip"), 0, &endpointinfo, CallmDNSNotifier, (void*)m); // -3221 invalid arg
312 err
= OTAsyncOpenEndpoint(OTCreateConfiguration(kUDPName
), 0, &endpointinfo
, NewOTNotifyUPP(CallmDNSNotifier
), (void*)m
);
313 if (err
) { debugf("ERROR: OTAsyncOpenEndpoint(UDP) failed with error <%d>", err
); return(err
); }
318 // Define these here because they're not in older versions of OpenTransport.h
321 xOTStackIsLoading
= 0x27000001, /* Sent before Open Transport attempts to load the TCP/IP protocol stack.*/
322 xOTStackWasLoaded
= 0x27000002, /* Sent after the TCP/IP stack has been successfully loaded.*/
323 xOTStackIsUnloading
= 0x27000003 /* Sent before Open Transport unloads the TCP/IP stack.*/
326 static mDNS
*ClientNotifierContext
;
328 mDNSlocal
pascal void ClientNotifier(void *contextPtr
, OTEventCode code
, OTResult result
, void *cookie
)
330 mDNS
*const m
= ClientNotifierContext
;
332 #pragma unused(contextPtr) // Usually zero (except one in the 'xOTStackIsLoading' case)
333 #pragma unused(cookie) // Usually 'ipv4' (except for kOTPortNetworkChange)
334 #pragma unused(result) // Usually zero
338 case xOTStackIsLoading
: break;
339 case xOTStackWasLoaded
: m
->mDNSPlatformStatus
= mStatus_Waiting
; m
->p
->mOTstate
= mOT_Reset
; break;
340 case xOTStackIsUnloading
: break;
341 case kOTPortNetworkChange
: break;
342 default: debugf("ClientNotifier unknown code %X, %X, %d", contextPtr
, code
, result
); break;
346 #if TARGET_API_MAC_CARBON
348 mDNSlocal
void GetUserSpecifiedComputerName(domainlabel
*const namelabel
)
350 CFStringRef cfs
= CSCopyMachineName();
351 CFStringGetPascalString(cfs
, namelabel
->c
, sizeof(*namelabel
), kCFStringEncodingUTF8
);
357 mDNSlocal OSStatus
ConvertStringHandleToUTF8(const StringHandle machineName
, UInt8
*const utf8
, ByteCount maxlen
)
360 TextEncoding utf8TextEncoding
, SystemTextEncoding
;
361 UnicodeMapping theMapping
;
362 TextToUnicodeInfo textToUnicodeInfo
;
363 ByteCount unicodelen
= 0;
365 if (maxlen
> 255) maxlen
= 255; // Can't put more than 255 in a Pascal String
367 utf8TextEncoding
= CreateTextEncoding(kTextEncodingUnicodeDefault
, kTextEncodingDefaultVariant
, kUnicodeUTF8Format
);
368 UpgradeScriptInfoToTextEncoding(smSystemScript
, kTextLanguageDontCare
, kTextRegionDontCare
, NULL
, &SystemTextEncoding
);
369 theMapping
.unicodeEncoding
= utf8TextEncoding
;
370 theMapping
.otherEncoding
= SystemTextEncoding
;
371 theMapping
.mappingVersion
= kUnicodeUseLatestMapping
;
372 status
= CreateTextToUnicodeInfo(&theMapping
, &textToUnicodeInfo
);
375 status
= ConvertFromPStringToUnicode(textToUnicodeInfo
, *machineName
, maxlen
, &unicodelen
, (UniCharArrayPtr
)&(utf8
[1]));
376 DisposeTextToUnicodeInfo(&textToUnicodeInfo
);
378 utf8
[0] = (UInt8
)unicodelen
;
382 mDNSlocal
void GetUserSpecifiedComputerName(domainlabel
*const namelabel
)
384 StringHandle machineName
= GetString(-16413); // Get machine name set in file sharing
387 char machineNameState
= HGetState((Handle
)machineName
);
388 HLock((Handle
)machineName
);
389 ConvertStringHandleToUTF8(machineName
, namelabel
->c
, MAX_DOMAIN_LABEL
);
390 HSetState((Handle
)machineName
, machineNameState
);
396 static pascal void mDNSTimerTask(void *arg
)
398 #if __ONLYSYSTEMTASK__
400 ONLYSYSTEMTASKevent
= true;
402 mDNS
*const m
= (mDNS
*const)arg
;
403 // Increment m->p->nesting to indicate to mDNSPlatformLock that there's no need
404 // to call OTEnterNotifier() (because we're already in OTNotifier context)
405 if (m
->p
->nesting
) DebugStr("\pmDNSTimerTask ERROR! OTEnterNotifier is supposed to suppress timer callbacks too");
409 ScheduleNextTimerCallback(m
);
414 long sleep
, wake
, mode
;
417 mDNSexport mStatus
mDNSPlatformInit(mDNS
*const m
)
421 // Set up the nice label
422 m
->nicelabel
.c
[0] = 0;
423 GetUserSpecifiedComputerName(&m
->nicelabel
);
424 // m->nicelabel = *(domainlabel*)"\pStu"; // For conflict testing
425 if (m
->nicelabel
.c
[0] == 0) MakeDomainLabelFromLiteralString(&m
->nicelabel
, "Macintosh");
427 // Set up the RFC 1034-compliant label
428 m
->hostlabel
.c
[0] = 0;
429 ConvertUTF8PstringToRFC1034HostLabel(m
->nicelabel
.c
, &m
->hostlabel
);
430 if (m
->hostlabel
.c
[0] == 0) MakeDomainLabelFromLiteralString(&m
->hostlabel
, "Macintosh");
432 mDNS_GenerateFQDN(m
);
434 ClientNotifierContext
= m
;
436 #if !TARGET_API_MAC_CARBON
437 err
= OTRegisterAsClient(LMGetCurApName(), NewOTNotifyUPP(ClientNotifier
));
438 if (err
) debugf("OTRegisterAsClient failed %d", err
);
441 err
= mDNSOpenEndpoint(m
);
442 if (err
) { debugf("mDNSOpenEndpoint failed %d", err
); return(err
); }
444 m
->p
->OTTimerTask
= OTCreateTimerTask(NewOTProcessUPP(mDNSTimerTask
), m
);
448 sleep
= TickCount() + 600;
449 wake
= TickCount() + 1200;
456 extern void mDNSPlatformClose (mDNS
*const m
)
458 if (m
->p
->OTTimerTask
) { OTDestroyTimerTask(m
->p
->OTTimerTask
); m
->p
->OTTimerTask
= 0; }
459 if (m
->p
->ep
) { OTCloseProvider (m
->p
->ep
); m
->p
->ep
= NULL
; }
460 CloseOpenTransport();
463 extern void mDNSPlatformIdle(mDNS
*const m
);
464 mDNSexport
void mDNSPlatformIdle(mDNS
*const m
)
466 #if __ONLYSYSTEMTASK__
467 while (ONLYSYSTEMTASKcontextPtr
)
469 void *contextPtr
= ONLYSYSTEMTASKcontextPtr
;
470 ONLYSYSTEMTASKcontextPtr
= NULL
;
471 mDNSNotifier(contextPtr
, ONLYSYSTEMTASKcode
, ONLYSYSTEMTASKresult
, ONLYSYSTEMTASKcookie
);
473 if (ONLYSYSTEMTASKevent
)
475 ONLYSYSTEMTASKevent
= false;
480 if (m
->p
->mOTstate
== mOT_Reset
)
483 printf("******************************************************************************\n");
485 printf("Reopening endpoint\n");
487 m
->ResourceRecords
= NULL
;
493 case 0: if ((long)TickCount() - sleep
>= 0) { mDNSCoreMachineSleep(m
, 1); mode
++; }
495 case 1: if ((long)TickCount() - wake
>= 0) { mDNSCoreMachineSleep(m
, 0); mode
++; }
502 mDNSexport
void mDNSPlatformLock(const mDNS
*const m
)
504 if (!m
) { DebugStr("\pmDNSPlatformLock m NULL!"); return; }
505 if (!m
->p
) { DebugStr("\pmDNSPlatformLock m->p NULL!"); return; }
506 if (!m
->p
->ep
) { DebugStr("\pmDNSPlatformLock m->p->ep NULL!"); return; }
508 // If we try to call OTEnterNotifier and fail because we're already running at
509 // Notifier context, then make sure we don't do the matching OTLeaveNotifier() on exit.
510 if (m
->p
->nesting
|| OTEnterNotifier(m
->p
->ep
) == false) m
->p
->nesting
++;
513 mDNSlocal
void ScheduleNextTimerCallback(const mDNS
*const m
)
516 interval
= m
->NextScheduledEvent
- mDNSPlatformTimeNow();
517 if (interval
< 0) interval
= 0;
518 else if (interval
> 0x7FFFFFFF / 1000) interval
= 0x7FFFFFFF / mDNSPlatformOneSecond
;
519 else interval
= interval
* 1000 / mDNSPlatformOneSecond
;
520 //debugf("mDNSPlatformScheduleTask Interval %d", interval);
521 OTScheduleTimerTask(m
->p
->OTTimerTask
, (OTTimeout
)interval
);
524 mDNSexport
void mDNSPlatformUnlock(const mDNS
*const m
)
526 if (!m
) { DebugStr("\pmDNSPlatformUnlock m NULL!"); return; }
527 if (!m
->p
) { DebugStr("\pmDNSPlatformUnlock m->p NULL!"); return; }
528 if (!m
->p
->ep
) { DebugStr("\pmDNSPlatformUnlock m->p->ep NULL!"); return; }
529 if (m
->p
->nesting
) m
->p
->nesting
--;
532 ScheduleNextTimerCallback(m
);
533 OTLeaveNotifier(m
->p
->ep
);
537 mDNSexport
void mDNSPlatformStrCopy(const void *src
, void *dst
) { OTStrCopy((char*)dst
, (char*)src
); }
538 mDNSexport UInt32
mDNSPlatformStrLen (const void *src
) { return(OTStrLength((char*)src
)); }
539 mDNSexport
void mDNSPlatformMemCopy(const void *src
, void *dst
, UInt32 len
) { OTMemcpy(dst
, src
, len
); }
540 mDNSexport mDNSBool
mDNSPlatformMemSame(const void *src
, const void *dst
, UInt32 len
) { return(OTMemcmp(dst
, src
, len
)); }
541 mDNSexport
void mDNSPlatformMemZero( void *dst
, UInt32 len
) { OTMemzero(dst
, len
); }
542 mDNSexport
void * mDNSPlatformMemAllocate(mDNSu32 len
) { return(OTAllocMem(len
)); }
543 mDNSexport
void mDNSPlatformMemFree (void *mem
) { OTFreeMem(mem
); }
544 mDNSexport mStatus
mDNSPlatformTimeInit(mDNSs32
*timenow
) { *timenow
= mDNSPlatformTimeNow(); return(mStatus_NoError
); }
545 mDNSexport SInt32
mDNSPlatformTimeNow() { return((SInt32
)TickCount()); }
546 mDNSexport SInt32 mDNSPlatformOneSecond
= 60;