diff options
Diffstat (limited to 'mDNSResponder/mDNSMacOS9/mDNSMacOS9.c')
-rw-r--r-- | mDNSResponder/mDNSMacOS9/mDNSMacOS9.c | 687 |
1 files changed, 687 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSMacOS9/mDNSMacOS9.c b/mDNSResponder/mDNSMacOS9/mDNSMacOS9.c new file mode 100644 index 00000000..24b03f22 --- /dev/null +++ b/mDNSResponder/mDNSMacOS9/mDNSMacOS9.c @@ -0,0 +1,687 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdarg.h> // For va_list support + +#include <LowMem.h> // For LMGetCurApName() +#include <TextUtils.h> // For smSystemScript +#include <UnicodeConverter.h> // For ConvertFromPStringToUnicode() + +#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above + +#include "mDNSMacOS9.h" // Defines the specific types needed to run mDNS on this platform + +// *************************************************************************** +// Constants + +static const TSetBooleanOption kReusePortOption = +{ kOTBooleanOptionSize, INET_IP, IP_REUSEPORT, 0, true }; + +// IP_RCVDSTADDR with TSetByteOption/kOTOneByteOptionSize works on OS 9, OS X Classic, and OS 9 Carbon, +// but gives error #-3151 (kOTBadOptionErr) on OS X Carbon. +// If we instead use TSetBooleanOption/kOTBooleanOptionSize then OTOptionManagement on OS X Carbon +// no longer returns -3151 but it still doesn't actually work -- no destination addresses +// are delivered by OTRcvUData. I think it's just a bug in OS X Carbon. +static const TSetByteOption kRcvDestAddrOption = +{ kOTOneByteOptionSize, INET_IP, IP_RCVDSTADDR, 0, true }; +//static const TSetBooleanOption kRcvDestAddrOption = +// { kOTBooleanOptionSize, INET_IP, IP_RCVDSTADDR, 0, true }; + +static const TSetByteOption kSetUnicastTTLOption = +{ kOTOneByteOptionSize, INET_IP, IP_TTL, 0, 255 }; + +static const TSetByteOption kSetMulticastTTLOption = +{ kOTOneByteOptionSize, INET_IP, IP_MULTICAST_TTL, 0, 255 }; + +static const TIPAddMulticastOption kAddLinkMulticastOption = +{ sizeof(TIPAddMulticastOption), INET_IP, IP_ADD_MEMBERSHIP, 0, { 224, 0, 0,251 }, { 0,0,0,0 } }; + +//static const TIPAddMulticastOption kAddAdminMulticastOption = +// { sizeof(TIPAddMulticastOption), INET_IP, IP_ADD_MEMBERSHIP, 0, { 239,255,255,251 }, { 0,0,0,0 } }; + +// Bind endpoint to port number. Don't specify any specific IP address -- +// we want to receive unicasts on all interfaces, as well as multicasts. +typedef struct { OTAddressType fAddressType; mDNSIPPort fPort; mDNSv4Addr fHost; UInt8 fUnused[8]; } mDNSInetAddress; +//static const mDNSInetAddress mDNSPortInetAddress = { AF_INET, { 0,0 }, { 0,0,0,0 } }; // For testing legacy client support +#define MulticastDNSPortAsNumber 5353 +static const mDNSInetAddress mDNSPortInetAddress = { AF_INET, { MulticastDNSPortAsNumber >> 8, MulticastDNSPortAsNumber & 0xFF }, { 0,0,0,0 } }; +static const TBind mDNSbindReq = { sizeof(mDNSPortInetAddress), sizeof(mDNSPortInetAddress), (UInt8*)&mDNSPortInetAddress, 0 }; + +static const TNetbuf zeroTNetbuf = { 0 }; + +// *************************************************************************** +// Functions + +mDNSlocal void SafeDebugStr(unsigned char *buffer) +{ + int i; + // Don't want semicolons in MacsBug messages -- they signify commands to execute + for (i=1; i<= buffer[0]; i++) if (buffer[i] == ';') buffer[i] = '.'; + DebugStr(buffer); +} + +#if MDNS_DEBUGMSGS +mDNSexport void debugf_(const char *format, ...) +{ + unsigned char buffer[256]; + va_list ptr; + va_start(ptr,format); + buffer[0] = (unsigned char)mDNS_vsnprintf((char*)buffer+1, 255, format, ptr); + va_end(ptr); +#if MDNS_ONLYSYSTEMTASK + buffer[1+buffer[0]] = 0; + fprintf(stderr, "%s\n", buffer+1); + fflush(stderr); +#else + SafeDebugStr(buffer); +#endif +} +#endif + +#if MDNS_BUILDINGSHAREDLIBRARY >= 2 +// When building the non-debug version of the Extension, intended to go on end-user systems, we don't want +// MacsBug breaks for *anything*, not even for the serious LogMsg messages that on OS X would be written to syslog +mDNSexport void LogMsg(const char *format, ...) { (void)format; } +#else +mDNSexport void LogMsg(const char *format, ...) +{ + unsigned char buffer[256]; + va_list ptr; + va_start(ptr,format); + buffer[0] = (unsigned char)mDNS_vsnprintf((char*)buffer+1, 255, format, ptr); + va_end(ptr); +#if MDNS_ONLYSYSTEMTASK + buffer[1+buffer[0]] = 0; + fprintf(stderr, "%s\n", buffer+1); + fflush(stderr); +#else + SafeDebugStr(buffer); +#endif +} +#endif + +mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end, + mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstPort) +{ + // Note: If we did multi-homing, we'd have to use the InterfaceID parameter to specify from which interface to send this response + #pragma unused(InterfaceID) + + InetAddress InetDest; + TUnitData senddata; + + if (dst->type != mDNSAddrType_IPv4) return(mStatus_NoError); + + InetDest.fAddressType = AF_INET; + InetDest.fPort = dstPort.NotAnInteger; + InetDest.fHost = dst->ip.v4.NotAnInteger; + + senddata.addr.maxlen = sizeof(InetDest); + senddata.addr.len = sizeof(InetDest); + senddata.addr.buf = (UInt8*)&InetDest; + senddata.opt = zeroTNetbuf; + senddata.udata.maxlen = (UInt32)((UInt8*)end - (UInt8*)msg); + senddata.udata.len = (UInt32)((UInt8*)end - (UInt8*)msg); + senddata.udata.buf = (UInt8*)msg; + + return(OTSndUData(m->p->ep, &senddata)); +} + +mDNSlocal OSStatus readpacket(mDNS *m) +{ + mDNSAddr senderaddr, destaddr; + mDNSInterfaceID interface; + mDNSIPPort senderport; + InetAddress sender; + char options[256]; + DNSMessage packet; + TUnitData recvdata; + OTFlags flags = 0; + OSStatus err; + + recvdata.addr.maxlen = sizeof(sender); + recvdata.addr.len = 0; + recvdata.addr.buf = (UInt8*)&sender; + recvdata.opt.maxlen = sizeof(options); + recvdata.opt.len = 0; + recvdata.opt.buf = (UInt8*)&options; + recvdata.udata.maxlen = sizeof(packet); + recvdata.udata.len = 0; + recvdata.udata.buf = (UInt8*)&packet; + + err = OTRcvUData(m->p->ep, &recvdata, &flags); + if (err && err != kOTNoDataErr) debugf("OTRcvUData error %d", err); + + if (err) return(err); + + senderaddr.type = mDNSAddrType_IPv4; + senderaddr.ip.v4.NotAnInteger = sender.fHost; + senderport.NotAnInteger = sender.fPort; + + destaddr.type = mDNSAddrType_IPv4; + destaddr.ip.v4 = zerov4Addr; + + #if OTCARBONAPPLICATION + // IP_RCVDSTADDR is known to fail on OS X Carbon, so we'll just assume the packet was probably multicast + destaddr.ip.v4 = AllDNSLinkGroup_v4.ip.v4; + #endif + + if (recvdata.opt.len) + { + TOption *c = nil; + while (1) + { + err = OTNextOption(recvdata.opt.buf, recvdata.opt.len, &c); + if (err || !c) break; + if (c->level == INET_IP && c->name == IP_RCVDSTADDR && c->len - kOTOptionHeaderSize == sizeof(destaddr.ip.v4)) + mDNSPlatformMemCopy(&destaddr.ip.v4, c->value, sizeof(destaddr.ip.v4)); + } + } + + interface = m->HostInterfaces->InterfaceID; + + if (flags & T_MORE) debugf("ERROR: OTRcvUData() buffer too small (T_MORE set)"); + else if (recvdata.addr.len < sizeof(InetAddress)) debugf("ERROR: recvdata.addr.len (%d) too short", recvdata.addr.len); + else mDNSCoreReceive(m, &packet, recvdata.udata.buf + recvdata.udata.len, &senderaddr, senderport, &destaddr, MulticastDNSPort, interface); + + return(err); +} + +mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS * const m, TCPSocketFlags flags, mDNSIPPort * port) +{ + (void)m; // Unused + (void)flags; // Unused + (void)port; // Unused + return NULL; +} + +mDNSexport TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd) +{ + (void)flags; // Unused + (void)sd; // Unused + return NULL; +} + +mDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock) +{ + (void)sock; // Unused + return -1; +} + +mDNSexport mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr * dst, mDNSOpaque16 dstport, mDNSInterfaceID InterfaceID, + TCPConnectionCallback callback, void * context) +{ + (void)sock; // Unused + (void)dst; // Unused + (void)dstport; // Unused + (void)InterfaceID; // Unused + (void)callback; // Unused + (void)context; // Unused + return(mStatus_UnsupportedErr); +} + +mDNSexport void mDNSPlatformTCPCloseConnection(TCPSocket *sd) +{ + (void)sd; // Unused +} + +mDNSexport long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed) +{ + (void)sock; // Unused + (void)buf; // Unused + (void)buflen; // Unused + (void)closed; // Unused + return(0); +} + +mDNSexport long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len) +{ + (void)sock; // Unused + (void)msg; // Unused + (void)len; // Unused + return(0); +} + +mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS * const m, mDNSIPPort port) +{ + (void)m; // Unused + (void)port; // Unused + return NULL; +} + +mDNSexport void mDNSPlatformUDPClose(UDPSocket *sock) +{ + (void)sock; // Unused +} + +mDNSlocal void mDNSOptionManagement(mDNS *const m) +{ + OSStatus err; + + // Make sure the length in the TNetbuf agrees with the length in the TOptionHeader + m->p->optReq.opt.len = m->p->optBlock.h.len; + m->p->optReq.opt.maxlen = m->p->optBlock.h.len; + if (m->p->optReq.opt.maxlen < 4) + m->p->optReq.opt.maxlen = 4; + + err = OTOptionManagement(m->p->ep, &m->p->optReq, NULL); + if (err) LogMsg("OTOptionManagement failed %d", err); +} + +mDNSlocal void mDNSinitComplete(mDNS *const m, mStatus result) +{ + m->mDNSPlatformStatus = result; + mDNSCoreInitComplete(m, mStatus_NoError); +} + +mDNSlocal pascal void mDNSNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie) +{ + mDNS *const m = (mDNS *const)contextPtr; + if (!m) debugf("mDNSNotifier FATAL ERROR! No context"); + switch (code) + { + case T_OPENCOMPLETE: + { + OSStatus err; + InetInterfaceInfo interfaceinfo; + if (result) { LogMsg("T_OPENCOMPLETE failed %d", result); mDNSinitComplete(m, result); return; } + //debugf("T_OPENCOMPLETE"); + m->p->ep = (EndpointRef)cookie; + //debugf("OTInetGetInterfaceInfo"); + // (In future may want to loop over all interfaces instead of just using kDefaultInetInterface) + err = OTInetGetInterfaceInfo(&interfaceinfo, kDefaultInetInterface); + if (err) { LogMsg("OTInetGetInterfaceInfo failed %d", err); mDNSinitComplete(m, err); return; } + + // Make our basic standard host resource records (address, PTR, etc.) + m->p->interface.InterfaceID = (mDNSInterfaceID)&m->p->interface; + m->p->interface.ip.type = mDNSAddrType_IPv4; + m->p->interface.ip.ip.v4.NotAnInteger = interfaceinfo.fAddress; + m->p->interface.mask.type = mDNSAddrType_IPv4; + m->p->interface.mask.ip.v4.NotAnInteger = interfaceinfo.fNetmask; + m->p->interface.ifname[0] = 0; + m->p->interface.Advertise = m->AdvertiseLocalAddresses; + m->p->interface.McastTxRx = mDNStrue; + } + + case T_OPTMGMTCOMPLETE: + case T_BINDCOMPLETE: + // IP_RCVDSTADDR is known to fail on OS X Carbon, so we don't want to abort for that error + // (see comment above at the definition of kRcvDestAddrOption) + #if OTCARBONAPPLICATION + if (result && m->p->mOTstate == mOT_RcvDestAddr) + LogMsg("Carbon IP_RCVDSTADDR option failed %d; continuing anyway", result); + else + #endif + if (result) { LogMsg("T_OPTMGMTCOMPLETE/T_BINDCOMPLETE %d failed %d", m->p->mOTstate, result); mDNSinitComplete(m, result); return; } + //LogMsg("T_OPTMGMTCOMPLETE/T_BINDCOMPLETE %d", m->p->mOTstate); + switch (++m->p->mOTstate) + { + case mOT_ReusePort: m->p->optBlock.b = kReusePortOption; mDNSOptionManagement(m); break; + case mOT_RcvDestAddr: m->p->optBlock.i = kRcvDestAddrOption; mDNSOptionManagement(m); break; + case mOT_SetUTTL: m->p->optBlock.i = kSetUnicastTTLOption; mDNSOptionManagement(m); break; + case mOT_SetMTTL: m->p->optBlock.i = kSetMulticastTTLOption; mDNSOptionManagement(m); break; + case mOT_LLScope: m->p->optBlock.m = kAddLinkMulticastOption; mDNSOptionManagement(m); break; +// case mOT_AdminScope: m->p->optBlock.m = kAddAdminMulticastOption; mDNSOptionManagement(m); break; + case mOT_Bind: OTBind(m->p->ep, (TBind*)&mDNSbindReq, NULL); break; + case mOT_Ready: mDNSinitComplete(m, mStatus_NoError); + // Can't do mDNS_RegisterInterface until *after* mDNSinitComplete has set m->mDNSPlatformStatus to mStatus_NoError + mDNS_RegisterInterface(m, &m->p->interface, mDNSfalse); + break; + default: LogMsg("Unexpected m->p->mOTstate %d", m->p->mOTstate-1); + } + break; + + case T_DATA: + //debugf("T_DATA"); + while (readpacket(m) == kOTNoError) continue; // Read packets until we run out + break; + + case kOTProviderWillClose: LogMsg("kOTProviderWillClose"); break; + case kOTProviderIsClosed: // Machine is going to sleep, shutting down, or reconfiguring IP + LogMsg("kOTProviderIsClosed"); + if (m->p->mOTstate == mOT_Ready) + { + m->p->mOTstate = mOT_Closed; + mDNS_DeregisterInterface(m, &m->p->interface, mDNSfalse); + } + if (m->p->ep) { OTCloseProvider(m->p->ep); m->p->ep = NULL; } + break; // Do we need to do anything? + + default: debugf("mDNSNotifier: Unexpected OTEventCode %X", code); + break; + } +} + +#if MDNS_ONLYSYSTEMTASK + +static Boolean ONLYSYSTEMTASKevent; +static void *ONLYSYSTEMTASKcontextPtr; +static OTEventCode ONLYSYSTEMTASKcode; +static OTResult ONLYSYSTEMTASKresult; +static void *ONLYSYSTEMTASKcookie; + +mDNSlocal pascal void CallmDNSNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie) +{ + ONLYSYSTEMTASKcontextPtr = contextPtr; + ONLYSYSTEMTASKcode = code; + ONLYSYSTEMTASKresult = result; + ONLYSYSTEMTASKcookie = cookie; +} + +#else + +mDNSlocal pascal void CallmDNSNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie) +{ + mDNS *const m = (mDNS *const)contextPtr; + if (!m) debugf("mDNSNotifier FATAL ERROR! No context"); + if (m->p->nesting) LogMsg("CallmDNSNotifier ERROR! OTEnterNotifier is supposed to suppress notifier callbacks"); + mDNSNotifier(contextPtr, code, result, cookie); +} + +#endif + +static OTNotifyUPP CallmDNSNotifierUPP; + +mDNSlocal OSStatus mDNSOpenEndpoint(const mDNS *const m) +{ + OSStatus err; + // m->optReq is pre-set to point to the shared m->optBlock + // m->optBlock is filled in by each OTOptionManagement call + m->p->optReq.opt.maxlen = sizeof(m->p->optBlock); + m->p->optReq.opt.len = sizeof(m->p->optBlock); + m->p->optReq.opt.buf = (UInt8*)&m->p->optBlock; + m->p->optReq.flags = T_NEGOTIATE; + + // Open an endpoint and start answering queries + //printf("Opening endpoint now...\n"); + m->p->ep = NULL; + m->p->mOTstate = mOT_Start; + err = OTAsyncOpenEndpoint(OTCreateConfiguration(kUDPName), 0, NULL, CallmDNSNotifierUPP, (void*)m); + if (err) { LogMsg("ERROR: OTAsyncOpenEndpoint(UDP) failed with error <%d>", err); return(err); } + return(kOTNoError); +} + +// Define these here because they're not in older versions of OpenTransport.h +enum +{ + xOTStackIsLoading = 0x27000001, /* Sent before Open Transport attempts to load the TCP/IP protocol stack.*/ + xOTStackWasLoaded = 0x27000002, /* Sent after the TCP/IP stack has been successfully loaded.*/ + xOTStackIsUnloading = 0x27000003 /* Sent before Open Transport unloads the TCP/IP stack.*/ +}; + +static mDNS *ClientNotifierContext; + +mDNSlocal pascal void ClientNotifier(void *contextPtr, OTEventCode code, OTResult result, void *cookie) +{ + mDNS *const m = ClientNotifierContext; + + #pragma unused(contextPtr) // Usually zero (except one in the 'xOTStackIsLoading' case) + #pragma unused(cookie) // Usually 'ipv4' (except for kOTPortNetworkChange) + #pragma unused(result) // Usually zero + + switch (code) + { + case xOTStackIsLoading: break; + case xOTStackWasLoaded: if (m->p->mOTstate == mOT_Closed) + { + LogMsg("kOTStackWasLoaded: Re-opening endpoint"); + if (m->p->ep) + LogMsg("kOTStackWasLoaded: ERROR: m->p->ep already set"); + m->mDNSPlatformStatus = mStatus_Waiting; + m->p->mOTstate = mOT_Reset; + #if !MDNS_ONLYSYSTEMTASK + mDNSOpenEndpoint(m); + #endif + } + else + LogMsg("kOTStackWasLoaded (no action)"); + break; + case xOTStackIsUnloading: break; + case kOTPortNetworkChange: break; + default: debugf("ClientNotifier unknown code %X, %X, %d", contextPtr, code, result); break; + } +} + +#if TARGET_API_MAC_CARBON + +mDNSlocal void GetUserSpecifiedComputerName(domainlabel *const namelabel) +{ + CFStringRef cfs = CSCopyMachineName(); + CFStringGetPascalString(cfs, namelabel->c, sizeof(*namelabel), kCFStringEncodingUTF8); + CFRelease(cfs); +} + +#else + +mDNSlocal OSStatus ConvertStringHandleToUTF8(const StringHandle machineName, UInt8 *const utf8, ByteCount maxlen) +{ + OSStatus status; + TextEncoding utf8TextEncoding, SystemTextEncoding; + UnicodeMapping theMapping; + TextToUnicodeInfo textToUnicodeInfo; + ByteCount unicodelen = 0; + + if (maxlen > 255) maxlen = 255; // Can't put more than 255 in a Pascal String + + utf8TextEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kUnicodeUTF8Format); + UpgradeScriptInfoToTextEncoding(smSystemScript, kTextLanguageDontCare, kTextRegionDontCare, NULL, &SystemTextEncoding); + theMapping.unicodeEncoding = utf8TextEncoding; + theMapping.otherEncoding = SystemTextEncoding; + theMapping.mappingVersion = kUnicodeUseLatestMapping; + status = CreateTextToUnicodeInfo(&theMapping, &textToUnicodeInfo); + if (status == noErr) + { + status = ConvertFromPStringToUnicode(textToUnicodeInfo, *machineName, maxlen, &unicodelen, (UniCharArrayPtr)&(utf8[1])); + DisposeTextToUnicodeInfo(&textToUnicodeInfo); + } + utf8[0] = (UInt8)unicodelen; + return(status); +} + +mDNSlocal void GetUserSpecifiedComputerName(domainlabel *const namelabel) +{ + StringHandle machineName = GetString(-16413); // Get machine name set in file sharing + if (machineName) + { + char machineNameState = HGetState((Handle)machineName); + HLock((Handle)machineName); + ConvertStringHandleToUTF8(machineName, namelabel->c, MAX_DOMAIN_LABEL); + HSetState((Handle)machineName, machineNameState); + } +} + +#endif + +static pascal void mDNSTimerTask(void *arg) +{ +#if MDNS_ONLYSYSTEMTASK +#pragma unused(arg) + ONLYSYSTEMTASKevent = true; +#else + mDNS *const m = (mDNS *const)arg; + if (!m->p->ep) LogMsg("mDNSTimerTask NO endpoint"); + if (m->mDNS_busy) LogMsg("mDNS_busy"); + if (m->p->nesting) LogMsg("mDNSTimerTask ERROR! OTEnterNotifier is supposed to suppress timer callbacks too"); + + // If our timer fires at a time when we have no endpoint, ignore it -- + // once we reopen our endpoint and get our T_BINDCOMPLETE message we'll call + // mDNS_RegisterInterface(), which does a lock/unlock, which retriggers the timer. + // Likewise, if m->mDNS_busy or m->p->nesting, we'll catch this on the unlock + if (m->p->ep && m->mDNS_busy == 0 && m->p->nesting == 0) mDNS_Execute(m); +#endif +} + +#if TEST_SLEEP +long sleep, wake, mode; +#endif + +mDNSexport mStatus mDNSPlatformInit (mDNS *const m) +{ + OSStatus err = InitOpenTransport(); + + ClientNotifierContext = m; + // Note: OTRegisterAsClient returns kOTNotSupportedErr when running as Carbon code on OS X + // -- but that's okay, we don't need a ClientNotifier when running as Carbon code on OS X + OTRegisterAsClient(NULL, NewOTNotifyUPP(ClientNotifier)); + + m->p->OTTimerTask = OTCreateTimerTask(NewOTProcessUPP(mDNSTimerTask), m); + m->p->nesting = 0; + +#if TEST_SLEEP + sleep = TickCount() + 600; + wake = TickCount() + 1200; + mode = 0; +#endif + + // Set up the nice label + m->nicelabel.c[0] = 0; + GetUserSpecifiedComputerName(&m->nicelabel); +// m->nicelabel = *(domainlabel*)"\pStu"; // For conflict testing + if (m->nicelabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->nicelabel, "Macintosh"); + + // Set up the RFC 1034-compliant label + m->hostlabel.c[0] = 0; + ConvertUTF8PstringToRFC1034HostLabel(m->nicelabel.c, &m->hostlabel); + if (m->hostlabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->hostlabel, "Macintosh"); + + mDNS_SetFQDN(m); + + // When it's finished mDNSOpenEndpoint asynchronously calls mDNSinitComplete() and then mDNS_RegisterInterface() + CallmDNSNotifierUPP = NewOTNotifyUPP(CallmDNSNotifier); + err = mDNSOpenEndpoint(m); + if (err) + { + LogMsg("mDNSOpenEndpoint failed %d", err); + if (m->p->OTTimerTask) OTDestroyTimerTask(m->p->OTTimerTask); + OTUnregisterAsClient(); + CloseOpenTransport(); + } + return(err); +} + +extern void mDNSPlatformClose (mDNS *const m) +{ + if (m->p->mOTstate == mOT_Ready) + { + m->p->mOTstate = mOT_Closed; + mDNS_DeregisterInterface(m, &m->p->interface, mDNSfalse); + } + if (m->p->ep) { OTCloseProvider (m->p->ep); m->p->ep = NULL; } + if (m->p->OTTimerTask) { OTDestroyTimerTask(m->p->OTTimerTask); m->p->OTTimerTask = 0; } + + OTUnregisterAsClient(); + CloseOpenTransport(); +} + +#if MDNS_ONLYSYSTEMTASK +extern void mDNSPlatformIdle(mDNS *const m); +mDNSexport void mDNSPlatformIdle(mDNS *const m) +{ + while (ONLYSYSTEMTASKcontextPtr) + { + void *contextPtr = ONLYSYSTEMTASKcontextPtr; + ONLYSYSTEMTASKcontextPtr = NULL; + mDNSNotifier(contextPtr, ONLYSYSTEMTASKcode, ONLYSYSTEMTASKresult, ONLYSYSTEMTASKcookie); + } + if (ONLYSYSTEMTASKevent) + { + ONLYSYSTEMTASKevent = false; + mDNS_Execute(m); + } + + if (m->p->mOTstate == mOT_Reset) + { + printf("\n"); + printf("******************************************************************************\n"); + printf("\n"); + printf("Reopening endpoint\n"); + mDNSOpenEndpoint(m); + m->ResourceRecords = NULL; + } + +#if TEST_SLEEP + switch (mode) + { + case 0: if ((long)TickCount() - sleep >= 0) { mDNSCoreMachineSleep(m, 1); mode++; } + break; + case 1: if ((long)TickCount() - wake >= 0) { mDNSCoreMachineSleep(m, 0); mode++; } + break; + } +#endif +} +#endif + +mDNSexport void mDNSPlatformLock(const mDNS *const m) +{ + if (!m) { DebugStr("\pmDNSPlatformLock m NULL!"); return; } + if (!m->p) { DebugStr("\pmDNSPlatformLock m->p NULL!"); return; } + + // If we try to call OTEnterNotifier and fail because we're already running at + // Notifier context, then make sure we don't do the matching OTLeaveNotifier() on exit. + // If we haven't even opened our endpoint yet, then just increment m->p->nesting for the same reason + if (m->p->mOTstate == mOT_Ready && !m->p->ep) DebugStr("\pmDNSPlatformLock: m->p->mOTstate == mOT_Ready && !m->p->ep"); + if (!m->p->ep || m->p->nesting || OTEnterNotifier(m->p->ep) == false) m->p->nesting++; +} + +mDNSlocal void ScheduleNextTimerCallback(const mDNS *const m) +{ + if (m->mDNSPlatformStatus == mStatus_NoError) + { + SInt32 interval = m->NextScheduledEvent - mDNS_TimeNow_NoLock(m); + if (interval < 1) interval = 1; + else if (interval > 0x70000000 / 1000) interval = 0x70000000 / mDNSPlatformOneSecond; + else interval = (interval * 1000 + mDNSPlatformOneSecond-1)/ mDNSPlatformOneSecond; + OTScheduleTimerTask(m->p->OTTimerTask, (OTTimeout)interval); + } +} + +mDNSexport void mDNSPlatformUnlock(const mDNS *const m) +{ + if (!m) { DebugStr("\pmDNSPlatformUnlock m NULL!"); return; } + if (!m->p) { DebugStr("\pmDNSPlatformUnlock m->p NULL!"); return; } + + if (m->p->ep && m->mDNS_busy == 0) ScheduleNextTimerCallback(m); + + if (m->p->nesting) m->p->nesting--; + else OTLeaveNotifier(m->p->ep); +} + +mDNSexport void mDNSPlatformStrCopy( void *dst, const void *src) { OTStrCopy((char*)dst, (char*)src); } +mDNSexport UInt32 mDNSPlatformStrLen ( const void *src) { return(OTStrLength((char*)src)); } +mDNSexport void mDNSPlatformMemCopy( void *dst, const void *src, UInt32 len) { OTMemcpy(dst, src, len); } +mDNSexport mDNSBool mDNSPlatformMemSame(const void *dst, const void *src, UInt32 len) { return(OTMemcmp(dst, src, len)); } +mDNSexport void mDNSPlatformMemZero( void *dst, UInt32 len) { OTMemzero(dst, len); } +mDNSexport void * mDNSPlatformMemAllocate(mDNSu32 len) { return(OTAllocMem(len)); } +mDNSexport void mDNSPlatformMemFree(void *mem) { OTFreeMem(mem); } +mDNSexport mDNSu32 mDNSPlatformRandomSeed(void) { return(TickCount()); } +mDNSexport mStatus mDNSPlatformTimeInit(void) { return(mStatus_NoError); } +mDNSexport SInt32 mDNSPlatformRawTime() { return((SInt32)TickCount()); } +mDNSexport SInt32 mDNSPlatformOneSecond = 60; + +mDNSexport mDNSs32 mDNSPlatformUTC(void) +{ + // Classic Mac OS since Midnight, 1st Jan 1904 + // Standard Unix counts from 1970 + // This value adjusts for the 66 years and 17 leap-days difference + mDNSu32 SecsSince1904; + MachineLocation ThisLocation; + #define TIME_ADJUST (((1970 - 1904) * 365 + 17) * 24 * 60 * 60) + #define ThisLocationGMTdelta ((ThisLocation.u.gmtDelta << 8) >> 8) + GetDateTime(&SecsSince1904); + ReadLocation(&ThisLocation); + return((mDNSs32)(SecsSince1904 - ThisLocationGMTdelta - TIME_ADJUST)); +} |