From 1a1751620d06770d59106ce41cd9a1e82d48bc27 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 30 Sep 2009 19:06:26 +0000 Subject: [PATCH] mDNSResponder-214.tar.gz --- .../PrinterSetupWizardLocRes.rc | 2 + Clients/PrinterSetupWizard/ThirdPage.cpp | 19 +- Clients/PrinterSetupWizard/resource_exe.h | 2 + Clients/PrinterSetupWizard/resource_loc_res.h | 2 + Clients/PrinterSetupWizard/resource_res.h | 2 + .../mDNSNetMonitor.manifest | 12 + .../mDNSNetMonitor.vcproj | 292 ++++++++++++++++++ Makefile | 2 +- mDNSCore/DNSCommon.c | 9 +- mDNSCore/mDNS.c | 168 +++++++--- mDNSCore/mDNSEmbeddedAPI.h | 27 +- mDNSMacOSX/LegacyNATTraversal.c | 2 +- mDNSMacOSX/daemon.c | 2 +- mDNSMacOSX/mDNSMacOSX.c | 218 ++++++++++++- mDNSPosix/NetMonitor.c | 57 +++- mDNSResponder.sln | 158 ++++++++++ mDNSShared/dns_sd.h | 2 +- mDNSShared/uds_daemon.c | 41 ++- mDNSWindows/DLLX/DLLX.vcproj | 6 +- mDNSWindows/PosixCompat.c | 141 +++++++++ mDNSWindows/PosixCompat.h | 78 +++++ mDNSWindows/Secret.c | 64 ++-- mDNSWindows/SystemService/Service.c | 203 +++++++++++- mDNSWindows/SystemService/Service.h | 38 +++ mDNSWindows/SystemService/Service.vcproj | 26 +- mDNSWindows/SystemService/main.c | 40 +++ mDNSWindows/WinVersRes.h | 14 +- mDNSWindows/mDNSWin32.c | 204 +++++++++++- mDNSWindows/mDNSWin32.h | 14 + 29 files changed, 1698 insertions(+), 147 deletions(-) create mode 100755 Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.manifest create mode 100755 Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj create mode 100755 mDNSWindows/PosixCompat.c create mode 100755 mDNSWindows/PosixCompat.h create mode 100755 mDNSWindows/SystemService/Service.h create mode 100755 mDNSWindows/SystemService/main.c diff --git a/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc b/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc index d535344..a07023e 100755 --- a/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc +++ b/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc @@ -256,6 +256,8 @@ BEGIN IDS_INSTALL_ERROR_CAPTION "Error" IDS_INSTALL_ERROR_MESSAGE "You do not have sufficient access to your computer to connect to the selected printer." + IDS_NO_MATCH_INF_FILE "The software that you chose does not match the selected printer." + IDS_NO_MATCH_INF_FILE_CAPTION "Select Device" IDS_BAD_INF_FILE "The specified location does not contain information about your printer" IDS_BAD_INF_FILE_CAPTION "Select Device" IDS_MANUFACTURER_HEADING "Manufacturer" diff --git a/Clients/PrinterSetupWizard/ThirdPage.cpp b/Clients/PrinterSetupWizard/ThirdPage.cpp index f3d0432..8981bd4 100644 --- a/Clients/PrinterSetupWizard/ThirdPage.cpp +++ b/Clients/PrinterSetupWizard/ThirdPage.cpp @@ -17,6 +17,9 @@ Change History (most recent first): $Log: ThirdPage.cpp,v $ +Revision 1.42 2009/07/07 22:04:55 herscher + LOC Impact: Need custom text when selecting the wrong printer driver + Revision 1.41 2009/06/18 18:05:50 herscher Eliminate the first screen of Printer Wizard and maybe combine others ("I'm Feeling Lucky") @@ -1136,6 +1139,7 @@ OSStatus CThirdPage::MatchPrinter(Manufacturers & manufacturers, Printer * print if (found) { text.LoadString(IDS_PRINTER_MATCH_GOOD); + err = kNoErr; } else if ( MatchGeneric( manufacturers, printer, service, &genericManufacturer, &genericModel ) ) { @@ -1157,6 +1161,8 @@ OSStatus CThirdPage::MatchPrinter(Manufacturers & manufacturers, Printer * print SelectMatch( manufacturers, printer, service, genericManufacturer, genericModel ); text.LoadString(IDS_PRINTER_MATCH_MAYBE); } + + err = kNoErr; } else { @@ -1193,6 +1199,8 @@ OSStatus CThirdPage::MatchPrinter(Manufacturers & manufacturers, Printer * print AutoScroll(m_manufacturerListCtrl, nIndex); } } + + err = kUnknownErr; } m_printerSelectionText.SetWindowText(text); @@ -1651,7 +1659,16 @@ void CThirdPage::OnBnClickedHaveDisk() { PopulateUI( manufacturers ); - MatchPrinter( manufacturers, printer, service, false ); + if ( MatchPrinter( manufacturers, printer, service, false ) != kNoErr ) + { + CString errorMessage; + CString errorCaption; + + errorMessage.LoadString( IDS_NO_MATCH_INF_FILE ); + errorCaption.LoadString( IDS_NO_MATCH_INF_FILE_CAPTION ); + + MessageBox( errorMessage, errorCaption, MB_OK ); + } break; } diff --git a/Clients/PrinterSetupWizard/resource_exe.h b/Clients/PrinterSetupWizard/resource_exe.h index 4a4f980..bb2faaf 100755 --- a/Clients/PrinterSetupWizard/resource_exe.h +++ b/Clients/PrinterSetupWizard/resource_exe.h @@ -51,6 +51,8 @@ #define IDS_PRINTER_UNAVAILABLE 145 #define IDS_BAD_INF_FILE 150 #define IDS_BAD_INF_FILE_CAPTION 151 +#define IDS_NO_MATCH_INF_FILE 152 +#define IDS_NO_MATCH_INF_FILE_CAPTION 153 #define IDC_BUTTON1 1000 #define IDC_LIST1 1000 #define IDC_BROWSE_LIST 1000 diff --git a/Clients/PrinterSetupWizard/resource_loc_res.h b/Clients/PrinterSetupWizard/resource_loc_res.h index 951c54d..3aac90d 100755 --- a/Clients/PrinterSetupWizard/resource_loc_res.h +++ b/Clients/PrinterSetupWizard/resource_loc_res.h @@ -52,6 +52,8 @@ #define IDS_PRINTER_UNAVAILABLE 145 #define IDS_BAD_INF_FILE 150 #define IDS_BAD_INF_FILE_CAPTION 151 +#define IDS_NO_MATCH_INF_FILE 152 +#define IDS_NO_MATCH_INF_FILE_CAPTION 153 #define IDC_BUTTON1 1000 #define IDC_LIST1 1000 #define IDC_BROWSE_LIST 1000 diff --git a/Clients/PrinterSetupWizard/resource_res.h b/Clients/PrinterSetupWizard/resource_res.h index 4a4f980..bb2faaf 100755 --- a/Clients/PrinterSetupWizard/resource_res.h +++ b/Clients/PrinterSetupWizard/resource_res.h @@ -51,6 +51,8 @@ #define IDS_PRINTER_UNAVAILABLE 145 #define IDS_BAD_INF_FILE 150 #define IDS_BAD_INF_FILE_CAPTION 151 +#define IDS_NO_MATCH_INF_FILE 152 +#define IDS_NO_MATCH_INF_FILE_CAPTION 153 #define IDC_BUTTON1 1000 #define IDC_LIST1 1000 #define IDC_BROWSE_LIST 1000 diff --git a/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.manifest b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.manifest new file mode 100755 index 0000000..554f590 --- /dev/null +++ b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.manifest @@ -0,0 +1,12 @@ + + + + mDNSNetMonitor command line utility. + + + + + + + + diff --git a/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj new file mode 100755 index 0000000..85ede41 --- /dev/null +++ b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Makefile b/Makefile index 1f62270..aaf7bc6 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ include /Developer/Makefiles/pb_makefiles/platform.make -MVERS = "mDNSResponder-212.1" +MVERS = "mDNSResponder-214" DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig" diff --git a/mDNSCore/DNSCommon.c b/mDNSCore/DNSCommon.c index b001a70..bf57929 100644 --- a/mDNSCore/DNSCommon.c +++ b/mDNSCore/DNSCommon.c @@ -606,6 +606,7 @@ mDNSexport const mDNSInterfaceID mDNSInterface_Unicast = (mDNSInterfaceID)2; #define SSHPortAsNumber 22 #define UnicastDNSPortAsNumber 53 #define SSDPPortAsNumber 1900 +#define IPSECPortAsNumber 4500 #define NSIPCPortAsNumber 5030 // Port used for dnsextd to talk to local nameserver bound to loopback #define NATPMPAnnouncementPortAsNumber 5350 #define NATPMPPortAsNumber 5351 @@ -619,6 +620,7 @@ mDNSexport const mDNSIPPort DiscardPort = { { DiscardPortAsNumber mDNSexport const mDNSIPPort SSHPort = { { SSHPortAsNumber >> 8, SSHPortAsNumber & 0xFF } }; mDNSexport const mDNSIPPort UnicastDNSPort = { { UnicastDNSPortAsNumber >> 8, UnicastDNSPortAsNumber & 0xFF } }; mDNSexport const mDNSIPPort SSDPPort = { { SSDPPortAsNumber >> 8, SSDPPortAsNumber & 0xFF } }; +mDNSexport const mDNSIPPort IPSECPort = { { IPSECPortAsNumber >> 8, IPSECPortAsNumber & 0xFF } }; mDNSexport const mDNSIPPort NSIPCPort = { { NSIPCPortAsNumber >> 8, NSIPCPortAsNumber & 0xFF } }; mDNSexport const mDNSIPPort NATPMPAnnouncementPort = { { NATPMPAnnouncementPortAsNumber >> 8, NATPMPAnnouncementPortAsNumber & 0xFF } }; mDNSexport const mDNSIPPort NATPMPPort = { { NATPMPPortAsNumber >> 8, NATPMPPortAsNumber & 0xFF } }; @@ -2833,7 +2835,7 @@ mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg, // embedded systems) putting a 9kB object on the stack isn't a big problem. LargeCacheRecord largecr; ptr = GetLargeResourceRecord(m, msg, ptr, end, mDNSInterface_Any, kDNSRecordTypePacketAns, &largecr); - if (ptr) LogMsg("%2d TTL%7d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r)); + if (ptr) LogMsg("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r)); } if (!ptr) LogMsg("ERROR: Premature end of packet data"); return(ptr); @@ -3048,7 +3050,8 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m) #endif if (e - m->NextCacheCheck > 0) e = m->NextCacheCheck; if (e - m->NextScheduledSPS > 0) e = m->NextScheduledSPS; - if (m->SleepLimit && e - m->NextScheduledSPRetry > 0) e = m->NextScheduledSPRetry; + // NextScheduledSPRetry only valid when DelaySleep not set + if (!m->DelaySleep && m->SleepLimit && e - m->NextScheduledSPRetry > 0) e = m->NextScheduledSPRetry; if (m->DelaySleep && e - m->DelaySleep > 0) e = m->DelaySleep; if (m->SuppressSending) @@ -3100,7 +3103,7 @@ mDNSexport void ShowTaskSchedulingError(mDNS *const m) LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp); if (m->timenow - m->NextScheduledSPS >= 0) LogMsg("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS); - if (m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0) + if (!m->DelaySleep && m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0) LogMsg("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry); if (m->DelaySleep && m->timenow - m->DelaySleep >= 0) LogMsg("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep); diff --git a/mDNSCore/mDNS.c b/mDNSCore/mDNS.c index c267896..8fe2a80 100755 --- a/mDNSCore/mDNS.c +++ b/mDNSCore/mDNS.c @@ -38,9 +38,13 @@ Change History (most recent first): $Log: mDNS.c,v $ -Revision 1.969.2.1 2009/07/23 23:41:25 cheshire +Revision 1.970.2.1 2009/07/23 23:36:04 cheshire Sleep Proxy: Ten-second maintenance wake not long enough to reliably get network connectivity +Revision 1.970 2009/07/11 01:59:27 cheshire + Sleep Proxy: Add support for using sleep proxy in local network interface hardware +When going to sleep, try calling ActivateLocalProxy before registering with remote sleep proxy + Revision 1.969 2009/06/30 21:18:19 cheshire Plugging and unplugging the power cable shouldn't cause a network change event Additional fixes: @@ -3886,6 +3890,21 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco // which we would subsequently cancel and retract if the CNAME referral record were removed. // In reality this is such a corner case we'll ignore it until someone actually needs it. LogInfo("AnswerCurrentQuestionWithResourceRecord: following CNAME referral for %s", CRDisplayString(m, rr)); + + // If this query is a duplicate of another query, UpdateQuestionDuplicates called from + // mDNS_StopQuery_internal copies the value of CNAMEReferrals from this query to the other + // query on the Questions list. By setting the new value before calling mDNS_StopQuery_internal, + // we ensure that the duplicate question gets a hgigher value and eventually the check for 10 above + // would be true. Otherwise, the two queries would end up as active questions + // sending mDNSResponder in an infinite loop e.g., Two queries starting off unique but receives + // a CNAME response that refers to itself (test IN CNAME test) which makes it a duplicate of + // one another. This fix now will make sure that stop at the 10th iteration. + // + // Though CNAME records that refer to itself are not added anymore in mDNSCoreReceiveResponse, this fix is + // still needed to catch the cases where the CNAME referral spans across multiple records with a potential + // cycle in it which in turn can make multiple queries duplicate of each other + + q->CNAMEReferrals = c; mDNS_StopQuery_internal(m, q); // Stop old query AssignDomainName(&q->qname, &rr->resrec.rdata->u.name); // Update qname q->qnamehash = DomainNameHashValue(&q->qname); // and namehash @@ -4130,7 +4149,7 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, CacheGroup *const cg) if (m->timenow - event >= 0) // If expired, delete it { *rp = rr->next; // Cut it from the list - verbosedebugf("CheckCacheExpiration: Deleting%7d %4d %p %s", + verbosedebugf("CheckCacheExpiration: Deleting%7d %7d %p %s", m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr)); if (rr->CRActiveQuestion) // If this record has one or more active questions, tell them it's going away { @@ -4877,6 +4896,8 @@ mDNSlocal void NetWakeResolve(mDNS *const m, DNSQuestion *question, const Resour if (!AddRecord) return; // Don't care about REMOVE events if (answer->rrtype != question->qtype) return; // Don't care about CNAMEs + // if (answer->rrtype == kDNSType_AAAA) return; // To test failing to resolve sleep proxy's address + mDNS_StopQuery(m, question); question->ThisQInterval = -1; @@ -4920,9 +4941,27 @@ mDNSexport mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m) return mDNSfalse; } +mDNSlocal void SendSleepGoodbyes(mDNS *const m) + { + AuthRecord *rr; + m->SleepState = SleepState_Sleeping; + +#ifndef UNICAST_DISABLED + SleepServiceRegistrations(m); + SleepRecordRegistrations(m); // If we have no SPS, need to deregister our uDNS records +#endif + + // Mark all the records we need to deregister and send them + for (rr = m->ResourceRecords; rr; rr=rr->next) + if (rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye) + rr->ImmedAnswer = mDNSInterfaceMark; + SendResponses(m); + } + // BeginSleepProcessing is called, with the lock held, from either mDNS_Execute or mDNSCoreMachineSleep mDNSlocal void BeginSleepProcessing(mDNS *const m) { + mDNSBool SendGoodbyes = mDNStrue; const CacheRecord *sps[3] = { mDNSNULL }; m->NextScheduledSPRetry = m->timenow; @@ -4935,6 +4974,16 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m) for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) { if (!intf->NetWake) LogSPS("BeginSleepProcessing: %-6s not capable of magic packet wakeup", intf->ifname); +#if APPLE_OSX_mDNSResponder + else if (ActivateLocalProxy(m, intf->ifname) == mStatus_NoError) + { + SendGoodbyes = mDNSfalse; + LogSPS("BeginSleepProcessing: %-6s using local proxy", intf->ifname); + // This will leave m->SleepState set to SleepState_Transferring, + // which is okay because with no outstanding resolves, or updates in flight, + // mDNSCoreReadyForSleep() will conclude correctly that all the updates have already completed + } +#endif // APPLE_OSX_mDNSResponder else { FindSPSInCache(m, &intf->NetWakeBrowse, sps); @@ -4942,6 +4991,7 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m) else { int i; + SendGoodbyes = mDNSfalse; intf->NextSPSAttempt = 0; intf->NextSPSAttemptTime = m->timenow + mDNSPlatformOneSecond; // Don't need to set m->NextScheduledSPRetry here because we already set "m->NextScheduledSPRetry = m->timenow" above @@ -4969,22 +5019,10 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m) } } - if (!sps[0]) // If we didn't find even one Sleep Proxy + if (SendGoodbyes) // If we didn't find even one Sleep Proxy { - AuthRecord *rr; LogSPS("BeginSleepProcessing: Not registering with Sleep Proxy Server"); - m->SleepState = SleepState_Sleeping; - -#ifndef UNICAST_DISABLED - SleepServiceRegistrations(m); - SleepRecordRegistrations(m); // If we have no SPS, need to deregister our uDNS records -#endif - - // Mark all the records we need to deregister and send them - for (rr = m->ResourceRecords; rr; rr=rr->next) - if (rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye) - rr->ImmedAnswer = mDNSInterfaceMark; - SendResponses(m); + SendSleepGoodbyes(m); } } @@ -5103,7 +5141,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep) mDNS_Unlock(m); } -mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m) +mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now) { DNSQuestion *q; AuthRecord *rr; @@ -5112,26 +5150,43 @@ mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m) mDNS_Lock(m); - if (m->NextScheduledSPRetry - m->timenow > 0) goto notready; + if (m->DelaySleep) goto notready; - m->NextScheduledSPRetry = m->timenow + 0x40000000UL; + // If we've not hit the sleep limit time, and it's not time for our next retry, we can skip these checks + if (m->SleepLimit - now > 0 && m->NextScheduledSPRetry - now > 0) goto notready; - if (m->DelaySleep) goto notready; + m->NextScheduledSPRetry = now + 0x40000000UL; // See if we might need to retransmit any lost Sleep Proxy Registrations for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) if (intf->NextSPSAttempt >= 0) { - if (m->timenow - intf->NextSPSAttemptTime >= 0) + if (now - intf->NextSPSAttemptTime >= 0) { LogSPS("ReadyForSleep retrying SPS %s %d", intf->ifname, intf->NextSPSAttempt); SendSPSRegistration(m, intf, zeroID); + // Don't need to "goto notready" here, becase if we do still have record registrations + // that have not been acknowledged yet, we'll catch that in the record list scan below. } else if (m->NextScheduledSPRetry - intf->NextSPSAttemptTime > 0) m->NextScheduledSPRetry = intf->NextSPSAttemptTime; } + // Scan list of interfaces, and see if we're still waiting for any sleep proxy resolves to complete + for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) + if (intf->NetWakeResolve[0].ThisQInterval >= 0) + { + LogSPS("ReadyForSleep waiting for SPS Resolve %s %##s (%s)", intf->ifname, intf->NetWakeResolve[0].qname.c, DNSTypeName(intf->NetWakeResolve[0].qtype)); + goto spsnotready; + } + + // Scan list of registered records + for (rr = m->ResourceRecords; rr; rr = rr->next) + if (!AuthRecord_uDNS(rr)) + if (!mDNSOpaque16IsZero(rr->updateid)) + { LogSPS("ReadyForSleep waiting for SPS Update ID %d %s", mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto spsnotready; } + // Scan list of private LLQs, and make sure they've all completed their handshake with the server for (q = m->Questions; q; q = q->next) if (!mDNSOpaque16IsZero(q->TargetQID) && q->LongLived && q->ReqLease == 0 && q->tcp) @@ -5140,28 +5195,11 @@ mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m) goto notready; } - // Scan list of interfaces - for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) - if (intf->NetWakeResolve[0].ThisQInterval >= 0) - { - LogSPS("ReadyForSleep waiting for SPS Resolve %s %##s (%s)", intf->ifname, intf->NetWakeResolve[0].qname.c, DNSTypeName(intf->NetWakeResolve[0].qtype)); - goto notready; - } - // Scan list of registered records for (rr = m->ResourceRecords; rr; rr = rr->next) - { if (AuthRecord_uDNS(rr)) - { if (rr->state == regState_Refresh && rr->tcp) { LogSPS("ReadyForSleep waiting for Record Update ID %d %s", mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto notready; } - } - else - { - if (!mDNSOpaque16IsZero(rr->updateid)) - { LogSPS("ReadyForSleep waiting for SPS Update ID %d %s", mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto notready; } - } - } // Scan list of registered services for (srs = m->ServiceRegistrations; srs; srs = srs->uDNS_next) @@ -5170,6 +5208,40 @@ mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m) mDNS_Unlock(m); return mDNStrue; +spsnotready: + + // If we failed to complete sleep proxy registration within ten seconds, we give up on that + // and allow up to ten seconds more to complete wide-area deregistration instead + if (now - m->SleepLimit >= 0) + { + LogMsg("Failed to register with SPS, now sending goodbyes"); + + for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) + if (intf->NetWakeBrowse.ThisQInterval >= 0) + { + LogSPS("ReadyForSleep mDNS_DeactivateNetWake %s %##s (%s)", intf->ifname, intf->NetWakeResolve[0].qname.c, DNSTypeName(intf->NetWakeResolve[0].qtype)); + mDNS_DeactivateNetWake_internal(m, intf); + } + + for (rr = m->ResourceRecords; rr; rr = rr->next) + if (!AuthRecord_uDNS(rr)) + if (!mDNSOpaque16IsZero(rr->updateid)) + { + LogSPS("ReadyForSleep clearing updateid for %s", ARDisplayString(m, rr)); + rr->updateid = zeroID; + } + + // We'd really like to allow up to ten seconds more here, + // but if we don't respond to the sleep notification within 30 seconds + // we'll be put back to sleep forcibly without the chance to schedule the next maintenance wake. + // Right now we wait 16 sec after wake for all the interfaces to come up, then we wait up to 10 seconds + // more for SPS resolves and record registrations to complete, which puts us at 26 seconds. + // If we allow just one more second to send our goodbyes, that puts us at 27 seconds. + m->SleepLimit = now + mDNSPlatformOneSecond * 1; + + SendSleepGoodbyes(m); + } + notready: mDNS_Unlock(m); return mDNSfalse; @@ -6177,8 +6249,8 @@ mDNSlocal mDNSu32 GetEffectiveTTL(const uDNS_LLQType LLQType, mDNSu32 ttl) // T else // else not LLQ (standard uDNS response) { // The TTL is already capped to a maximum value in GetLargeResourceRecord, but just to be extra safe we - // also do this check here to make sure we can't get integer overflow below - if (ttl > 0x8000000UL) ttl = 0x8000000UL; + // also do this check here to make sure we can't get overflow below when we add a quarter to the TTL + if (ttl > 0x60000000UL / mDNSPlatformOneSecond) ttl = 0x60000000UL / mDNSPlatformOneSecond; // Adjustment factor to avoid race condition: // Suppose real record as TTL of 3600, and our local caching server has held it for 3500 seconds, so it returns an aged TTL of 100. @@ -6338,6 +6410,14 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m, // Don't want to cache OPT or TSIG pseudo-RRs if (m->rec.r.resrec.rrtype == kDNSType_OPT || m->rec.r.resrec.rrtype == kDNSType_TSIG) { m->rec.r.resrec.RecordType = 0; continue; } + + // if a CNAME record points to itself, then don't add it to the cache + if ((m->rec.r.resrec.rrtype == kDNSType_CNAME) && SameDomainName(m->rec.r.resrec.name, &m->rec.r.resrec.rdata->u.name)) + { + LogInfo("mDNSCoreReceiveResponse: CNAME loop domain name %##s", m->rec.r.resrec.name->c); + m->rec.r.resrec.RecordType = 0; + continue; + } // When we receive uDNS LLQ responses, we assume a long cache lifetime -- // In the case of active LLQs, we'll get remove events when the records actually do go away @@ -8327,7 +8407,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s if (flapping) { - LogMsg("Note: RegisterInterface: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect", + LogMsg("RegisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip); if (!m->SuppressProbes || m->SuppressProbes - (m->timenow + delay) < 0) @@ -8438,7 +8518,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se " marking questions etc. dormant", set->InterfaceID, set->ifname, &set->ip); if (flapping) - LogMsg("Note: DeregisterInterface: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect", + LogMsg("DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip); // 1. Deactivate any questions specific to this interface, and tag appropriate questions @@ -9165,11 +9245,11 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->AddressProxy.ip.v4, v4->dst)) { - const mDNSu8 *const tp = (v4->protocol == 6) ? (mDNSu8 *)"\x4_tcp" : (mDNSu8 *)"\x4_udp"; + const mDNSu8 *const tp = (v4->protocol == 6) ? (const mDNSu8 *)"\x4_tcp" : (const mDNSu8 *)"\x4_udp"; for (r2 = m->ResourceRecords; r2; r2=r2->next) if (r2->resrec.InterfaceID == InterfaceID && mDNSSameEthAddress(&r2->WakeUp.HMAC, &rr->WakeUp.HMAC) && r2->resrec.rrtype == kDNSType_SRV && mDNSSameIPPort(r2->resrec.rdata->u.srv.port, port) && - SameDomainLabel(SkipLeadingLabels(r2->resrec.name, 2)->c, tp)) + SameDomainLabel(ThirdLabel(r2->resrec.name)->c, tp)) break; if (!r2 && mDNSSameIPPort(port, IPSEC)) r2 = rr; // So that we wake for BTMM IPSEC packets, even without a matching SRV record if (r2) diff --git a/mDNSCore/mDNSEmbeddedAPI.h b/mDNSCore/mDNSEmbeddedAPI.h index c02cea4..00329ec 100755 --- a/mDNSCore/mDNSEmbeddedAPI.h +++ b/mDNSCore/mDNSEmbeddedAPI.h @@ -54,6 +54,13 @@ Change History (most recent first): $Log: mDNSEmbeddedAPI.h,v $ +Revision 1.575 2009/07/11 01:57:00 cheshire + Sleep Proxy: Add support for using sleep proxy in local network interface hardware +Added declaration of ActivateLocalProxy + +Revision 1.574 2009/07/10 23:03:17 cheshire +Made SecondLabel(X) more defensive, to guard against the case where the name doesn't have a second label + Revision 1.573 2009/06/30 18:17:45 herscher Add to 64 bit macro check for 64 bit Windows OSes @@ -1212,6 +1219,13 @@ enum mDNSAddrType_Unknown = ~0 // Special marker value used in known answer list recording }; +enum + { + mDNSTransport_None = 0, + mDNSTransport_UDP = 1, + mDNSTransport_TCP = 2 + }; + typedef struct { mDNSs32 type; @@ -2562,7 +2576,8 @@ struct mDNS_struct mDNSs32 DelaySleep; // To inhibit re-sleeping too quickly right after wake mDNSs32 SleepLimit; // Time window to allow deregistrations, etc., // during which underying platform layer should inhibit system sleep - mDNSs32 NextScheduledSPRetry; // Time next sleep proxy registration action is required. Only valid if SleepLimit is nonzero. + mDNSs32 NextScheduledSPRetry; // Time next sleep proxy registration action is required. + // Only valid if SleepLimit is nonzero and DelaySleep is zero. // These fields only required for mDNS Searcher... DNSQuestion *Questions; // List of all registered questions, active and inactive @@ -2700,6 +2715,7 @@ extern const mDNSIPPort DiscardPort; extern const mDNSIPPort SSHPort; extern const mDNSIPPort UnicastDNSPort; extern const mDNSIPPort SSDPPort; +extern const mDNSIPPort IPSECPort; extern const mDNSIPPort NSIPCPort; extern const mDNSIPPort NATPMPAnnouncementPort; extern const mDNSIPPort NATPMPPort; @@ -2979,8 +2995,12 @@ extern mDNSBool SameDomainName(const domainname *const d1, const domainname *con extern mDNSBool SameDomainNameCS(const domainname *const d1, const domainname *const d2); extern mDNSBool IsLocalDomain(const domainname *d); // returns true for domains that by default should be looked up using link-local multicast +#define StripFirstLabel(X) ((const domainname *)&(X)->c[(X)->c[0] ? 1 + (X)->c[0] : 0]) + #define FirstLabel(X) ((const domainlabel *)(X)) -#define SecondLabel(X) ((const domainlabel *)&(X)->c[1 + (X)->c[0]]) +#define SecondLabel(X) ((const domainlabel *)StripFirstLabel(X)) +#define ThirdLabel(X) ((const domainlabel *)StripFirstLabel(StripFirstLabel(X))) + extern const mDNSu8 *LastLabel(const domainname *d); // Get total length of domain name, in native DNS format, including terminal root label @@ -3377,7 +3397,7 @@ extern void mDNSCoreReceive(mDNS *const m, void *const msg, const mDNSu8 *co extern void mDNSCoreRestartQueries(mDNS *const m); extern mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m); extern void mDNSCoreMachineSleep(mDNS *const m, mDNSBool wake); -extern mDNSBool mDNSCoreReadyForSleep(mDNS *m); +extern mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now); extern mDNSs32 mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now); extern void mDNSCoreBeSleepProxyServer(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower); @@ -3406,6 +3426,7 @@ extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const Resou extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q); extern void SetupLocalAutoTunnelInterface_internal(mDNS *const m); extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m); +extern mStatus ActivateLocalProxy(mDNS *const m, char *ifname); #endif // *************************************************************************** diff --git a/mDNSMacOSX/LegacyNATTraversal.c b/mDNSMacOSX/LegacyNATTraversal.c index 5cf1ae1..1a05eb1 100644 --- a/mDNSMacOSX/LegacyNATTraversal.c +++ b/mDNSMacOSX/LegacyNATTraversal.c @@ -1002,7 +1002,7 @@ mDNSexport void LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID Interface ptr = (char *)data; while (ptr && ptr != end) { - if (*ptr == 'L' && (strncasecmp(ptr, "Location:", 9) == 0)) break; // find the first 'L'; is this Location? if not, keep looking + if ((*ptr & 0xDF) == 'L' && (strncasecmp(ptr, "Location:", 9) == 0)) break; // find the first 'L'; is this Location? if not, keep looking ptr++; } if (ptr == mDNSNULL || ptr == end) diff --git a/mDNSMacOSX/daemon.c b/mDNSMacOSX/daemon.c index 50abe96..7e6db35 100644 --- a/mDNSMacOSX/daemon.c +++ b/mDNSMacOSX/daemon.c @@ -2663,7 +2663,7 @@ mDNSlocal mDNSu32 DHCPWakeTime(void) mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now) { - mDNSBool ready = mDNSCoreReadyForSleep(m); + mDNSBool ready = mDNSCoreReadyForSleep(m, now); if (m->SleepState && !ready && now - m->SleepLimit < 0) return(mDNSfalse); m->p->WakeAtUTC = 0; diff --git a/mDNSMacOSX/mDNSMacOSX.c b/mDNSMacOSX/mDNSMacOSX.c index 7f66dd4..cb3b3c7 100644 --- a/mDNSMacOSX/mDNSMacOSX.c +++ b/mDNSMacOSX/mDNSMacOSX.c @@ -17,6 +17,21 @@ Change History (most recent first): $Log: mDNSMacOSX.c,v $ +Revision 1.691 2009/07/30 20:28:15 mkrochma + Sleep Proxy: Structure changes to data passed to userclient + +Revision 1.690 2009/07/15 22:34:25 cheshire + Sleep Proxy: Add support for using sleep proxy in local network interface hardware +Fixes to make the code still compile with old headers and libraries (pre 10.5) that don't include IOConnectCallStructMethod + +Revision 1.689 2009/07/15 22:09:19 cheshire + Sleep Proxy: Add support for using sleep proxy in local network interface hardware +Removed unnecessary sleep(1) and syslog message + +Revision 1.688 2009/07/11 01:58:17 cheshire + Sleep Proxy: Add support for using sleep proxy in local network interface hardware +Added ActivateLocalProxy routine for transferring mDNS records to local proxy + Revision 1.687 2009/06/30 21:16:09 cheshire Plugging and unplugging the power cable shouldn't cause a network change event Additional fix: Only start and stop NetWake browses for active interfaces that are currently registered with mDNSCore @@ -1515,7 +1530,7 @@ mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *resu asl_set_filter(NULL, old_filter); asl_free(asl_msg); } -#endif +#endif // APPLE_OSX_mDNSResponder #if COMPILER_LIKES_PRAGMA_MARK #pragma mark - @@ -5323,6 +5338,207 @@ mDNSlocal mStatus WatchForInternetSharingChanges(mDNS *const m) return(mStatus_NoError); } +// The definitions below should eventually come from some externally-supplied header file. +// However, since these definitions can't really be changed without breaking binary compatibility, +// they should never change, so in practice it should not be a big problem to have them defined here. + +#define mDNS_IOREG_KEY "mDNS_KEY" +#define mDNS_IOREG_VALUE "2009-07-30" +#define mDNS_USER_CLIENT_CREATE_TYPE 'mDNS' + +enum + { // commands from the daemon to the driver + cmd_mDNSOffloadRR = 21, // give the mdns update buffer to the driver + }; + +typedef union { void *ptr; mDNSOpaque64 sixtyfourbits; } FatPtr; + +typedef struct + { // cmd_mDNSOffloadRR structure + uint32_t command; // set to OffloadRR + uint32_t rrBufferSize; // number of bytes of RR records + uint32_t numUDPPorts; // number of SRV UDP ports + uint32_t numTCPPorts; // number of SRV TCP ports + uint32_t numRRRecords; // number of RR records + uint32_t compression; // rrRecords - compression is base for compressed strings + FatPtr rrRecords; // address of array of pointers to the rr records + FatPtr udpPorts; // address of udp port list (SRV) + FatPtr tcpPorts; // address of tcp port list (SRV) + } mDNSOffloadCmd; + +#include +#include + +mDNSlocal mDNSu16 GetPortArray(mDNS *const m, int trans, mDNSIPPort *portarray) + { + const domainlabel *const tp = (trans == mDNSTransport_UDP) ? (const domainlabel *)"\x4_udp" : (const domainlabel *)"\x4_tcp"; + int count = 0; + AuthRecord *rr; + for (rr = m->ResourceRecords; rr; rr=rr->next) + if (rr->resrec.rrtype == kDNSType_SRV && SameDomainLabel(ThirdLabel(rr->resrec.name)->c, tp->c)) + { + if (portarray) portarray[count] = rr->resrec.rdata->u.srv.port; + count++; + } + + // If Back to My Mac is on, also wake for packets to the IPSEC UDP port (4500) + if (trans == mDNSTransport_UDP && TunnelServers(m)) + { + LogSPS("GetPortArray Back to My Mac at %d", count); + if (portarray) portarray[count] = IPSECPort; + count++; + } + return(count); + } + +#define TfrRecordToNIC(RR) \ + (((RR)->resrec.InterfaceID && (RR)->resrec.InterfaceID != mDNSInterface_LocalOnly) || \ + (!(RR)->resrec.InterfaceID && ((RR)->ForceMCast || IsLocalDomain((RR)->resrec.name)))) + +mDNSlocal mDNSu32 CountProxyRecords(mDNS *const m, uint32_t *numbytes) + { + *numbytes = 0; + int count = 0; + AuthRecord *rr; + for (rr = m->ResourceRecords; rr; rr=rr->next) + if (rr->resrec.RecordType > kDNSRecordTypeDeregistering) + if (TfrRecordToNIC(rr)) + { + *numbytes += DomainNameLength(rr->resrec.name) + 10 + rr->resrec.rdestimate; + LogSPS("CountProxyRecords: %3d %5d %5d %s", count, DomainNameLength(rr->resrec.name) + 10 + rr->resrec.rdestimate, *numbytes, ARDisplayString(m,rr)); + count++; + } + return(count); + } + +mDNSlocal mDNSu16 GetProxyRecords(mDNS *const m, DNSMessage *msg, uint16_t numbytes, FatPtr *records) + { + mDNSu8 *p = msg->data; + const mDNSu8 *const limit = p + numbytes; + InitializeDNSMessage(&msg->h, zeroID, zeroID); + + int count = 0; + AuthRecord *rr; + for (rr = m->ResourceRecords; rr; rr=rr->next) + if (rr->resrec.RecordType > kDNSRecordTypeDeregistering) + if (TfrRecordToNIC(rr)) + { + records[count].sixtyfourbits = zeroOpaque64; + records[count].ptr = p; + if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask) + rr->resrec.rrclass |= kDNSClass_UniqueRRSet; // Temporarily set the 'unique' bit so PutResourceRecord will set it + p = PutResourceRecordTTLWithLimit(msg, p, &msg->h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl, limit); + rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet; // Make sure to clear 'unique' bit back to normal state + LogSPS("GetProxyRecords: %3d %p %p %s", count, records[count].ptr, p, ARDisplayString(m,rr)); + count++; + } + return(count); + } + +// If compiling with old headers and libraries (pre 10.5) that don't include IOConnectCallStructMethod +// then we declare a dummy version here so that the code at least compiles +#ifndef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +static kern_return_t +IOConnectCallStructMethod( + mach_port_t connection, // In + uint32_t selector, // In + const void *inputStruct, // In + size_t inputStructCnt, // In + void *outputStruct, // Out + size_t *outputStructCnt) // In/Out + { + (void)connection; + (void)selector; + (void)inputStruct; + (void)inputStructCnt; + (void)outputStruct; + (void)outputStructCnt; + LogMsg("Compiled without IOConnectCallStructMethod"); + return(KERN_FAILURE); + } +#endif + +mDNSexport mStatus ActivateLocalProxy(mDNS *const m, char *ifname) + { + mStatus result = mStatus_UnknownErr; + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, ifname)); + if (!service) { LogMsg("ActivateLocalProxy: No service for interface %s", ifname); return(mStatus_UnknownErr); } + + io_name_t n1, n2; + IOObjectGetClass(service, n1); + io_object_t parent; + kern_return_t kr = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent); + if (kr != KERN_SUCCESS) LogMsg("ActivateLocalProxy: IORegistryEntryGetParentEntry for %s/%s failed %d", ifname, n1, kr); + else + { + IOObjectGetClass(parent, n2); + LogSPS("ActivateLocalProxy: Interface %s service %s parent %s", ifname, n1, n2); + const CFTypeRef ref = IORegistryEntryCreateCFProperty(parent, CFSTR(mDNS_IOREG_KEY), kCFAllocatorDefault, mDNSNULL); + if (!ref) LogSPS("ActivateLocalProxy: No mDNS_IOREG_KEY for interface %s/%s/%s", ifname, n1, n2); + else + { + if (CFGetTypeID(ref) != CFStringGetTypeID() || !CFEqual(ref, CFSTR(mDNS_IOREG_VALUE))) + LogMsg("ActivateLocalProxy: mDNS_IOREG_KEY for interface %s/%s/%s value %s != %s", + ifname, n1, n2, CFStringGetCStringPtr(ref, mDNSNULL), mDNS_IOREG_VALUE); + else + { + io_connect_t conObj; + kr = IOServiceOpen(parent, mach_task_self(), mDNS_USER_CLIENT_CREATE_TYPE, &conObj); + if (kr != KERN_SUCCESS) LogMsg("ActivateLocalProxy: IOServiceOpen for %s/%s/%s failed %d", ifname, n1, n2, kr); + else + { + mDNSOffloadCmd cmd; + mDNSPlatformMemZero(&cmd, sizeof(cmd)); // When compiling 32-bit, make sure top 32 bits of 64-bit pointers get initialized to zero + cmd.command = cmd_mDNSOffloadRR; + cmd.numUDPPorts = GetPortArray(m, mDNSTransport_UDP, mDNSNULL); + cmd.numTCPPorts = GetPortArray(m, mDNSTransport_TCP, mDNSNULL); + cmd.numRRRecords = CountProxyRecords(m, &cmd.rrBufferSize); + cmd.compression = sizeof(DNSMessageHeader); + + DNSMessage *msg = (DNSMessage *)mallocL("mDNSOffloadCmd msg", sizeof(DNSMessageHeader) + cmd.rrBufferSize); + cmd.rrRecords.ptr = mallocL("mDNSOffloadCmd rrRecords", cmd.numRRRecords * sizeof(FatPtr)); + cmd.udpPorts .ptr = mallocL("mDNSOffloadCmd udpPorts", cmd.numUDPPorts * sizeof(mDNSIPPort)); + cmd.tcpPorts .ptr = mallocL("mDNSOffloadCmd tcpPorts", cmd.numTCPPorts * sizeof(mDNSIPPort)); + + LogSPS("ActivateLocalProxy: msg %p %d RR %p %d, UDP %p %d, TCP %p %d", + msg, cmd.rrBufferSize, + cmd.rrRecords.ptr, cmd.numRRRecords, + cmd.udpPorts .ptr, cmd.numUDPPorts, + cmd.tcpPorts .ptr, cmd.numTCPPorts); + + if (!msg || !cmd.rrRecords.ptr || !cmd.udpPorts.ptr || !cmd.tcpPorts.ptr) + LogMsg("ActivateLocalProxy: Failed to allocate memory: msg %p %d RR %p %d, UDP %p %d, TCP %p %d", + msg, cmd.rrBufferSize, + cmd.rrRecords.ptr, cmd.numRRRecords, + cmd.udpPorts .ptr, cmd.numUDPPorts, + cmd.tcpPorts .ptr, cmd.numTCPPorts); + else + { + GetProxyRecords(m, msg, cmd.rrBufferSize, cmd.rrRecords.ptr); + GetPortArray(m, mDNSTransport_UDP, cmd.udpPorts.ptr); + GetPortArray(m, mDNSTransport_TCP, cmd.tcpPorts.ptr); + char outputData[2]; + size_t outputDataSize = sizeof(outputData); + kr = IOConnectCallStructMethod(conObj, 0, &cmd, sizeof(cmd), outputData, &outputDataSize); + LogSPS("ActivateLocalProxy: IOConnectCallStructMethod for %s/%s/%s %d", ifname, n1, n2, kr); + if (kr == KERN_SUCCESS) result = mStatus_NoError; + } + + if (cmd.tcpPorts. ptr) freeL("mDNSOffloadCmd udpPorts", cmd.tcpPorts .ptr); + if (cmd.udpPorts. ptr) freeL("mDNSOffloadCmd tcpPorts", cmd.udpPorts .ptr); + if (cmd.rrRecords.ptr) freeL("mDNSOffloadCmd rrRecords", cmd.rrRecords.ptr); + if (msg) freeL("mDNSOffloadCmd msg", msg); + IOServiceClose(conObj); + } + } + CFRelease(ref); + } + IOObjectRelease(parent); + } + IOObjectRelease(service); + return result; + } + #endif // APPLE_OSX_mDNSResponder static io_service_t g_rootdomain = MACH_PORT_NULL; diff --git a/mDNSPosix/NetMonitor.c b/mDNSPosix/NetMonitor.c index f873ea3..ed8124f 100644 --- a/mDNSPosix/NetMonitor.c +++ b/mDNSPosix/NetMonitor.c @@ -30,6 +30,12 @@ Change History (most recent first): $Log: NetMonitor.c,v $ +Revision 1.96 2009/07/16 00:08:57 cheshire +Display any stray Update (Authority) records in query packets + +Revision 1.95 2009/07/09 22:24:52 herscher + SDK: Port mDNSNetMonitor to Windows + Revision 1.94 2009/04/24 00:31:56 cheshire Return negative answers when host knows authoritatively that no answer exists Added code to display NSEC records @@ -115,13 +121,28 @@ Use IFNAMSIZ (more portable) instead of IF_NAMESIZE #include // For strrchr(), strcmp() #include // For "struct tm" etc. #include // For SIGINT, SIGTERM -#include // For gethostbyname() -#include // For AF_INET, AF_INET6, etc. -#include // For IF_NAMESIZE -#include // For INADDR_NONE -#include // For inet_addr() - -#include "mDNSPosix.h" // Defines the specific types needed to run mDNS on this platform +#if defined(WIN32) +# include +# include +# include +# include +# include +# define IFNAMSIZ 256 + +// Stub these functions out +mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count) { return 0; } +mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent) { return 0; } +mDNSexport void udsserver_handle_configchange(mDNS *const m) {} +mDNSexport int udsserver_exit(void) { return 0; } +void setlinebuf( FILE * fp ) {} +#else +# include // For gethostbyname() +# include // For AF_INET, AF_INET6, etc. +# include // For IF_NAMESIZE +# include // For INADDR_NONE +# include // For inet_addr() +# include "mDNSPosix.h" // Defines the specific types needed to run mDNS on this platform +#endif #include "ExampleClientApp.h" //************************************************************************************************************* @@ -179,7 +200,7 @@ struct FilterList_struct //************************************************************************************************************* // Globals -static mDNS mDNSStorage; // mDNS core uses this to store its globals +mDNS mDNSStorage; // mDNS core uses this to store its globals static mDNS_PlatformSupport PlatformStorage; // Stores this platform's globals mDNSexport const char ProgramName[] = "mDNSNetMonitor"; @@ -712,16 +733,19 @@ mDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mD for (i=0; ih.numAuthorities; i++) { const mDNSu8 *ep = ptr; - ptr = skipResourceRecord(msg, ptr, end); + ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &pkt); if (!ptr) { DisplayError(srcaddr, ep, end, "AUTHORITY"); return; } + // After we display an Update record with its matching question (above) we zero out its type and class + // If any remain that haven't been zero'd out, display them here + if (pkt.r.resrec.rrtype || pkt.r.resrec.rrclass) DisplayResourceRecord(srcaddr, "(AU)", &pkt.r.resrec); } for (i=0; ih.numAdditionals; i++) { const mDNSu8 *ep = ptr; - ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt); + ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt); if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; } - DisplayResourceRecord(srcaddr, " ", &pkt.r.resrec); + DisplayResourceRecord(srcaddr, pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : "(AD)", &pkt.r.resrec); } if (entry) AnalyseHost(m, entry, InterfaceID); @@ -785,7 +809,9 @@ mDNSlocal void DisplayResponse(mDNS *const m, const DNSMessage *const msg, const ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt); if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; } NumAdditionals++; - DisplayResourceRecord(srcaddr, (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AD)" : "(AD+)", &pkt.r.resrec); + DisplayResourceRecord(srcaddr, + pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AD)" : "(AD+)", + &pkt.r.resrec); if (entry) RecordHostInfo(entry, &pkt.r.resrec); } @@ -863,7 +889,9 @@ mDNSlocal mStatus mDNSNetMonitor(void) { struct tm tm; int h, m, s, mul, div, TotPkt; +#if !defined(WIN32) sigset_t signals; +#endif mStatus status = mDNS_Init(&mDNSStorage, &PlatformStorage, mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize, @@ -872,6 +900,10 @@ mDNSlocal mStatus mDNSNetMonitor(void) if (status) return(status); gettimeofday(&tv_start, NULL); + +#if defined( WIN32 ) + RunDirect( 0, NULL ); +#else mDNSPosixListenForSignalInEventLoop(SIGINT); mDNSPosixListenForSignalInEventLoop(SIGTERM); @@ -882,6 +914,7 @@ mDNSlocal mStatus mDNSNetMonitor(void) mDNSPosixRunEventLoopOnce(&mDNSStorage, &timeout, &signals, &gotSomething); } while ( !( sigismember( &signals, SIGINT) || sigismember( &signals, SIGTERM))); +#endif // Now display final summary TotPkt = NumPktQ + NumPktL + NumPktR; diff --git a/mDNSResponder.sln b/mDNSResponder.sln index 1e0eca1..98423dc 100755 --- a/mDNSResponder.sln +++ b/mDNSResponder.sln @@ -65,138 +65,296 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLStub", "mDNSWindows\DLLS {AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLX", "mDNSWindows\DLLX\DLLX.vcproj", "{78FBFCC5-2873-4AE2-9114-A08082F71124}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DNSServiceBrowser.NET", "Clients\DNSServiceBrowser.NET\DNSServiceBrowser.NET.csproj", "{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}" +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DNSServiceBrowser.VB", "Clients\DNSServiceBrowser.VB\DNSServiceBrowser.VB.vbproj", "{FB79E297-5703-435C-A829-51AA51CD71C2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mDNSNetMonitor", "Clients\mDNSNetMonitor.VisualStudio\mDNSNetMonitor.vcproj", "{AF35C285-528D-46A1-8A0E-47B0733DC718}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Any CPU.ActiveCfg = Debug|x64 + {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Mixed Platforms.Build.0 = Debug|x64 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Win32.ActiveCfg = Debug|Win32 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Win32.Build.0 = Debug|Win32 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|x64.ActiveCfg = Debug|x64 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|x64.Build.0 = Debug|x64 + {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Any CPU.ActiveCfg = Release|x64 + {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Mixed Platforms.Build.0 = Release|x64 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Win32.ActiveCfg = Release|Win32 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Win32.Build.0 = Release|Win32 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|x64.ActiveCfg = Release|x64 {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|x64.Build.0 = Release|x64 + {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Any CPU.ActiveCfg = Debug|x64 + {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Mixed Platforms.Build.0 = Debug|x64 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Win32.ActiveCfg = Debug|Win32 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Win32.Build.0 = Debug|Win32 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|x64.ActiveCfg = Debug|x64 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|x64.Build.0 = Debug|x64 + {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Any CPU.ActiveCfg = Release|x64 + {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Mixed Platforms.Build.0 = Release|x64 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Win32.ActiveCfg = Release|Win32 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Win32.Build.0 = Release|Win32 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|x64.ActiveCfg = Release|x64 {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|x64.Build.0 = Release|x64 + {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Any CPU.ActiveCfg = Debug|x64 + {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Mixed Platforms.Build.0 = Debug|x64 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Win32.ActiveCfg = Debug|Win32 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Win32.Build.0 = Debug|Win32 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|x64.ActiveCfg = Debug|x64 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|x64.Build.0 = Debug|x64 + {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Any CPU.ActiveCfg = Release|x64 + {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Mixed Platforms.Build.0 = Release|x64 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Win32.ActiveCfg = Release|Win32 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Win32.Build.0 = Release|Win32 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|x64.ActiveCfg = Release|x64 {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|x64.Build.0 = Release|x64 + {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Any CPU.ActiveCfg = Debug|x64 + {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Mixed Platforms.Build.0 = Debug|x64 {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Win32.ActiveCfg = Debug|Win32 {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Win32.Build.0 = Debug|Win32 {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|x64.ActiveCfg = Debug|x64 {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|x64.Build.0 = Debug|x64 + {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Any CPU.ActiveCfg = Release|x64 + {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Mixed Platforms.Build.0 = Release|x64 {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Win32.ActiveCfg = Release|Win32 {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Win32.Build.0 = Release|Win32 {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|x64.ActiveCfg = Release|x64 {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|x64.Build.0 = Release|x64 + {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Any CPU.ActiveCfg = Debug|x64 + {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Mixed Platforms.Build.0 = Debug|x64 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Win32.ActiveCfg = Debug|Win32 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Win32.Build.0 = Debug|Win32 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|x64.ActiveCfg = Debug|x64 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|x64.Build.0 = Debug|x64 + {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Any CPU.ActiveCfg = Release|x64 + {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Mixed Platforms.Build.0 = Release|x64 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Win32.ActiveCfg = Release|Win32 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Win32.Build.0 = Release|Win32 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|x64.ActiveCfg = Release|x64 {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|x64.Build.0 = Release|x64 + {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Any CPU.ActiveCfg = Debug|x64 + {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Mixed Platforms.Build.0 = Debug|x64 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Win32.ActiveCfg = Debug|Win32 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Win32.Build.0 = Debug|Win32 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|x64.ActiveCfg = Debug|x64 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|x64.Build.0 = Debug|x64 + {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Any CPU.ActiveCfg = Release|x64 + {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Mixed Platforms.Build.0 = Release|x64 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Win32.ActiveCfg = Release|Win32 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Win32.Build.0 = Release|Win32 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|x64.ActiveCfg = Release|x64 {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|x64.Build.0 = Release|x64 + {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Any CPU.ActiveCfg = Debug|x64 + {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Mixed Platforms.Build.0 = Debug|x64 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Win32.ActiveCfg = Debug|Win32 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Win32.Build.0 = Debug|Win32 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|x64.ActiveCfg = Debug|x64 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|x64.Build.0 = Debug|x64 + {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Any CPU.ActiveCfg = Release|x64 + {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Mixed Platforms.Build.0 = Release|x64 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Win32.ActiveCfg = Release|Win32 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Win32.Build.0 = Release|Win32 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|x64.ActiveCfg = Release|x64 {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|x64.Build.0 = Release|x64 + {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Any CPU.ActiveCfg = Debug|x64 + {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Mixed Platforms.Build.0 = Debug|x64 {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Win32.ActiveCfg = Debug|Win32 {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Win32.Build.0 = Debug|Win32 {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|x64.ActiveCfg = Debug|x64 {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|x64.Build.0 = Debug|x64 + {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Any CPU.ActiveCfg = Release|x64 + {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Mixed Platforms.Build.0 = Release|x64 {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Win32.ActiveCfg = Release|Win32 {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Win32.Build.0 = Release|Win32 {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|x64.ActiveCfg = Release|x64 {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|x64.Build.0 = Release|x64 + {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Any CPU.ActiveCfg = Debug|x64 + {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Mixed Platforms.Build.0 = Debug|x64 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Win32.ActiveCfg = Debug|Win32 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Win32.Build.0 = Debug|Win32 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|x64.ActiveCfg = Debug|x64 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|x64.Build.0 = Debug|x64 + {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Any CPU.ActiveCfg = Release|x64 + {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Mixed Platforms.Build.0 = Release|x64 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Win32.ActiveCfg = Release|Win32 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Win32.Build.0 = Release|Win32 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|x64.ActiveCfg = Release|x64 {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|x64.Build.0 = Release|x64 + {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Any CPU.ActiveCfg = Debug|x64 + {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Mixed Platforms.Build.0 = Debug|x64 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Win32.ActiveCfg = Debug|Win32 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Win32.Build.0 = Debug|Win32 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|x64.ActiveCfg = Debug|x64 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|x64.Build.0 = Debug|x64 + {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Any CPU.ActiveCfg = Release|x64 + {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Mixed Platforms.Build.0 = Release|x64 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Win32.ActiveCfg = Release|Win32 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Win32.Build.0 = Release|Win32 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|x64.ActiveCfg = Release|x64 {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|x64.Build.0 = Release|x64 + {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Any CPU.ActiveCfg = Debug|x64 + {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Mixed Platforms.Build.0 = Debug|x64 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Win32.ActiveCfg = Debug|Win32 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Win32.Build.0 = Debug|Win32 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|x64.ActiveCfg = Debug|x64 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|x64.Build.0 = Debug|x64 + {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Any CPU.ActiveCfg = Release|x64 + {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Mixed Platforms.Build.0 = Release|x64 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Win32.ActiveCfg = Release|Win32 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Win32.Build.0 = Release|Win32 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|x64.ActiveCfg = Release|x64 {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|x64.Build.0 = Release|x64 + {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Any CPU.ActiveCfg = Debug|x64 + {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Mixed Platforms.Build.0 = Debug|x64 {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Win32.ActiveCfg = Debug|Win32 {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Win32.Build.0 = Debug|Win32 {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|x64.ActiveCfg = Debug|x64 {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|x64.Build.0 = Debug|x64 + {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Any CPU.ActiveCfg = Release|x64 + {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Mixed Platforms.Build.0 = Release|x64 {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Win32.ActiveCfg = Release|Win32 {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Win32.Build.0 = Release|Win32 {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|x64.ActiveCfg = Release|x64 {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|x64.Build.0 = Release|x64 + {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Any CPU.ActiveCfg = Debug|x64 + {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Mixed Platforms.Build.0 = Debug|x64 {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Win32.ActiveCfg = Debug|Win32 {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Win32.Build.0 = Debug|Win32 {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|x64.ActiveCfg = Debug|x64 + {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Any CPU.ActiveCfg = Release|x64 + {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Mixed Platforms.Build.0 = Release|x64 {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Win32.ActiveCfg = Release|Win32 {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Win32.Build.0 = Release|Win32 {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|x64.ActiveCfg = Release|x64 + {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Any CPU.ActiveCfg = Debug|x64 + {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Mixed Platforms.Build.0 = Debug|x64 {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Win32.ActiveCfg = Debug|Win32 {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Win32.Build.0 = Debug|Win32 {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|x64.ActiveCfg = Debug|x64 + {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Any CPU.ActiveCfg = Release|x64 + {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Mixed Platforms.Build.0 = Release|x64 {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Win32.ActiveCfg = Release|Win32 {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Win32.Build.0 = Release|Win32 {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|x64.ActiveCfg = Release|x64 + {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Any CPU.ActiveCfg = Debug|x64 + {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Mixed Platforms.Build.0 = Debug|x64 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Win32.ActiveCfg = Debug|Win32 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Win32.Build.0 = Debug|Win32 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|x64.ActiveCfg = Debug|x64 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|x64.Build.0 = Debug|x64 + {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Any CPU.ActiveCfg = Release|x64 + {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Mixed Platforms.Build.0 = Release|x64 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Win32.ActiveCfg = Release|Win32 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Win32.Build.0 = Release|Win32 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|x64.ActiveCfg = Release|x64 {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|x64.Build.0 = Release|x64 + {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Any CPU.ActiveCfg = Debug|x64 + {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Mixed Platforms.Build.0 = Debug|x64 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Win32.ActiveCfg = Debug|Win32 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Win32.Build.0 = Debug|Win32 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|x64.ActiveCfg = Debug|x64 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|x64.Build.0 = Debug|x64 + {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Any CPU.ActiveCfg = Release|x64 + {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Mixed Platforms.Build.0 = Release|x64 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Win32.ActiveCfg = Release|Win32 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Win32.Build.0 = Release|Win32 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|x64.ActiveCfg = Release|x64 {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|x64.Build.0 = Release|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Any CPU.ActiveCfg = Debug|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Mixed Platforms.Build.0 = Debug|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Win32.ActiveCfg = Debug|Win32 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Win32.Build.0 = Debug|Win32 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|x64.ActiveCfg = Debug|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|x64.Build.0 = Debug|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Any CPU.ActiveCfg = Release|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Mixed Platforms.Build.0 = Release|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Win32.ActiveCfg = Release|Win32 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Win32.Build.0 = Release|Win32 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|x64.ActiveCfg = Release|x64 + {78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|x64.Build.0 = Release|x64 + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Win32.ActiveCfg = Debug|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Any CPU.Build.0 = Release|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Win32.ActiveCfg = Release|Any CPU + {DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|x64.ActiveCfg = Release|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Win32.ActiveCfg = Debug|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|x64.ActiveCfg = Debug|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Any CPU.Build.0 = Release|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Win32.ActiveCfg = Release|Any CPU + {FB79E297-5703-435C-A829-51AA51CD71C2}.Release|x64.ActiveCfg = Release|Any CPU + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Win32.ActiveCfg = Debug|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Win32.Build.0 = Debug|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|x64.ActiveCfg = Debug|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Any CPU.ActiveCfg = Release|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Mixed Platforms.Build.0 = Release|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Win32.ActiveCfg = Release|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Win32.Build.0 = Release|Win32 + {AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/mDNSShared/dns_sd.h b/mDNSShared/dns_sd.h index 3169a5a..59891f7 100644 --- a/mDNSShared/dns_sd.h +++ b/mDNSShared/dns_sd.h @@ -77,7 +77,7 @@ */ #ifndef _DNS_SD_H -#define _DNS_SD_H 2120100 +#define _DNS_SD_H 2140000 #ifdef __cplusplus extern "C" { diff --git a/mDNSShared/uds_daemon.c b/mDNSShared/uds_daemon.c index dfae86e..9022f94 100644 --- a/mDNSShared/uds_daemon.c +++ b/mDNSShared/uds_daemon.c @@ -17,6 +17,14 @@ Change History (most recent first): $Log: uds_daemon.c,v $ +Revision 1.463 2009/07/10 22:25:47 cheshire +Updated syslog messages for debugging unresponsive clients: +Will now log a warning message about an unresponsive client every ten seconds, +and then after 60 messagess (10 minutes) will terminate connection to that client. + +Revision 1.462 2009/07/09 22:43:31 cheshire +Improved log messages for debugging unresponsive clients + Revision 1.461 2009/06/19 23:15:07 cheshire Library: crash at handle_resolve_response + 183 Made resolve_result_callback code more defensive and improved LogOperation messages @@ -989,7 +997,8 @@ struct request_state // reply, termination, error, and client context info int no_reply; // don't send asynchronous replies to client - int time_blocked; // record time of a blocked client + mDNSs32 time_blocked; // record time of a blocked client + int unresponsiveness_reports; struct reply_state *replies; // corresponding (active) reply list req_termination_fn terminate; @@ -1891,8 +1900,7 @@ mDNSlocal mStatus handle_update_request(request_state *request) if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_update_request - malloc"); mDNSPlatformMemCopy(request->u.servicereg.txtdata, rdata, rdlen); } - else - request->u.servicereg.txtdata = NULL; + request->u.servicereg.txtlen = rdlen; } // update a record from a service record set @@ -2231,7 +2239,6 @@ mDNSlocal mStatus handle_regservice_request(request_state *request) if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_regservice_request - malloc"); mDNSPlatformMemCopy(request->u.servicereg.txtdata, get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen), request->u.servicereg.txtlen); } - else request->u.servicereg.txtdata = NULL; if (!request->msgptr) { LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd); return(mStatus_BadParamErr); } @@ -4467,6 +4474,7 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent) r->replies = r->replies->next; freeL("reply_state/udsserver_idle", fptr); r->time_blocked = 0; // reset failure counter after successful send + r->unresponsiveness_reports = 0; continue; } else if (result == t_terminated || result == t_error) @@ -4480,15 +4488,24 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent) if (r->replies) // If we failed to send everything, check our time_blocked timer { - if (!r->time_blocked) r->time_blocked = NonZeroTime(now); - if (now - r->time_blocked >= 60 * mDNSPlatformOneSecond) + if (nextevent - now > mDNSPlatformOneSecond) nextevent = now + mDNSPlatformOneSecond; + + if (mDNSStorage.SleepState != SleepState_Awake) r->time_blocked = 0; + else if (!r->time_blocked) r->time_blocked = NonZeroTime(now); + else if (now - r->time_blocked >= 10 * mDNSPlatformOneSecond * (r->unresponsiveness_reports+1)) { - LogMsg("%3d: Could not write data to client after %ld seconds - aborting connection", r->sd, - (now - r->time_blocked) / mDNSPlatformOneSecond); - LogClientInfo(&mDNSStorage, r); - abort_request(r); + int num = 0; + struct reply_state *x = r->replies; + while (x) { num++; x=x->next; } + LogMsg("%3d: Could not write data to client after %ld seconds, %d repl%s waiting", + r->sd, (now - r->time_blocked) / mDNSPlatformOneSecond, num, num == 1 ? "y" : "ies"); + if (++r->unresponsiveness_reports >= 60) + { + LogMsg("%3d: Client unresponsive; aborting connection", r->sd); + LogClientInfo(&mDNSStorage, r); + abort_request(r); + } } - else if (nextevent - now > mDNSPlatformOneSecond) nextevent = now + mDNSPlatformOneSecond; } if (!dnssd_SocketValid(r->sd)) // If this request is finished, unlink it from the list and free the memory @@ -4508,7 +4525,7 @@ struct CompileTimeAssertionChecks_uds_daemon // Check our structures are reasonable sizes. Including overly-large buffers, or embedding // other overly-large structures instead of having a pointer to them, can inadvertently // cause structure sizes (and therefore memory usage) to balloon unreasonably. - char sizecheck_request_state [(sizeof(request_state) <= 1760) ? 1 : -1]; + char sizecheck_request_state [(sizeof(request_state) <= 2000) ? 1 : -1]; char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <= 40) ? 1 : -1]; char sizecheck_service_instance [(sizeof(service_instance) <= 6552) ? 1 : -1]; char sizecheck_browser_t [(sizeof(browser_t) <= 992) ? 1 : -1]; diff --git a/mDNSWindows/DLLX/DLLX.vcproj b/mDNSWindows/DLLX/DLLX.vcproj index 04fe58b..7c58b0a 100755 --- a/mDNSWindows/DLLX/DLLX.vcproj +++ b/mDNSWindows/DLLX/DLLX.vcproj @@ -272,7 +272,7 @@ /> diff --git a/mDNSWindows/PosixCompat.c b/mDNSWindows/PosixCompat.c new file mode 100755 index 0000000..ec69f95 --- /dev/null +++ b/mDNSWindows/PosixCompat.c @@ -0,0 +1,141 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 1997-2004 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. + + Change History (most recent first): + +$Log: PosixCompat.c,v $ +Revision 1.1 2009/07/09 21:40:32 herscher + SDK: Port mDNSNetMonitor to Windows. Add a small Posix compatibility layer to the mDNSWindows platform layer. This makes it possible to centralize the implementations to functions such as if_indextoname() and inet_pton() that are made in several projects in B4W. + + +*/ + +#include "PosixCompat.h" +#include + + +typedef PCHAR (WINAPI * if_indextoname_funcptr_t)(ULONG index, PCHAR name); +typedef ULONG (WINAPI * if_nametoindex_funcptr_t)(PCSTR name); + + +unsigned +if_nametoindex( const char * ifname ) +{ + HMODULE library; + unsigned index = 0; + + check( ifname ); + + // Try and load the IP helper library dll + if ((library = LoadLibrary(TEXT("Iphlpapi")) ) != NULL ) + { + if_nametoindex_funcptr_t if_nametoindex_funcptr; + + // On Vista and above there is a Posix like implementation of if_nametoindex + if ((if_nametoindex_funcptr = (if_nametoindex_funcptr_t) GetProcAddress(library, "if_nametoindex")) != NULL ) + { + index = if_nametoindex_funcptr(ifname); + } + + FreeLibrary(library); + } + + return index; +} + + +char* +if_indextoname( unsigned ifindex, char * ifname ) +{ + HMODULE library; + char * name = NULL; + + check( ifname ); + *ifname = '\0'; + + // Try and load the IP helper library dll + if ((library = LoadLibrary(TEXT("Iphlpapi")) ) != NULL ) + { + if_indextoname_funcptr_t if_indextoname_funcptr; + + // On Vista and above there is a Posix like implementation of if_indextoname + if ((if_indextoname_funcptr = (if_indextoname_funcptr_t) GetProcAddress(library, "if_indextoname")) != NULL ) + { + name = if_indextoname_funcptr(ifindex, ifname); + } + + FreeLibrary(library); + } + + return name; +} + + +int +inet_pton( int family, const char * addr, void * dst ) +{ + struct sockaddr_storage ss; + int sslen = sizeof( ss ); + + ZeroMemory( &ss, sizeof( ss ) ); + ss.ss_family = family; + + if ( WSAStringToAddressA( ( LPSTR ) addr, family, NULL, ( struct sockaddr* ) &ss, &sslen ) == 0 ) + { + if ( family == AF_INET ) { memcpy( dst, &( ( struct sockaddr_in* ) &ss)->sin_addr, sizeof( IN_ADDR ) ); return 1; } + else if ( family == AF_INET6 ) { memcpy( dst, &( ( struct sockaddr_in6* ) &ss)->sin6_addr, sizeof( IN6_ADDR ) ); return 1; } + else return 0; + } + else return 0; +} + + +int +gettimeofday( struct timeval * tv, struct timezone * tz ) +{ +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) +# define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else +# define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + + FILETIME ft; + unsigned __int64 tmpres = 0; + + if ( tv != NULL ) + { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tmpres /= 10; /*convert into microseconds*/ + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + return 0; +} + + +extern struct tm* +localtime_r( const time_t * clock, struct tm * result ) +{ + result = localtime( clock ); + return result; +} diff --git a/mDNSWindows/PosixCompat.h b/mDNSWindows/PosixCompat.h new file mode 100755 index 0000000..c7de0ea --- /dev/null +++ b/mDNSWindows/PosixCompat.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 1997-2004 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. + + Change History (most recent first): + +$Log: PosixCompat.h,v $ +Revision 1.1 2009/07/09 21:40:32 herscher + SDK: Port mDNSNetMonitor to Windows. Add a small Posix compatibility layer to the mDNSWindows platform layer. This makes it possible to centralize the implementations to functions such as if_indextoname() and inet_pton() that are made in several projects in B4W. + + +*/ + +#pragma once + +#include "CommonServices.h" +#include +#include + + +/* + * Posix process compatibility + */ +typedef int pid_t; +#if !defined( getpid ) +# define getpid _getpid +#endif + + +/* + * Posix networking compatibility + */ +extern unsigned +if_nametoindex( const char * ifname ); + + +extern char* +if_indextoname( unsigned ifindex, char * ifname ); + + +extern int +inet_pton( int family, const char * addr, void * dst ); + + +/* + * Posix time compatibility + */ +extern int +gettimeofday( struct timeval * tv, struct timezone * tz ); + + +extern struct tm* +localtime_r( const time_t * clock, struct tm * result ); + + +/* + * Posix string compatibility + */ +#if !defined( strcasecmp ) +# define strcasecmp _stricmp +#endif + +#if !defined( snprintf ) +# define snprint _snprintf +#endif + diff --git a/mDNSWindows/Secret.c b/mDNSWindows/Secret.c index 4c12d15..2797655 100644 --- a/mDNSWindows/Secret.c +++ b/mDNSWindows/Secret.c @@ -17,6 +17,9 @@ Change History (most recent first): $Log: Secret.c,v $ +Revision 1.3 2009/07/17 19:50:25 herscher + ControlPanel doesn't display key and password in dialog box + Revision 1.2 2009/06/25 21:11:52 herscher Fix compilation error when building Control Panel. @@ -46,7 +49,7 @@ mDNSlocal OSStatus MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_ BOOL -LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, char * outKey, unsigned outKeyLength, char * outSecret, unsigned outSecretLength ) +LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize ) { PLSA_UNICODE_STRING domainLSA; PLSA_UNICODE_STRING keyLSA; @@ -69,21 +72,23 @@ LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, keyLSA = NULL; secretLSA = NULL; + // Make sure we have enough space to add trailing dot + + dlen = strlen( inDomain ); + err = strcpy_s( outDomain, outDomainSize - 2, inDomain ); + require_noerr( err, exit ); + // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. - strcpy_s( outDomain, outDomainLength, inDomain ); - dlen = strlen( outDomain ); - if ( outDomain[ dlen - 1 ] != '.' ) { - outDomain[ dlen ] = '.'; - outDomain[ dlen + 1 ] = '\0'; + outDomain[ dlen++ ] = '.'; + outDomain[ dlen ] = '\0'; } // Canonicalize name by converting to lower case (keychain and some name servers are case sensitive) - dlen = strlen( outDomain ); for ( i = 0; i < dlen; i++ ) { outDomain[i] = (char) tolower( outDomain[i] ); // canonicalize -> lower case @@ -113,11 +118,10 @@ LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, require_noerr_quiet( err, exit ); // Lsa secrets use a flat naming space. Therefore, we will prepend "$" to the keyname to - // make sure it doesn't conflict with a zone name. - + // make sure it doesn't conflict with a zone name. // Strip off the "$" prefix. - err = MakeUTF8StringFromLsaString( outKey, outKeyLength, keyLSA ); + err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA ); require_noerr( err, exit ); require_action( outKey[0] == '$', exit, err = kUnknownErr ); memcpy( outKey, outKey + 1, strlen( outKey ) ); @@ -130,7 +134,7 @@ LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, // Convert the secret to UTF8 string - err = MakeUTF8StringFromLsaString( outSecret, outSecretLength, secretLSA ); + err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA ); require_noerr( err, exit ); exit: @@ -185,21 +189,19 @@ LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret ) require_action( inKey != NULL, exit, ok = FALSE ); require_action( inSecret != NULL, exit, ok = FALSE ); - inDomainLength = strlen( inDomain ); - require_action( ( inDomainLength > 0 ) && ( inDomainLength < sizeof( domain ) ), exit, ok = FALSE ); - - inKeyLength = strlen( inKey ); - require_action( ( inKeyLength > 0 ) && ( inKeyLength < ( sizeof( key ) - 1 ) ), exit, ok = FALSE ); - // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. ZeroMemory( domain, sizeof( domain ) ); - strcpy_s( domain, sizeof( domain ), inDomain ); + inDomainLength = strlen( inDomain ); + require_action( inDomainLength > 0, exit, ok = FALSE ); + err = strcpy_s( domain, sizeof( domain ) - 2, inDomain ); + require_action( !err, exit, ok = FALSE ); - if ( domain[ strlen( domain ) - 1 ] != '.' ) + if ( domain[ inDomainLength - 1 ] != '.' ) { - domain[ strlen( domain ) - 1 ] = '.'; + domain[ inDomainLength++ ] = '.'; + domain[ inDomainLength ] = '\0'; } // @@ -209,12 +211,17 @@ LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret ) // name ZeroMemory( key, sizeof( key ) ); + inKeyLength = strlen( inKey ); + require_action( inKeyLength > 0 , exit, ok = FALSE ); key[ 0 ] = '$'; - strcpy_s( key + 1, sizeof( key ) - 1, inKey ); + err = strcpy_s( key + 1, sizeof( key ) - 3, inKey ); + require_action( !err, exit, ok = FALSE ); + inKeyLength++; - if ( key[ strlen( key ) - 1 ] != '.' ) + if ( key[ inKeyLength - 1 ] != '.' ) { - key[ strlen( key ) - 1 ] = '.'; + key[ inKeyLength++ ] = '.'; + key[ inKeyLength ] = '\0'; } // attrs are reserved, so initialize to zeroes. @@ -229,16 +236,13 @@ LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret ) // Intializing PLSA_UNICODE_STRING structures - ok = MakeLsaStringFromUTF8String( &lucZoneName, domain ); - err = translate_errno( ok, errno_compat(), kUnknownErr ); + err = MakeLsaStringFromUTF8String( &lucZoneName, domain ); require_noerr( err, exit ); - - ok = MakeLsaStringFromUTF8String( &lucKeyName, key ); - err = translate_errno( ok, errno_compat(), kUnknownErr ); + + err = MakeLsaStringFromUTF8String( &lucKeyName, key ); require_noerr( err, exit ); - ok = MakeLsaStringFromUTF8String( &lucSecretName, inSecret ); - err = translate_errno( ok, errno_compat(), kUnknownErr ); + err = MakeLsaStringFromUTF8String( &lucSecretName, inSecret ); require_noerr( err, exit ); // Store the private data. diff --git a/mDNSWindows/SystemService/Service.c b/mDNSWindows/SystemService/Service.c index 8671e0b..2fb67bc 100644 --- a/mDNSWindows/SystemService/Service.c +++ b/mDNSWindows/SystemService/Service.c @@ -17,6 +17,15 @@ Change History (most recent first): $Log: Service.c,v $ +Revision 1.49 2009/07/17 19:59:46 herscher + Update the womp settings for each network adapter immediately preceding the call to mDNSCoreMachineSleep(). + +Revision 1.48 2009/07/09 21:34:14 herscher + SDK: Port mDNSNetMonitor to Windows. Refactor the system service slightly by removing the main() function from Service.c so that mDNSNetMonitor can link to functions defined in Service.c + +Revision 1.47 2009/07/07 21:35:06 herscher + windows platform changes to support use as sleep proxy client + Revision 1.46 2009/06/05 18:28:24 herscher mDNSResponder should be able to identify VPN adapters generically WIN7: Bonjour removes the default gateway entry and thereby breaks network connectivity @@ -198,6 +207,7 @@ mDNSResponder Windows Service. Provides global Bonjour support with an IPC inter #include "uds_daemon.h" #include "GenLinkedList.h" +#include "Service.h" #include "Resource.h" @@ -215,6 +225,7 @@ mDNSResponder Windows Service. Provides global Bonjour support with an IPC inter #include #include #include + #include #endif #ifndef HeapEnableTerminationOnCorruption @@ -289,11 +300,6 @@ typedef struct Win32EventSource //=========================================================================================================================== // Prototypes //=========================================================================================================================== -#if defined(UNICODE) -int __cdecl wmain( int argc, LPTSTR argv[] ); -#else -int __cdecl main( int argc, char *argv[] ); -#endif static void Usage( void ); static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent ); static OSStatus InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath ); @@ -303,7 +309,6 @@ static OSStatus GetServiceParameters(); static OSStatus CheckFirewall(); static OSStatus SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription ); static void ReportStatus( int inType, const char *inFormat, ... ); -static OSStatus RunDirect( int argc, LPTSTR argv[] ); static void WINAPI ServiceMain( DWORD argc, LPTSTR argv[] ); static OSStatus ServiceSetupEventLogging( void ); @@ -322,6 +327,7 @@ static void EventSourceUnlock(); static mDNSs32 udsIdle(mDNS * const inMDNS, mDNSs32 interval); static void CoreCallback(mDNS * const inMDNS, mStatus result); static void HostDescriptionChanged(mDNS * const inMDNS); +static mDNSu8 SystemWakeForNetworkAccess( LARGE_INTEGER * timeout ); static OSStatus GetRouteDestination(DWORD * ifIndex, DWORD * address); static OSStatus SetLLRoute( mDNS * const inMDNS ); static bool HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric ); @@ -370,6 +376,8 @@ DEBUG_LOCAL bool gServiceManageLLRouting = true; DEBUG_LOCAL int gWaitCount = 0; DEBUG_LOCAL HANDLE * gWaitList = NULL; DEBUG_LOCAL HANDLE gStopEvent = NULL; +DEBUG_LOCAL HANDLE gSPSWakeupEvent = NULL; +DEBUG_LOCAL HANDLE gSPSSleepEvent = NULL; DEBUG_LOCAL CRITICAL_SECTION gEventSourceLock; DEBUG_LOCAL GenLinkedList gEventSources; DEBUG_LOCAL BOOL gRetryFirewall = FALSE; @@ -386,13 +394,9 @@ mDNSlocal GetIpInterfaceEntryFunctionPtr gGetIpInterfaceEntryFunctionPtr = NULL #endif //=========================================================================================================================== -// main +// Main //=========================================================================================================================== -#if defined(UNICODE) -int __cdecl wmain( int argc, wchar_t * argv[] ) -#else -int __cdecl main( int argc, char *argv[] ) -#endif +int Main( int argc, LPTSTR argv[] ) { OSStatus err; BOOL ok; @@ -987,7 +991,7 @@ static void ReportStatus( int inType, const char *inFormat, ... ) // RunDirect //=========================================================================================================================== -static OSStatus RunDirect( int argc, LPTSTR argv[] ) +int RunDirect( int argc, LPTSTR argv[] ) { OSStatus err; BOOL initialized; @@ -1160,7 +1164,7 @@ static DWORD WINAPI ServiceControlHandler( DWORD inControl, DWORD inEventType, L switch( inControl ) { case SERVICE_CONTROL_STOP: - dlog( kDebugLevelNotice, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP\n" ); + dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP\n" ); ServiceStop(); setStatus = FALSE; @@ -1170,10 +1174,42 @@ static DWORD WINAPI ServiceControlHandler( DWORD inControl, DWORD inEventType, L if (inEventType == PBT_APMSUSPEND) { + LARGE_INTEGER timeout; + + dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMSUSPEND\n" ); + + mDNSPlatformLock( &gMDNSRecord ); + + gMDNSRecord.SystemWakeOnLANEnabled = SystemWakeForNetworkAccess( &timeout ); + + if ( gMDNSRecord.SystemWakeOnLANEnabled ) + { + ok = SetWaitableTimer( gSPSWakeupEvent, &timeout, 0, NULL, NULL, TRUE ); + check( ok ); + } + + mDNSPlatformUnlock( &gMDNSRecord ); + mDNSCoreMachineSleep(&gMDNSRecord, TRUE); } else if (inEventType == PBT_APMRESUMESUSPEND) { + dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMRESUMESUSPEND\n" ); + + mDNSPlatformLock( &gMDNSRecord ); + + if ( gSPSWakeupEvent ) + { + CancelWaitableTimer( gSPSWakeupEvent ); + } + + if ( gSPSSleepEvent ) + { + CancelWaitableTimer( gSPSSleepEvent ); + } + + mDNSPlatformUnlock( &gMDNSRecord ); + mDNSCoreMachineSleep(&gMDNSRecord, FALSE); } @@ -1301,6 +1337,14 @@ static OSStatus ServiceSpecificInitialize( int argc, LPTSTR argv[] ) err = translate_errno( gStopEvent, errno_compat(), kNoResourcesErr ); require_noerr( err, exit ); + gSPSWakeupEvent = CreateWaitableTimer( NULL, FALSE, NULL ); + err = translate_errno( gSPSWakeupEvent, (mStatus) GetLastError(), kUnknownErr ); + require_noerr( err, exit ); + + gSPSSleepEvent = CreateWaitableTimer( NULL, FALSE, NULL ); + err = translate_errno( gSPSSleepEvent, (mStatus) GetLastError(), kUnknownErr ); + require_noerr( err, exit ); + err = mDNS_Init( &gMDNSRecord, &gPlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, CoreCallback, mDNS_Init_NoInitCallbackContext); require_noerr( err, exit); @@ -1343,9 +1387,41 @@ static OSStatus ServiceSpecificRun( int argc, LPTSTR argv[] ) timeout = ( gRetryFirewall ) ? kRetryFirewallPeriod : INFINITE; - while( (result = WaitForSingleObject( gStopEvent, timeout ) ) != WAIT_OBJECT_0 ) + for ( ;; ) { - if ( result == WAIT_TIMEOUT ) + HANDLE waitList[ 3 ]; + + waitList[ 0 ] = gStopEvent; + waitList[ 1 ] = gSPSWakeupEvent; + waitList[ 2 ] = gSPSSleepEvent; + + result = WaitForMultipleObjects( 3, waitList, FALSE, timeout ); + + if ( result == WAIT_OBJECT_0 ) + { + break; + } + else if ( result == WAIT_OBJECT_0 + 1 ) + { + __int64 temp; + LARGE_INTEGER timeout; + + dlog( kDebugLevelInfo, DEBUG_NAME "setting suspend event\n" ); + + // Stay awake for 60 seconds + + temp = -60 * 10000000; + timeout.LowPart = (DWORD) ( temp & 0xFFFFFFFF ); + timeout.HighPart = (LONG) ( temp >> 32 ); + + SetWaitableTimer( gSPSSleepEvent, &timeout, 0, NULL, NULL, TRUE ); + } + else if ( result == WAIT_OBJECT_0 + 2 ) + { + dlog( kDebugLevelInfo, DEBUG_NAME "suspending machine\n" ); + SetSuspendState( FALSE, FALSE, FALSE ); + } + else if ( result == WAIT_TIMEOUT ) { OSStatus err; @@ -1411,6 +1487,24 @@ static void ServiceSpecificFinalize( int argc, LPTSTR argv[] ) // DeleteCriticalSection(&gEventSourceLock); + if ( gSPSWakeupEvent ) + { + CloseHandle( gSPSWakeupEvent ); + gSPSWakeupEvent = NULL; + } + + if ( gSPSSleepEvent ) + { + CloseHandle( gSPSSleepEvent ); + gSPSSleepEvent = NULL; + } + + if ( gStopEvent ) + { + CloseHandle( gStopEvent ); + gStopEvent = NULL; + } + // // clean up loaded library // @@ -1834,6 +1928,83 @@ EventSourceUnlock() } +//=========================================================================================================================== +// SystemWakeForNetworkAccess +//=========================================================================================================================== + +mDNSu8 +SystemWakeForNetworkAccess( LARGE_INTEGER * timeout ) +{ + HKEY key = NULL; + DWORD dwSize; + DWORD enabled; + mDNSu8 ok; + SYSTEM_POWER_STATUS powerStatus; + time_t startTime; + time_t nextWakeupTime; + time_t delta; + __int64 delta64; + DWORD err; + + dlog( kDebugLevelInfo, DEBUG_NAME "SystemWakeForNetworkAccess\n" ); + + // Make sure we have a timer + + require_action( gSPSWakeupEvent != NULL, exit, ok = FALSE ); + require_action( gSPSSleepEvent != NULL, exit, ok = FALSE ); + + // Make sure the user enabled bonjour sleep proxy client + + err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key ); + require_action( !err, exit, ok = FALSE ); + dwSize = sizeof( DWORD ); + err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize ); + require_action( !err, exit, ok = FALSE ); + require_action( enabled, exit, ok = FALSE ); + + // Make sure machine is on AC power + + ok = ( mDNSu8 ) GetSystemPowerStatus( &powerStatus ); + require_action( ok, exit, ok = FALSE ); + require_action( powerStatus.ACLineStatus == AC_LINE_ONLINE, exit, ok = FALSE ); + + // Now make sure we have a network interface that does wake-on-lan + + UpdateWOMPConfig( &gMDNSRecord ); + require_action( gMDNSRecord.p->womp, exit, ok = FALSE ); + + // Calculate next wake up time + + startTime = time( NULL ); + nextWakeupTime = startTime + ( 120 * 60 ); + + if ( gMDNSRecord.p->nextDHCPLeaseExpires < nextWakeupTime ) + { + nextWakeupTime = gMDNSRecord.p->nextDHCPLeaseExpires; + } + + // Finally calculate the next relative wakeup time + + delta = ( time_t ) ( ( ( double )( nextWakeupTime - startTime ) ) * 0.9 ); + delta64 = -delta * 10000000; + timeout->LowPart = (DWORD) ( delta64 & 0xFFFFFFFF ); + timeout->HighPart = (LONG) ( delta64 >> 32 ); + + dlog( kDebugLevelInfo, DEBUG_NAME "enabling sleep proxy client with next wakeup time %d seconds from now\n", delta ); + + ok = TRUE; + +exit: + + if ( key ) + { + RegCloseKey( key ); + } + + return ok; +} + + //=========================================================================================================================== // HaveRoute //=========================================================================================================================== diff --git a/mDNSWindows/SystemService/Service.h b/mDNSWindows/SystemService/Service.h new file mode 100755 index 0000000..438c1c4 --- /dev/null +++ b/mDNSWindows/SystemService/Service.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 2002-2004 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. + + Change History (most recent first): + +$Log: Service.h,v $ +Revision 1.1 2009/07/09 21:34:15 herscher + SDK: Port mDNSNetMonitor to Windows. Refactor the system service slightly by removing the main() function from Service.c so that mDNSNetMonitor can link to functions defined in Service.c + + + */ + +#ifndef __MDNS_SERVICE_H__ +#define __MDNS_SERVICE_H__ + + +#include + + +extern int RunDirect( int argc, LPTSTR argv[] ); +extern int Main( int argc, LPTSTR argv[] ); + + +#endif + diff --git a/mDNSWindows/SystemService/Service.vcproj b/mDNSWindows/SystemService/Service.vcproj index d16d017..c30cca8 100644 --- a/mDNSWindows/SystemService/Service.vcproj +++ b/mDNSWindows/SystemService/Service.vcproj @@ -44,7 +44,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;"C:/Program Files/Microsoft SDKs/Windows/v6.1/Include"" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;DEBUG=1;MDNS_DEBUGMSGS=0;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE="""";UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;_LEGACY_NAT_TRAVERSAL_" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;DEBUG=1;MDNS_DEBUGMSGS=0;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE="""";UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;_LEGACY_NAT_TRAVERSAL_;_USE_32BIT_TIME_T" StringPooling="true" MinimalRebuild="true" ExceptionHandling="0" @@ -58,7 +58,7 @@ Detect64BitPortabilityProblems="true" DebugInformationFormat="3" CallingConvention="2" - DisableSpecificWarnings="4127" + DisableSpecificWarnings="4127;4201" ShowIncludes="false" /> + + @@ -483,6 +487,10 @@ RelativePath="..\Secret.h" > + + diff --git a/mDNSWindows/SystemService/main.c b/mDNSWindows/SystemService/main.c new file mode 100755 index 0000000..40c53b8 --- /dev/null +++ b/mDNSWindows/SystemService/main.c @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 2002-2004 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. + + Change History (most recent first): + +$Log: main.c,v $ +Revision 1.1 2009/07/09 21:34:15 herscher + SDK: Port mDNSNetMonitor to Windows. Refactor the system service slightly by removing the main() function from Service.c so that mDNSNetMonitor can link to functions defined in Service.c + + + */ + +#include "Service.h" + + +//=========================================================================================================================== +// main +//=========================================================================================================================== +#if defined(UNICODE) +int __cdecl wmain( int argc, wchar_t * argv[] ) +#else +int __cdecl main( int argc, char *argv[] ) +#endif +{ + return Main( argc, argv ); +} + diff --git a/mDNSWindows/WinVersRes.h b/mDNSWindows/WinVersRes.h index b155515..a46a002 100644 --- a/mDNSWindows/WinVersRes.h +++ b/mDNSWindows/WinVersRes.h @@ -17,6 +17,12 @@ Change History (most recent first): $Log: WinVersRes.h,v $ +Revision 1.63 2009/07/21 05:10:55 herscher +Bump version to 2.0.0.7 + +Revision 1.62 2009/07/13 18:47:58 herscher +Bump to version 2.0.0.6 + Revision 1.61 2009/06/30 17:37:32 herscher Bump to 2.0.0.5 @@ -211,10 +217,10 @@ First checked in. #define MASTER_COMPANY_NAME "Apple Inc." // Define the product version for mDNSResponder on Windows -#define MASTER_PROD_VERS 2,0,0,5 -#define MASTER_PROD_VERS_STR "2,0,0,5" -#define MASTER_PROD_VERS_STR2 "2.0.0.5" -#define MASTER_PROD_VERS_STR3 "Explorer Plugin 2.0.0.5" +#define MASTER_PROD_VERS 2,0,0,7 +#define MASTER_PROD_VERS_STR "2,0,0,7" +#define MASTER_PROD_VERS_STR2 "2.0.0.7" +#define MASTER_PROD_VERS_STR3 "Explorer Plugin 2.0.0.7" // Define the legal copyright #define MASTER_LEGAL_COPYRIGHT "Copyright (C) 2003-2009 Apple Inc." diff --git a/mDNSWindows/mDNSWin32.c b/mDNSWindows/mDNSWin32.c index 8f1283f..05b9a56 100755 --- a/mDNSWindows/mDNSWin32.c +++ b/mDNSWindows/mDNSWin32.c @@ -17,6 +17,15 @@ Change History (most recent first): $Log: mDNSWin32.c,v $ +Revision 1.145 2009/07/20 04:07:41 herscher + Bonjour does not list IPv6 loopback address when all network adapters are disabled + +Revision 1.144 2009/07/17 19:59:46 herscher + Update the womp settings for each network adapter immediately preceding the call to mDNSCoreMachineSleep(). + +Revision 1.143 2009/07/07 21:34:58 herscher + windows platform changes to support use as sleep proxy client + Revision 1.142 2009/06/25 21:11:02 herscher Platform layer doesn't correctly initialize the port field of TCP and UDP socket structures. @@ -169,6 +178,8 @@ Revision 1.106 2006/02/26 19:31:05 herscher #include #include #include + #include + #include // This defines the IOCTL constants. #endif #include "mDNSEmbeddedAPI.h" @@ -215,6 +226,7 @@ Revision 1.106 2006/02/26 19:31:05 herscher #define kIPv6IfIndexBase (10000000L) #define SMBPortAsNumber 445 +#define DEVICE_PREFIX "\\\\.\\" #if 0 @@ -335,6 +347,7 @@ mDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCSTR lpSubKey ); mDNSlocal void SetDomainSecrets( mDNS * const m ); mDNSlocal void SetDomainSecret( mDNS * const m, const domainname * inDomain ); mDNSlocal void CheckFileShares( mDNS * const m ); +mDNSlocal mDNSu8 IsWOMPEnabled( const char * adapterName ); #ifdef __cplusplus } @@ -1350,7 +1363,7 @@ mDNSexport UDPSocket* mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requ if (mDNSIPPortIsZero(requestedport)) { - port = mDNSOpaque16fromIntVal(0xC000 + mDNSRandom(0x3FFF)); + port = mDNSOpaque16fromIntVal( ( mDNSu16 ) ( 0xC000 + mDNSRandom(0x3FFF) ) ); } saddr.sin_port = port.NotAnInteger; @@ -2362,6 +2375,8 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS ) check( inMDNS->p ); inMDNS->p->registeredLoopback4 = mDNSfalse; + inMDNS->p->nextDHCPLeaseExpires = 0xFFFFFFFF; + inMDNS->p->womp = mDNSfalse; addrs = NULL; foundv4 = mDNSfalse; foundv6 = mDNSfalse; @@ -2425,6 +2440,11 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS ) foundv4 = mDNStrue; } + if ( p->ifa_dhcpEnabled && ( p->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) ) + { + inMDNS->p->nextDHCPLeaseExpires = p->ifa_dhcpLeaseExpires; + } + // If we're on a platform that doesn't have WSARecvMsg(), there's no way // of determing the destination address of a packet that is sent to us. // For multicast packets, that's easy to determine. But for the unicast @@ -2519,7 +2539,7 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS ) if ( !foundv4 && loopbackv4 ) { - dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", + dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", loopbackv4->ifa_name ? loopbackv4->ifa_name : "", loopbackv4->ifa_extra.index, loopbackv4->ifa_addr ); err = SetupInterface( inMDNS, loopbackv4, &ifd ); @@ -2547,6 +2567,34 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS ) ++inMDNS->p->interfaceCount; } + if ( !foundv6 && loopbackv6 ) + { + dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", + loopbackv6->ifa_name ? loopbackv6->ifa_name : "", loopbackv6->ifa_extra.index, loopbackv6->ifa_addr ); + + err = SetupInterface( inMDNS, loopbackv6, &ifd ); + require_noerr( err, exit ); + +#if( MDNS_WINDOWS_ENABLE_IPV6 ) + + // If we're on a platform that doesn't have WSARecvMsg(), there's no way + // of determing the destination address of a packet that is sent to us. + // For multicast packets, that's easy to determine. But for the unicast + // sockets, we'll fake it by taking the address of the first interface + // that is successfully setup. + + if ( !foundUnicastSock6DestAddr ) + { + inMDNS->p->unicastSock6DestAddr = ifd->defaultAddr; + foundUnicastSock6DestAddr = TRUE; + } +#endif + + *next = ifd; + next = &ifd->next; + ++inMDNS->p->interfaceCount; + } + exit: if( err ) { @@ -2723,7 +2771,19 @@ mDNSlocal mStatus SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inI err = translate_errno( ifd->readPendingEvent, (mStatus) GetLastError(), kUnknownErr ); require_noerr( err, exit ); } - + + if ( inIFA->ifa_dhcpEnabled && ( inIFA->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) ) + { + inMDNS->p->nextDHCPLeaseExpires = inIFA->ifa_dhcpLeaseExpires; + } + + ifd->interfaceInfo.NetWake = inIFA->ifa_womp; + + if ( ifd->interfaceInfo.NetWake ) + { + inMDNS->p->womp = TRUE; + } + // Register this interface with mDNS. err = SockAddrToMDNSAddr( inIFA->ifa_addr, &ifd->interfaceInfo.ip, NULL ); @@ -2746,6 +2806,7 @@ mDNSlocal mStatus SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inI ifd = NULL; exit: + if( ifd ) { TearDownInterface( inMDNS, ifd ); @@ -4138,9 +4199,9 @@ mDNSlocal int getifaddrs_ipv6( struct ifaddrs **outAddrs ) firstPrefix = NULL; } - // Skip psuedo and tunnel interfaces. + // Skip pseudo and tunnel interfaces. - if( ( ipv6IfIndex == 1 ) || ( iaa->IfType == IF_TYPE_TUNNEL ) ) + if( ( ( ipv6IfIndex == 1 ) && ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) ) || ( iaa->IfType == IF_TYPE_TUNNEL ) ) { continue; } @@ -4155,7 +4216,7 @@ mDNSlocal int getifaddrs_ipv6( struct ifaddrs **outAddrs ) ULONG prefixLength; uint32_t ipv4Index; struct sockaddr_in ipv4Netmask; - + family = addr->Address.lpSockaddr->sa_family; if( ( family != AF_INET ) && ( family != AF_INET6 ) ) continue; @@ -4221,6 +4282,26 @@ mDNSlocal int getifaddrs_ipv6( struct ifaddrs **outAddrs ) case AF_INET6: ifa->ifa_extra.index = ipv6IfIndex + kIPv6IfIndexBase; break; default: break; } + + // Get lease lifetime + + if ( ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) && ( addr->LeaseLifetime != 0 ) && ( addr->LeaseLifetime != 0xFFFFFFFF ) ) + { + ifa->ifa_dhcpEnabled = TRUE; + ifa->ifa_dhcpLeaseExpires = time( NULL ) + addr->LeaseLifetime; + } + else + { + ifa->ifa_dhcpEnabled = FALSE; + ifa->ifa_dhcpLeaseExpires = 0; + } + + // Get WakeOnLAN settings + + if ( iaa->IfType == IF_TYPE_ETHERNET_CSMACD ) + { + ifa->ifa_womp = IsWOMPEnabled( iaa->AdapterName ); + } // Get address. @@ -4338,6 +4419,9 @@ mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs ) INTERFACE_INFO * buffer; INTERFACE_INFO * tempBuffer; INTERFACE_INFO * ifInfo; + IP_ADAPTER_INFO * pAdapterInfo; + IP_ADAPTER_INFO * pAdapter; + ULONG bufLen; int n; int i; struct ifaddrs * head; @@ -4348,6 +4432,7 @@ mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs ) buffer = NULL; head = NULL; next = &head; + pAdapterInfo = NULL; // Get the interface list. WSAIoctl is called with SIO_GET_INTERFACE_LIST, but since this does not provide a // way to determine the size of the interface list beforehand, we have to start with an initial size guess and @@ -4379,6 +4464,28 @@ mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs ) check( actualSize <= size ); check( ( actualSize % sizeof( INTERFACE_INFO ) ) == 0 ); n = (int)( actualSize / sizeof( INTERFACE_INFO ) ); + + // Now call GetAdaptersInfo so we can get DHCP information for each interface + + pAdapterInfo = NULL; + bufLen = 0; + + for ( i = 0; i < 100; i++ ) + { + err = GetAdaptersInfo( pAdapterInfo, &bufLen); + + if ( err != ERROR_BUFFER_OVERFLOW ) + { + break; + } + + pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen ); + + if ( !pAdapterInfo ) + { + break; + } + } // Process the raw interface list and build a linked list of IPv4 interfaces. @@ -4448,6 +4555,19 @@ mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs ) ifa->ifa_extra.index = (uint32_t)( i + 1 ); } + + // Now get DHCP configuration information + + for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next ) + { + if ( strcmp( inet_ntoa( ifInfo->iiAddress.AddressIn.sin_addr ), pAdapter->IpAddressList.IpAddress.String ) == 0 ) + { + ifa->ifa_dhcpEnabled = pAdapter->DhcpEnabled; + ifa->ifa_dhcpLeaseExpires = pAdapter->LeaseExpires; + ifa->ifa_womp = IsWOMPEnabled( pAdapter->AdapterName ); + break; + } + } } // Success! @@ -4460,6 +4580,11 @@ mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs ) err = 0; exit: + + if ( pAdapterInfo ) + { + free( pAdapterInfo ); + } if( head ) { freeifaddrs( head ); @@ -5440,3 +5565,70 @@ exit: return; } + + +void +UpdateWOMPConfig( mDNS * const m ) +{ + mDNSInterfaceData * ifd; + + mDNSPlatformLock( m ); + + m->p->womp = mDNSfalse; + + for( ifd = m->p->interfaceList; ifd; ifd = ifd->next ) + { + ifd->interfaceInfo.NetWake = IsWOMPEnabled( ifd->name ); + + if ( ifd->interfaceInfo.NetWake ) + { + m->p->womp = mDNStrue; + } + } + + mDNSPlatformUnlock( m ); +} + + +mDNSlocal mDNSu8 +IsWOMPEnabled( const char * adapterName ) +{ + char fileName[80]; + NDIS_OID oid; + DWORD count; + HANDLE handle = INVALID_HANDLE_VALUE; + NDIS_PNP_CAPABILITIES * pNPC = NULL; + int err; + mDNSu8 ok = TRUE; + + // Construct a device name to pass to CreateFile + + strncpy_s( fileName, sizeof( fileName ), DEVICE_PREFIX, strlen( DEVICE_PREFIX ) ); + strcat_s( fileName, sizeof( fileName ), adapterName ); + handle = CreateFileA( fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, INVALID_HANDLE_VALUE ); + require_action ( handle != INVALID_HANDLE_VALUE, exit, ok = FALSE ); + + // We successfully opened the driver, format the IOCTL to pass the driver. + + oid = OID_PNP_CAPABILITIES; + pNPC = ( NDIS_PNP_CAPABILITIES * ) malloc( sizeof( NDIS_PNP_CAPABILITIES ) ); + require_action( pNPC != NULL, exit, ok = FALSE ); + ok = ( mDNSu8 ) DeviceIoControl( handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof( oid ), pNPC, sizeof( NDIS_PNP_CAPABILITIES ), &count, NULL ); + err = translate_errno( ok, GetLastError(), kUnknownErr ); + require_action( !err, exit, ok = FALSE ); + ok = ( mDNSu8 ) ( ( count == sizeof( NDIS_PNP_CAPABILITIES ) ) && ( pNPC->Flags & NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE ) ); + +exit: + + if ( pNPC != NULL ) + { + free( pNPC ); + } + + if ( handle != INVALID_HANDLE_VALUE ) + { + CloseHandle( handle ); + } + + return ( mDNSu8 ) ok; +} diff --git a/mDNSWindows/mDNSWin32.h b/mDNSWindows/mDNSWin32.h index c85f2fe..4d30be5 100755 --- a/mDNSWindows/mDNSWin32.h +++ b/mDNSWindows/mDNSWin32.h @@ -17,6 +17,12 @@ Change History (most recent first): $Log: mDNSWin32.h,v $ +Revision 1.30 2009/07/17 19:59:46 herscher + Update the womp settings for each network adapter immediately preceding the call to mDNSCoreMachineSleep(). + +Revision 1.29 2009/07/07 21:34:58 herscher + windows platform changes to support use as sleep proxy client + Revision 1.28 2009/04/24 04:55:26 herscher Advertise SMB file sharing via Bonjour @@ -211,6 +217,8 @@ struct mDNS_PlatformSupport_struct HANDLE firewallEvent; // Firewall changed HANDLE wakeupEvent; HANDLE initEvent; + time_t nextDHCPLeaseExpires; + mDNSBool womp; // Does any interface support wake-on-magic-packet HKEY descKey; HKEY tcpipKey; HKEY ddnsKey; @@ -257,6 +265,9 @@ struct ifaddrs struct sockaddr * ifa_netmask; struct sockaddr * ifa_broadaddr; struct sockaddr * ifa_dstaddr; + BOOL ifa_dhcpEnabled; + time_t ifa_dhcpLeaseExpires; + mDNSu8 ifa_womp; void * ifa_data; struct @@ -267,6 +278,9 @@ struct ifaddrs }; +extern void UpdateWOMPConfig(); + + #ifdef __cplusplus } #endif -- 2.47.2