--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ * ("Apple") in consideration of your agreement to the following terms, and your
+ * use, installation, modification or redistribution of this Apple software
+ * constitutes acceptance of these terms. If you do not agree with these terms,
+ * please do not use, install, modify or redistribute this Apple software.
+ *
+ * In consideration of your agreement to abide by the following terms, and subject
+ * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
+ * copyrights in this original Apple software (the "Apple Software"), to use,
+ * reproduce, modify and redistribute the Apple Software, with or without
+ * modifications, in source and/or binary forms; provided that if you redistribute
+ * the Apple Software in its entirety and without modifications, you must retain
+ * this notice and the following text and disclaimers in all such redistributions of
+ * the Apple Software. Neither the name, trademarks, service marks or logos of
+ * Apple Computer, Inc. may be used to endorse or promote products derived from the
+ * Apple Software without specific prior written permission from Apple. Except as
+ * expressly stated in this notice, no other rights or licenses, express or implied,
+ * are granted by Apple herein, including but not limited to any patent rights that
+ * may be infringed by your derivative works or by other works in which the Apple
+ * Software may be incorporated.
+ *
+ * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ * COMBINATION WITH YOUR PRODUCTS.
+ *
+ * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Change History (most recent first):
+
+$Log: ClientCommon.c,v $
+Revision 1.2 2008/05/08 00:42:03 cheshire
+Removed some unnecessary header files
+
+Revision 1.1 2008/05/08 00:25:48 cheshire
+<rdar://problem/5919272> GetNextLabel insufficiently defensive
+
+
+*/
+
+#include <ctype.h>
+#include <stdio.h> // For stdout, stderr
+
+#include "ClientCommon.h"
+
+const char *GetNextLabel(const char *cstr, char label[64])
+ {
+ char *ptr = label;
+ while (*cstr && *cstr != '.') // While we have characters in the label...
+ {
+ char c = *cstr++;
+ if (c == '\\' && *cstr) // If we have a backslash, and it's not the last character of the string
+ {
+ c = *cstr++;
+ if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
+ {
+ int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
+ int v1 = cstr[ 0] - '0';
+ int v2 = cstr[ 1] - '0';
+ int val = v0 * 100 + v1 * 10 + v2;
+ // If valid three-digit decimal value, use it
+ // Note that although ascii nuls are possible in DNS labels
+ // we're building a C string here so we have no way to represent that
+ if (val == 0) val = '-';
+ if (val <= 255) { c = (char)val; cstr += 2; }
+ }
+ }
+ *ptr++ = c;
+ if (ptr >= label+64) { label[63] = 0; return(NULL); } // Illegal label more than 63 bytes
+ }
+ *ptr = 0; // Null-terminate label text
+ if (ptr == label) return(NULL); // Illegal empty label
+ if (*cstr) cstr++; // Skip over the trailing dot (if present)
+ return(cstr);
+ }
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ * ("Apple") in consideration of your agreement to the following terms, and your
+ * use, installation, modification or redistribution of this Apple software
+ * constitutes acceptance of these terms. If you do not agree with these terms,
+ * please do not use, install, modify or redistribute this Apple software.
+ *
+ * In consideration of your agreement to abide by the following terms, and subject
+ * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
+ * copyrights in this original Apple software (the "Apple Software"), to use,
+ * reproduce, modify and redistribute the Apple Software, with or without
+ * modifications, in source and/or binary forms; provided that if you redistribute
+ * the Apple Software in its entirety and without modifications, you must retain
+ * this notice and the following text and disclaimers in all such redistributions of
+ * the Apple Software. Neither the name, trademarks, service marks or logos of
+ * Apple Computer, Inc. may be used to endorse or promote products derived from the
+ * Apple Software without specific prior written permission from Apple. Except as
+ * expressly stated in this notice, no other rights or licenses, express or implied,
+ * are granted by Apple herein, including but not limited to any patent rights that
+ * may be infringed by your derivative works or by other works in which the Apple
+ * Software may be incorporated.
+ *
+ * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ * COMBINATION WITH YOUR PRODUCTS.
+ *
+ * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Change History (most recent first):
+
+$Log: ClientCommon.h,v $
+Revision 1.1 2008/05/08 00:25:48 cheshire
+<rdar://problem/5919272> GetNextLabel insufficiently defensive
+
+
+*/
+
+extern const char *GetNextLabel(const char *cstr, char label[64]);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.DNS-SD" type="win32"/>
+ <description>Command line utility.</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="amd64" name="Apple.Bonjour.DNS-SD" type="win32"/>
+ <description>Command Line Utility</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="dns-sd"\r
ProjectGUID="{AA230639-E115-4A44-AA5A-44A61235BA50}"\r
- Keyword="Win32Proj">\r
+ Keyword="Win32Proj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory="Debug"\r
- IntermediateDirectory="Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_WIN32;_DEBUG;_CONSOLE;NOT_HAVE_GETOPT;NOT_HAVE_SETLINEBUF;WIN32_LEAN_AND_MEAN"\r
- MinimalRebuild="TRUE"\r
+ PreprocessorDefinitions="WIN32;_WIN32;_DEBUG;_CONSOLE;NOT_HAVE_GETOPT;NOT_HAVE_SETLINEBUF;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
- RuntimeLibrary="5"\r
+ RuntimeLibrary="1"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="3"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"/>\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../../mDNSWindows/DLL/Debug/dnssd.lib ws2_32.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../../mDNSWindows/DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
OutputFile="$(OutDir)/dns-sd.exe"\r
LinkIncremental="2"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/dns-sd.pdb"\r
SubSystem="1"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="DNS-SD.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCCustomBuildTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_WIN32;_DEBUG;_CONSOLE;NOT_HAVE_GETOPT;NOT_HAVE_SETLINEBUF;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../../mDNSWindows/DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/dns-sd.exe"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/dns-sd.pdb"\r
+ SubSystem="1"\r
+ TargetMachine="17"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="DNS-SD64.manifest"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
InlineFunctionExpansion="1"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories="../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_WIN32;NDEBUG;_CONSOLE;NOT_HAVE_GETOPT;NOT_HAVE_SETLINEBUF;WIN32_LEAN_AND_MEAN"\r
- StringPooling="TRUE"\r
- RuntimeLibrary="4"\r
- EnableFunctionLevelLinking="TRUE"\r
+ PreprocessorDefinitions="WIN32;_WIN32;NDEBUG;_CONSOLE;NOT_HAVE_GETOPT;NOT_HAVE_SETLINEBUF;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="3"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="3"/>\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../../mDNSWindows/DLL/Release/dnssd.lib ws2_32.lib "\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../../mDNSWindows/DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
OutputFile="$(OutDir)/dns-sd.exe"\r
LinkIncremental="1"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
SubSystem="1"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="DNS-SD.manifest"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\WINDOWS\system32\$(PlatformName)" mkdir "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
if not exist "$(DSTROOT)\Program Files\Bonjour SDK\Samples\C" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\Samples\C"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
xcopy /I/Y "$(ProjectDir)..\dns-sd.c" "$(DSTROOT)\Program Files\Bonjour SDK\Samples\C"
:END
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories="../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_WIN32;NDEBUG;_CONSOLE;NOT_HAVE_GETOPT;NOT_HAVE_SETLINEBUF;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../../mDNSWindows/DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/dns-sd.exe"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="1"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="DNS-SD64.manifest"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\WINDOWS\system32\$(PlatformName)" mkdir "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
if not exist "$(DSTROOT)\Program Files\Bonjour SDK\Samples\C" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\Samples\C"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
:END
"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">\r
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+ >\r
+ <File\r
+ RelativePath="..\ClientCommon.c"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="..\dns-sd.c">\r
+ RelativePath="..\dns-sd.c"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
+ <File\r
+ RelativePath="..\ClientCommon.h"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="resource.h">\r
+ RelativePath="resource.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+ >\r
<File\r
- RelativePath="dns-sd.rc">\r
+ RelativePath="dns-sd.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
FF1B6915067114AF002304DD /* DNSServiceBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = FF1B6914067114AF002304DD /* DNSServiceBrowser.m */; };
FF1E351C06711BCF003DD5BC /* DNSServiceReg.m in Sources */ = {isa = PBXBuildFile; fileRef = FF1E351B06711BCF003DD5BC /* DNSServiceReg.m */; };
FF1E352606711BD6003DD5BC /* DNSServiceReg.nib in Resources */ = {isa = PBXBuildFile; fileRef = FF1E352506711BD6003DD5BC /* DNSServiceReg.nib */; };
+ FF2704F90F12A60900299571 /* ClientCommon.c in Sources */ = {isa = PBXBuildFile; fileRef = FF2704F80F12A60900299571 /* ClientCommon.c */; };
FF964AA10671153B0099215A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF964AA00671153B0099215A /* Foundation.framework */; };
FF964CAA0671155C0099215A /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF964CA90671155C0099215A /* AppKit.framework */; };
FF964DAC067115710099215A /* DNSServiceBrowser.nib in Resources */ = {isa = PBXBuildFile; fileRef = FF964DAB067115710099215A /* DNSServiceBrowser.nib */; };
/* Begin PBXFileReference section */
08FB7796FE84155DC02AAC07 /* dns-sd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "dns-sd.c"; sourceTree = "<group>"; };
- 8DD76F7E0486A8DE00D96B5E /* dns-sd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "dns-sd"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8DD76F7E0486A8DE00D96B5E /* dns-sd */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = "dns-sd"; sourceTree = BUILT_PRODUCTS_DIR; };
FF1B691106711383002304DD /* DNS Service Browser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DNS Service Browser.app"; sourceTree = BUILT_PRODUCTS_DIR; };
FF1B6914067114AF002304DD /* DNSServiceBrowser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DNSServiceBrowser.m; sourceTree = "<group>"; };
FF1E351306711B5C003DD5BC /* DNS Service Registration.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DNS Service Registration.app"; sourceTree = BUILT_PRODUCTS_DIR; };
FF1E351B06711BCF003DD5BC /* DNSServiceReg.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DNSServiceReg.m; sourceTree = "<group>"; };
FF1E352506711BD6003DD5BC /* DNSServiceReg.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = DNSServiceReg.nib; sourceTree = "<group>"; };
+ FF2704F80F12A60900299571 /* ClientCommon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ClientCommon.c; sourceTree = "<group>"; };
FF964AA00671153B0099215A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
FF964CA90671155C0099215A /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
FF964DAB067115710099215A /* DNSServiceBrowser.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = DNSServiceBrowser.nib; sourceTree = "<group>"; };
isa = PBXGroup;
children = (
08FB7796FE84155DC02AAC07 /* dns-sd.c */,
+ FF2704F80F12A60900299571 /* ClientCommon.c */,
FF1B6914067114AF002304DD /* DNSServiceBrowser.m */,
FF1E351B06711BCF003DD5BC /* DNSServiceReg.m */,
);
buildActionMask = 2147483647;
files = (
8DD76F770486A8DE00D96B5E /* dns-sd.c in Sources */,
+ FF2704F90F12A60900299571 /* ClientCommon.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
-<VisualStudioProject>\r
- <CSHARP\r
- ProjectType = "Local"\r
- ProductVersion = "7.0.9466"\r
- SchemaVersion = "1.0"\r
- ProjectGuid = "{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}"\r
- >\r
- <Build>\r
- <Settings\r
- ApplicationIcon = ""\r
- AssemblyKeyContainerName = ""\r
- AssemblyName = "DNSServiceBrowser_NET"\r
- AssemblyOriginatorKeyFile = ""\r
- DefaultClientScript = "JScript"\r
- DefaultHTMLPageLayout = "Grid"\r
- DefaultTargetSchema = "IE50"\r
- DelaySign = "false"\r
- OutputType = "WinExe"\r
- RootNamespace = "DNSServiceBrowser_NET"\r
- StartupObject = ""\r
- >\r
- <Config\r
- Name = "Debug"\r
- AllowUnsafeBlocks = "false"\r
- BaseAddress = "285212672"\r
- CheckForOverflowUnderflow = "false"\r
- ConfigurationOverrideFile = ""\r
- DefineConstants = "DEBUG;TRACE"\r
- DocumentationFile = ""\r
- DebugSymbols = "true"\r
- FileAlignment = "4096"\r
- IncrementalBuild = "true"\r
- Optimize = "false"\r
- OutputPath = "bin\Debug\"\r
- RegisterForComInterop = "false"\r
- RemoveIntegerChecks = "false"\r
- TreatWarningsAsErrors = "false"\r
- WarningLevel = "4"\r
- />\r
- <Config\r
- Name = "Release"\r
- AllowUnsafeBlocks = "false"\r
- BaseAddress = "285212672"\r
- CheckForOverflowUnderflow = "false"\r
- ConfigurationOverrideFile = ""\r
- DefineConstants = "TRACE"\r
- DocumentationFile = ""\r
- DebugSymbols = "false"\r
- FileAlignment = "4096"\r
- IncrementalBuild = "false"\r
- Optimize = "true"\r
- OutputPath = "bin\Release\"\r
- RegisterForComInterop = "false"\r
- RemoveIntegerChecks = "false"\r
- TreatWarningsAsErrors = "false"\r
- WarningLevel = "4"\r
- />\r
- </Settings>\r
- <References>\r
- <Reference\r
- Name = "System"\r
- AssemblyName = "System"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"\r
- />\r
- <Reference\r
- Name = "System.Data"\r
- AssemblyName = "System.Data"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"\r
- />\r
- <Reference\r
- Name = "System.Drawing"\r
- AssemblyName = "System.Drawing"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"\r
- />\r
- <Reference\r
- Name = "System.Windows.Forms"\r
- AssemblyName = "System.Windows.Forms"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"\r
- />\r
- <Reference\r
- Name = "System.XML"\r
- AssemblyName = "System.Xml"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"\r
- />\r
- <Reference\r
- Name = "dnssd.NET"\r
- AssemblyName = "dnssd.NET"\r
- HintPath = "..\..\mDNSWindows\DLL.NET\Release\dnssd.NET.dll"\r
- />\r
- </References>\r
- </Build>\r
- <Files>\r
- <Include>\r
- <File\r
- RelPath = "App.ico"\r
- BuildAction = "Content"\r
- />\r
- <File\r
- RelPath = "AssemblyInfo.cs"\r
- SubType = "Code"\r
- BuildAction = "Compile"\r
- />\r
- <File\r
- RelPath = "DNSServiceBrowser.cs"\r
- SubType = "Form"\r
- BuildAction = "Compile"\r
- />\r
- <File\r
- RelPath = "DNSServiceBrowser.resx"\r
- DependentUpon = "DNSServiceBrowser.cs"\r
- BuildAction = "EmbeddedResource"\r
- />\r
- </Include>\r
- </Files>\r
- </CSHARP>\r
-</VisualStudioProject>\r
-\r
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <PropertyGroup>\r
+ <ProjectType>Local</ProjectType>\r
+ <ProductVersion>8.0.50727</ProductVersion>\r
+ <SchemaVersion>2.0</SchemaVersion>\r
+ <ProjectGuid>{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}</ProjectGuid>\r
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+ <ApplicationIcon>\r
+ </ApplicationIcon>\r
+ <AssemblyKeyContainerName>\r
+ </AssemblyKeyContainerName>\r
+ <AssemblyName>DNSServiceBrowser_NET</AssemblyName>\r
+ <AssemblyOriginatorKeyFile>\r
+ </AssemblyOriginatorKeyFile>\r
+ <DefaultClientScript>JScript</DefaultClientScript>\r
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>\r
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>\r
+ <DelaySign>false</DelaySign>\r
+ <OutputType>WinExe</OutputType>\r
+ <RootNamespace>DNSServiceBrowser_NET</RootNamespace>\r
+ <StartupObject>\r
+ </StartupObject>\r
+ <FileUpgradeFlags>\r
+ </FileUpgradeFlags>\r
+ <UpgradeBackupLocation>\r
+ </UpgradeBackupLocation>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+ <OutputPath>bin\Debug\</OutputPath>\r
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\r
+ <BaseAddress>285212672</BaseAddress>\r
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>\r
+ <ConfigurationOverrideFile>\r
+ </ConfigurationOverrideFile>\r
+ <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+ <DocumentationFile>\r
+ </DocumentationFile>\r
+ <DebugSymbols>true</DebugSymbols>\r
+ <FileAlignment>4096</FileAlignment>\r
+ <Optimize>false</Optimize>\r
+ <RegisterForComInterop>false</RegisterForComInterop>\r
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>\r
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\r
+ <WarningLevel>4</WarningLevel>\r
+ <DebugType>full</DebugType>\r
+ <ErrorReport>prompt</ErrorReport>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+ <OutputPath>bin\Release\</OutputPath>\r
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\r
+ <BaseAddress>285212672</BaseAddress>\r
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>\r
+ <ConfigurationOverrideFile>\r
+ </ConfigurationOverrideFile>\r
+ <DefineConstants>TRACE</DefineConstants>\r
+ <DocumentationFile>\r
+ </DocumentationFile>\r
+ <DebugSymbols>false</DebugSymbols>\r
+ <FileAlignment>4096</FileAlignment>\r
+ <Optimize>true</Optimize>\r
+ <RegisterForComInterop>false</RegisterForComInterop>\r
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>\r
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\r
+ <WarningLevel>4</WarningLevel>\r
+ <DebugType>none</DebugType>\r
+ <ErrorReport>prompt</ErrorReport>\r
+ </PropertyGroup>\r
+ <ItemGroup>\r
+ <Reference Include="System">\r
+ <Name>System</Name>\r
+ </Reference>\r
+ <Reference Include="System.Data">\r
+ <Name>System.Data</Name>\r
+ </Reference>\r
+ <Reference Include="System.Drawing">\r
+ <Name>System.Drawing</Name>\r
+ </Reference>\r
+ <Reference Include="System.Windows.Forms">\r
+ <Name>System.Windows.Forms</Name>\r
+ </Reference>\r
+ <Reference Include="System.Xml">\r
+ <Name>System.XML</Name>\r
+ </Reference>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Content Include="App.ico" />\r
+ <Compile Include="AssemblyInfo.cs">\r
+ <SubType>Code</SubType>\r
+ </Compile>\r
+ <Compile Include="DNSServiceBrowser.cs">\r
+ <SubType>Form</SubType>\r
+ </Compile>\r
+ <EmbeddedResource Include="DNSServiceBrowser.resx">\r
+ <DependentUpon>DNSServiceBrowser.cs</DependentUpon>\r
+ <SubType>Designer</SubType>\r
+ </EmbeddedResource>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <COMReference Include="Bonjour">\r
+ <Guid>{18FBED6D-F2B7-4EC8-A4A4-46282E635308}</Guid>\r
+ <VersionMajor>1</VersionMajor>\r
+ <VersionMinor>0</VersionMinor>\r
+ <Lcid>0</Lcid>\r
+ <WrapperTool>tlbimp</WrapperTool>\r
+ <Isolated>False</Isolated>\r
+ </COMReference>\r
+ </ItemGroup>\r
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />\r
+ <PropertyGroup>\r
+ <PreBuildEvent>\r
+ </PreBuildEvent>\r
+ <PostBuildEvent>\r
+ </PostBuildEvent>\r
+ </PropertyGroup>\r
+</Project>
\ No newline at end of file
Change History (most recent first):
$Log: DNSServiceBrowser.cs,v $
+Revision 1.8 2009/06/02 18:49:23 herscher
+<rdar://problem/3948252> Update the .NET code to use the new Bonjour COM component
+
Revision 1.7 2006/08/14 23:23:58 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
using System.Windows.Forms;
using System.Data;
using System.Text;
-using Apple.DNSSD;
+using Bonjour;
namespace DNSServiceBrowser_NET
{
{
private System.Windows.Forms.ComboBox typeBox;
private System.Windows.Forms.ListBox browseList;
- private ServiceRef browser = null;
- private ServiceRef resolver = null;
+ private Bonjour.DNSSDEventManager eventManager = null;
+ private Bonjour.DNSSDService service = null;
+ private Bonjour.DNSSDService browser = null;
+ private Bonjour.DNSSDService resolver = null;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
-
- //
- // These delegates are invoked as a result of DNSService
- // operation.
- //
- delegate void AddServiceCallback(BrowseData data);
- delegate void RemoveServiceCallback(BrowseData data);
- delegate void ResolveServiceCallback(ResolveData data);
-
- AddServiceCallback addServiceCallback;
- RemoveServiceCallback removeServiceCallback;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox portField;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.ListBox serviceTextField;
- ResolveServiceCallback resolveServiceCallback;
public Form1()
{
//
InitializeComponent();
- addServiceCallback = new AddServiceCallback(OnAddService);
- removeServiceCallback = new RemoveServiceCallback(OnRemoveService);
- resolveServiceCallback = new ResolveServiceCallback(OnResolveService);
-
this.Load += new System.EventHandler(this.Form1_Load);
+
+ eventManager = new DNSSDEventManager();
+ eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);
+ eventManager.ServiceLost += new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);
+ eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);
+ eventManager.OperationFailed += new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
+
+ service = new DNSSDService();
}
private void Form1_Load(object sender, EventArgs e)
-
{
-
- typeBox.SelectedItem = "_spike._tcp";
-
+ typeBox.SelectedItem = "_http._tcp";
}
{
if( disposing )
{
- if (components != null)
- {
- components.Dispose();
- }
+ if (components != null)
+ {
+ components.Dispose();
+ }
- if (browser != null)
- {
- browser.Dispose();
- }
+ if (resolver != null)
+ {
+ resolver.Stop();
+ }
+
+ if (browser != null)
+ {
+ browser.Stop();
+ }
+
+ if (service != null)
+ {
+ service.Stop();
+ }
+
+ eventManager.ServiceFound -= new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);
+ eventManager.ServiceLost -= new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);
+ eventManager.ServiceResolved -= new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);
+ eventManager.OperationFailed -= new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
}
base.Dispose( disposing );
}
//
public class BrowseData
{
- public int InterfaceIndex;
+ public uint InterfaceIndex;
public String Name;
public String Type;
public String Domain;
//
public class ResolveData
{
- public int InterfaceIndex;
- public String FullName;
- public String HostName;
- public int Port;
- public Byte[] TxtRecord;
+ public uint InterfaceIndex;
+ public String FullName;
+ public String HostName;
+ public int Port;
+ public TXTRecord TxtRecord;
public override String
ToString()
portField.Text = resolveData.Port.ToString();
serviceTextField.Items.Clear();
-
- if (resolveData.TxtRecord != null)
- {
- for (int idx = 0; idx < TextRecord.GetCount(resolveData.TxtRecord); idx++)
- {
- String key;
- Byte[] bytes;
-
- bytes = TextRecord.GetItemAtIndex(resolveData.TxtRecord, idx, out key);
+
+ if (resolveData.TxtRecord != null)
+ {
+ for (uint idx = 0; idx < resolveData.TxtRecord.GetCount(); idx++)
+ {
+ String key;
+ Byte[] bytes;
- if (key.Length > 0)
- {
- String val = "";
+ key = resolveData.TxtRecord.GetKeyAtIndex(idx);
+ bytes = (Byte[])resolveData.TxtRecord.GetValueAtIndex(idx);
- if (bytes != null)
- {
- val = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
- }
+ if (key.Length > 0)
+ {
+ String val = "";
- serviceTextField.Items.Add(key + "=" + val);
- }
- }
- }
+ if (bytes != null)
+ {
+ val = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
+ }
+
+ serviceTextField.Items.Add(key + "=" + val);
+ }
+ }
+ }
}
//
if (browser != null)
{
- browser.Dispose();
+ browser.Stop();
}
nameField.Text = "";
try
{
- browser = DNSService.Browse(0, 0, typeBox.SelectedItem.ToString(), null, new DNSService.BrowseReply(OnBrowseReply));
+ browser = service.Browse( 0, 0, typeBox.SelectedItem.ToString(), null, eventManager );
}
catch
{
{
if (resolver != null)
{
- resolver.Dispose();
+ resolver.Stop();
+ resolver = null;
}
if (browseList.SelectedItem != null)
{
BrowseData data = (BrowseData) browseList.SelectedItem;
- resolver = DNSService.Resolve(0, 0, data.Name, data.Type, data.Domain, new DNSService.ResolveReply(OnResolveReply));
+ resolver = service.Resolve(0, data.InterfaceIndex, data.Name, data.Type, data.Domain, eventManager);
}
catch
{
}
//
- // OnAddService
+ // ServiceFound
//
- // This method is "Invoked" by OnBrowseReply. This call
- // executes in the context of the main thread
+ // This call is invoked by the DNSService core. We create
+ // a BrowseData object and invoked the appropriate method
+ // in the GUI thread so we can update the UI
//
- private void OnAddService
- (
- BrowseData data
- )
+ public void ServiceFound
+ (
+ DNSSDService sref,
+ DNSSDFlags flags,
+ uint ifIndex,
+ String serviceName,
+ String regType,
+ String domain
+ )
{
- browseList.Items.Add(data);
- browseList.Invalidate();
- }
+ BrowseData data = new BrowseData();
- //
- // OnRemoveService
- //
- // This method is "Invoked" by OnBrowseReply. This call
- // executes in the context of the main thread
- //
- private void OnRemoveService
- (
- BrowseData data
- )
- {
- browseList.Items.Remove(data);
- browseList.Invalidate();
+ data.InterfaceIndex = ifIndex;
+ data.Name = serviceName;
+ data.Type = regType;
+ data.Domain = domain;
+
+ browseList.Items.Add(data);
+ browseList.Invalidate();
}
- //
- // OnResolveService
- //
- // This method is "Invoked" by OnResolveReply. This call
- // executes in the context of the main thread
- //
- private void OnResolveService
- (
- ResolveData data
- )
+ public void ServiceLost
+ (
+ DNSSDService sref,
+ DNSSDFlags flags,
+ uint ifIndex,
+ String serviceName,
+ String regType,
+ String domain
+ )
+ {
+ BrowseData data = new BrowseData();
+
+ data.InterfaceIndex = ifIndex;
+ data.Name = serviceName;
+ data.Type = regType;
+ data.Domain = domain;
+
+ browseList.Items.Remove(data);
+ browseList.Invalidate();
+ }
+
+ public void ServiceResolved
+ (
+ DNSSDService sref,
+ DNSSDFlags flags,
+ uint ifIndex,
+ String fullName,
+ String hostName,
+ ushort port,
+ TXTRecord txtRecord
+ )
{
- resolver.Dispose();
+ ResolveData data = new ResolveData();
+
+ data.InterfaceIndex = ifIndex;
+ data.FullName = fullName;
+ data.HostName = hostName;
+ data.Port = port;
+ data.TxtRecord = txtRecord;
+
+ resolver.Stop();
resolver = null;
Populate((BrowseData) browseList.SelectedItem, data);
}
- //
- // OnBrowseReply
- //
- // This call is invoked by the DNSService core. It is
- // executed in the context of a worker thread, not the
- // main (GUI) thread. We create a BrowseData object
- // and invoked the appropriate method in the GUI thread
- // so we can update the UI
- //
- private void OnBrowseReply
- (
- ServiceRef sdRef,
- ServiceFlags flags,
- int interfaceIndex,
- ErrorCode errorCode,
- String name,
- String type,
- String domain
- )
- {
- if (errorCode == ErrorCode.NoError)
- {
- BrowseData data = new BrowseData();
-
- data.InterfaceIndex = interfaceIndex;
- data.Name = name;
- data.Type = type;
- data.Domain = domain;
-
- if ((flags & ServiceFlags.Add) != 0)
- {
- Invoke(addServiceCallback, new Object[]{data});
-
- }
- else if ((flags == 0) || ((flags & ServiceFlags.MoreComing) != 0))
- {
- Invoke(removeServiceCallback, new Object[]{data});
- }
- }
- else
- {
- MessageBox.Show("OnBrowseReply returned an error code: " + errorCode, "Error");
- }
- }
-
- private void OnResolveReply
- (
- ServiceRef sdRef,
- ServiceFlags flags,
- int interfaceIndex,
- ErrorCode errorCode,
- String fullName,
- String hostName,
- int port,
- Byte[] txtRecord
- )
- {
- if (errorCode == ErrorCode.NoError)
- {
- ResolveData data = new ResolveData();
-
- data.InterfaceIndex = interfaceIndex;
- data.FullName = fullName;
- data.HostName = hostName;
- data.Port = port;
- data.TxtRecord = txtRecord;
-
- Invoke(resolveServiceCallback, new Object[]{data});
- }
- else
- {
- MessageBox.Show("OnResolveReply returned an error code: " + errorCode, "Error");
- }
- }
- }
+ public void OperationFailed
+ (
+ DNSSDService sref,
+ DNSSDError error
+ )
+ {
+ MessageBox.Show("Operation failed: error code: " + error, "Error");
+ }
+ }
}
--- /dev/null
+<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _\r
+Partial Class DNSServiceBrowser\r
+ Inherits System.Windows.Forms.Form\r
+\r
+ 'Form overrides dispose to clean up the component list.\r
+ <System.Diagnostics.DebuggerNonUserCode()> _\r
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)\r
+ Try\r
+ If disposing AndAlso components IsNot Nothing Then\r
+ components.Dispose()\r
+ End If\r
+ Finally\r
+ MyBase.Dispose(disposing)\r
+ End Try\r
+ End Sub\r
+\r
+ 'Required by the Windows Form Designer\r
+ Private components As System.ComponentModel.IContainer\r
+\r
+ 'NOTE: The following procedure is required by the Windows Form Designer\r
+ 'It can be modified using the Windows Form Designer. \r
+ 'Do not modify it using the code editor.\r
+ <System.Diagnostics.DebuggerStepThrough()> _\r
+ Private Sub InitializeComponent()\r
+ Me.ComboBox1 = New System.Windows.Forms.ComboBox\r
+ Me.ServiceNames = New System.Windows.Forms.ListBox\r
+ Me.Label1 = New System.Windows.Forms.Label\r
+ Me.Label2 = New System.Windows.Forms.Label\r
+ Me.Label3 = New System.Windows.Forms.Label\r
+ Me.Label4 = New System.Windows.Forms.Label\r
+ Me.Label5 = New System.Windows.Forms.Label\r
+ Me.NameField = New System.Windows.Forms.TextBox\r
+ Me.PortField = New System.Windows.Forms.TextBox\r
+ Me.HostField = New System.Windows.Forms.TextBox\r
+ Me.DomainField = New System.Windows.Forms.TextBox\r
+ Me.TypeField = New System.Windows.Forms.TextBox\r
+ Me.TextRecord = New System.Windows.Forms.ListBox\r
+ Me.SuspendLayout()\r
+ '\r
+ 'ComboBox1\r
+ '\r
+ Me.ComboBox1.FormattingEnabled = True\r
+ Me.ComboBox1.Items.AddRange(New Object() {"_accessone._tcp", "_accountedge._tcp", "_actionitems._tcp", "_addressbook._tcp", "_aecoretech._tcp", "_afpovertcp._tcp", "_airport._tcp", "_animobserver._tcp", "_animolmd._tcp", "_apple-sasl._tcp", "_aquamon._tcp", "_async._tcp", "_auth._tcp", "_beep._tcp", "_bfagent._tcp", "_bootps._udp", "_bousg._tcp", "_bsqdea._tcp", "_cheat._tcp", "_chess._tcp", "_clipboard._tcp", "_collection._tcp", "_contactserver._tcp", "_cvspserver._tcp", "_cytv._tcp", "_daap._tcp", "_difi._tcp", "_distcc._tcp", "_dossier._tcp", "_dpap._tcp", "_earphoria._tcp", "_ebms._tcp", "_ebreg._tcp", "_ecbyesfsgksc._tcp", "_eheap._tcp", "_embrace._tcp", "_eppc._tcp", "_eventserver._tcp", "_exec._tcp", "_facespan._tcp", "_faxstfx._tcp", "_fish._tcp", "_fjork._tcp", "_fmpro-internal._tcp", "_ftp._tcp", "_ftpcroco._tcp", "_gbs-smp._tcp", "_gbs-stp._tcp", "_grillezvous._tcp", "_h323._tcp", "_hotwayd._tcp", "_http._tcp", "_hydra._tcp", "_ica-networking._tcp", "_ichalkboard._tcp", "_ichat._tcp", "_iconquer._tcp", "_ifolder._tcp", "_ilynx._tcp", "_imap._tcp", "_imidi._tcp", "_ipbroadcaster._tcp", "_ipp._tcp", "_ishare._tcp", "_isparx._tcp", "_ispq-vc._tcp", "_isticky._tcp", "_istorm._tcp", "_iwork._tcp", "_lan2p._tcp", "_ldap._tcp", "_liaison._tcp", "_login._tcp", "_lontalk._tcp", "_lonworks._tcp", "_macfoh-remote._tcp", "_macminder._tcp", "_moneyworks._tcp", "_mp3sushi._tcp", "_mttp._tcp", "_ncbroadcast._tcp", "_ncdirect._tcp", "_ncsyncserver._tcp", "_net-assistant._tcp", "_newton-dock._tcp", "_nfs._udp", "_nssocketport._tcp", "_odabsharing._tcp", "_omni-bookmark._tcp", "_openbase._tcp", "_p2pchat._udp", "_pdl-datastream._tcp", "_poch._tcp", "_pop3._tcp", "_postgresql._tcp", "_presence._tcp", "_printer._tcp", "_ptp._tcp", "_quinn._tcp", "_raop._tcp", "_rce._tcp", "_realplayfavs._tcp", "_rfb._tcp", "_riousbprint._tcp", "_rtsp._tcp", "_safarimenu._tcp", "_sallingclicker._tcp", "_scone._tcp", "_sdsharing._tcp", "_see._tcp", "_seeCard._tcp", "_serendipd._tcp", "_servermgr._tcp", "_sge-exec._tcp", "_sge-qmaster._tcp", "_shell._tcp", "_shout._tcp", "_shoutcast._tcp", "_soap._tcp", "_spike._tcp", "_spincrisis._tcp", "_spl-itunes._tcp", "_spr-itunes._tcp", "_ssh._tcp", "_ssscreenshare._tcp", "_stickynotes._tcp", "_strateges._tcp", "_sxqdea._tcp", "_sybase-tds._tcp", "_teamlist._tcp", "_teleport._udp", "_telnet._tcp", "_tftp._udp", "_ticonnectmgr._tcp", "_tinavigator._tcp", "_tryst._tcp", "_upnp._tcp", "_utest._tcp", "_vue4rendercow._tcp", "_webdav._tcp", "_whamb._tcp", "_wired._tcp", "_workgroup._tcp", "_workstation._tcp", "_wormhole._tcp", "_ws._tcp", "_xserveraid._tcp", "_xsync._tcp", "_xtshapro._tcp"})\r
+ Me.ComboBox1.Location = New System.Drawing.Point(13, 13)\r
+ Me.ComboBox1.Name = "ComboBox1"\r
+ Me.ComboBox1.Size = New System.Drawing.Size(252, 21)\r
+ Me.ComboBox1.Sorted = True\r
+ Me.ComboBox1.TabIndex = 0\r
+ '\r
+ 'ServiceNames\r
+ '\r
+ Me.ServiceNames.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _\r
+ Or System.Windows.Forms.AnchorStyles.Left) _\r
+ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)\r
+ Me.ServiceNames.FormattingEnabled = True\r
+ Me.ServiceNames.Location = New System.Drawing.Point(13, 41)\r
+ Me.ServiceNames.Name = "ServiceNames"\r
+ Me.ServiceNames.Size = New System.Drawing.Size(662, 251)\r
+ Me.ServiceNames.Sorted = True\r
+ Me.ServiceNames.TabIndex = 1\r
+ '\r
+ 'Label1\r
+ '\r
+ Me.Label1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.Label1.AutoSize = True\r
+ Me.Label1.Location = New System.Drawing.Point(16, 311)\r
+ Me.Label1.Name = "Label1"\r
+ Me.Label1.Size = New System.Drawing.Size(38, 13)\r
+ Me.Label1.TabIndex = 2\r
+ Me.Label1.Text = "Name:"\r
+ '\r
+ 'Label2\r
+ '\r
+ Me.Label2.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.Label2.AutoSize = True\r
+ Me.Label2.Location = New System.Drawing.Point(16, 439)\r
+ Me.Label2.Name = "Label2"\r
+ Me.Label2.Size = New System.Drawing.Size(29, 13)\r
+ Me.Label2.TabIndex = 3\r
+ Me.Label2.Text = "Port:"\r
+ '\r
+ 'Label3\r
+ '\r
+ Me.Label3.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.Label3.AutoSize = True\r
+ Me.Label3.Location = New System.Drawing.Point(16, 407)\r
+ Me.Label3.Name = "Label3"\r
+ Me.Label3.Size = New System.Drawing.Size(32, 13)\r
+ Me.Label3.TabIndex = 4\r
+ Me.Label3.Text = "Host:"\r
+ '\r
+ 'Label4\r
+ '\r
+ Me.Label4.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.Label4.AutoSize = True\r
+ Me.Label4.Location = New System.Drawing.Point(16, 374)\r
+ Me.Label4.Name = "Label4"\r
+ Me.Label4.Size = New System.Drawing.Size(46, 13)\r
+ Me.Label4.TabIndex = 5\r
+ Me.Label4.Text = "Domain:"\r
+ '\r
+ 'Label5\r
+ '\r
+ Me.Label5.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.Label5.AutoSize = True\r
+ Me.Label5.Location = New System.Drawing.Point(16, 342)\r
+ Me.Label5.Name = "Label5"\r
+ Me.Label5.Size = New System.Drawing.Size(34, 13)\r
+ Me.Label5.TabIndex = 6\r
+ Me.Label5.Text = "Type:"\r
+ '\r
+ 'NameField\r
+ '\r
+ Me.NameField.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.NameField.Location = New System.Drawing.Point(69, 309)\r
+ Me.NameField.Name = "NameField"\r
+ Me.NameField.ReadOnly = True\r
+ Me.NameField.Size = New System.Drawing.Size(195, 20)\r
+ Me.NameField.TabIndex = 7\r
+ '\r
+ 'PortField\r
+ '\r
+ Me.PortField.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.PortField.Location = New System.Drawing.Point(69, 436)\r
+ Me.PortField.Name = "PortField"\r
+ Me.PortField.ReadOnly = True\r
+ Me.PortField.Size = New System.Drawing.Size(195, 20)\r
+ Me.PortField.TabIndex = 8\r
+ '\r
+ 'HostField\r
+ '\r
+ Me.HostField.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.HostField.Location = New System.Drawing.Point(69, 403)\r
+ Me.HostField.Name = "HostField"\r
+ Me.HostField.ReadOnly = True\r
+ Me.HostField.Size = New System.Drawing.Size(195, 20)\r
+ Me.HostField.TabIndex = 9\r
+ '\r
+ 'DomainField\r
+ '\r
+ Me.DomainField.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.DomainField.Location = New System.Drawing.Point(69, 371)\r
+ Me.DomainField.Name = "DomainField"\r
+ Me.DomainField.ReadOnly = True\r
+ Me.DomainField.Size = New System.Drawing.Size(195, 20)\r
+ Me.DomainField.TabIndex = 10\r
+ '\r
+ 'TypeField\r
+ '\r
+ Me.TypeField.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.TypeField.Location = New System.Drawing.Point(69, 340)\r
+ Me.TypeField.Name = "TypeField"\r
+ Me.TypeField.ReadOnly = True\r
+ Me.TypeField.Size = New System.Drawing.Size(195, 20)\r
+ Me.TypeField.TabIndex = 11\r
+ '\r
+ 'TextRecord\r
+ '\r
+ Me.TextRecord.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _\r
+ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)\r
+ Me.TextRecord.FormattingEnabled = True\r
+ Me.TextRecord.Location = New System.Drawing.Point(278, 309)\r
+ Me.TextRecord.Name = "TextRecord"\r
+ Me.TextRecord.SelectionMode = System.Windows.Forms.SelectionMode.None\r
+ Me.TextRecord.Size = New System.Drawing.Size(397, 147)\r
+ Me.TextRecord.TabIndex = 12\r
+ '\r
+ 'Form1\r
+ '\r
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)\r
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font\r
+ Me.ClientSize = New System.Drawing.Size(690, 480)\r
+ Me.Controls.Add(Me.TextRecord)\r
+ Me.Controls.Add(Me.TypeField)\r
+ Me.Controls.Add(Me.DomainField)\r
+ Me.Controls.Add(Me.HostField)\r
+ Me.Controls.Add(Me.PortField)\r
+ Me.Controls.Add(Me.NameField)\r
+ Me.Controls.Add(Me.Label5)\r
+ Me.Controls.Add(Me.Label4)\r
+ Me.Controls.Add(Me.Label3)\r
+ Me.Controls.Add(Me.Label2)\r
+ Me.Controls.Add(Me.Label1)\r
+ Me.Controls.Add(Me.ServiceNames)\r
+ Me.Controls.Add(Me.ComboBox1)\r
+ Me.Name = "Form1"\r
+ Me.Text = "Bonjour Browser"\r
+ Me.ResumeLayout(False)\r
+ Me.PerformLayout()\r
+\r
+ End Sub\r
+ Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox\r
+ Friend WithEvents ServiceNames As System.Windows.Forms.ListBox\r
+ Friend WithEvents Label1 As System.Windows.Forms.Label\r
+ Friend WithEvents Label2 As System.Windows.Forms.Label\r
+ Friend WithEvents Label3 As System.Windows.Forms.Label\r
+ Friend WithEvents Label4 As System.Windows.Forms.Label\r
+ Friend WithEvents Label5 As System.Windows.Forms.Label\r
+ Friend WithEvents NameField As System.Windows.Forms.TextBox\r
+ Friend WithEvents PortField As System.Windows.Forms.TextBox\r
+ Friend WithEvents HostField As System.Windows.Forms.TextBox\r
+ Friend WithEvents DomainField As System.Windows.Forms.TextBox\r
+ Friend WithEvents TypeField As System.Windows.Forms.TextBox\r
+ Friend WithEvents TextRecord As System.Windows.Forms.ListBox\r
+\r
+End Class\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <PropertyGroup>\r
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+ <ProductVersion>8.0.50727</ProductVersion>\r
+ <SchemaVersion>2.0</SchemaVersion>\r
+ <ProjectGuid>{FB79E297-5703-435C-A829-51AA51CD71C2}</ProjectGuid>\r
+ <OutputType>WinExe</OutputType>\r
+ <StartupObject>DNSServiceBrowser.VB.My.MyApplication</StartupObject>\r
+ <RootNamespace>DNSServiceBrowser.VB</RootNamespace>\r
+ <AssemblyName>DNSServiceBrowser.VB</AssemblyName>\r
+ <MyType>WindowsForms</MyType>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+ <DebugSymbols>true</DebugSymbols>\r
+ <DebugType>full</DebugType>\r
+ <DefineDebug>true</DefineDebug>\r
+ <DefineTrace>true</DefineTrace>\r
+ <OutputPath>bin\Debug\</OutputPath>\r
+ <DocumentationFile>DNSServiceBrowser.VB.xml</DocumentationFile>\r
+ <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+ <DebugType>pdbonly</DebugType>\r
+ <DefineDebug>false</DefineDebug>\r
+ <DefineTrace>true</DefineTrace>\r
+ <Optimize>true</Optimize>\r
+ <OutputPath>bin\Release\</OutputPath>\r
+ <DocumentationFile>DNSServiceBrowser.VB.xml</DocumentationFile>\r
+ <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>\r
+ </PropertyGroup>\r
+ <ItemGroup>\r
+ <Reference Include="System" />\r
+ <Reference Include="System.Data" />\r
+ <Reference Include="System.Deployment" />\r
+ <Reference Include="System.Drawing" />\r
+ <Reference Include="System.Windows.Forms" />\r
+ <Reference Include="System.Xml" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Import Include="Microsoft.VisualBasic" />\r
+ <Import Include="System" />\r
+ <Import Include="System.Collections" />\r
+ <Import Include="System.Collections.Generic" />\r
+ <Import Include="System.Data" />\r
+ <Import Include="System.Drawing" />\r
+ <Import Include="System.Diagnostics" />\r
+ <Import Include="System.Windows.Forms" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Compile Include="DNSServiceBrowser.vb">\r
+ <SubType>Form</SubType>\r
+ </Compile>\r
+ <Compile Include="DNSServiceBrowser.Designer.vb">\r
+ <DependentUpon>DNSServiceBrowser.vb</DependentUpon>\r
+ <SubType>Form</SubType>\r
+ </Compile>\r
+ <Compile Include="My Project\AssemblyInfo.vb" />\r
+ <Compile Include="My Project\Application.Designer.vb">\r
+ <AutoGen>True</AutoGen>\r
+ <DependentUpon>Application.myapp</DependentUpon>\r
+ </Compile>\r
+ <Compile Include="My Project\Resources.Designer.vb">\r
+ <AutoGen>True</AutoGen>\r
+ <DesignTime>True</DesignTime>\r
+ <DependentUpon>Resources.resx</DependentUpon>\r
+ </Compile>\r
+ <Compile Include="My Project\Settings.Designer.vb">\r
+ <AutoGen>True</AutoGen>\r
+ <DependentUpon>Settings.settings</DependentUpon>\r
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>\r
+ </Compile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <EmbeddedResource Include="DNSServiceBrowser.resx">\r
+ <SubType>Designer</SubType>\r
+ <DependentUpon>DNSServiceBrowser.vb</DependentUpon>\r
+ </EmbeddedResource>\r
+ <EmbeddedResource Include="My Project\Resources.resx">\r
+ <Generator>VbMyResourcesResXFileCodeGenerator</Generator>\r
+ <LastGenOutput>Resources.Designer.vb</LastGenOutput>\r
+ <CustomToolNamespace>My.Resources</CustomToolNamespace>\r
+ <SubType>Designer</SubType>\r
+ </EmbeddedResource>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <None Include="My Project\Application.myapp">\r
+ <Generator>MyApplicationCodeGenerator</Generator>\r
+ <LastGenOutput>Application.Designer.vb</LastGenOutput>\r
+ </None>\r
+ <None Include="My Project\Settings.settings">\r
+ <Generator>SettingsSingleFileGenerator</Generator>\r
+ <CustomToolNamespace>My</CustomToolNamespace>\r
+ <LastGenOutput>Settings.Designer.vb</LastGenOutput>\r
+ </None>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <COMReference Include="Bonjour">\r
+ <Guid>{18FBED6D-F2B7-4EC8-A4A4-46282E635308}</Guid>\r
+ <VersionMajor>1</VersionMajor>\r
+ <VersionMinor>0</VersionMinor>\r
+ <Lcid>0</Lcid>\r
+ <WrapperTool>tlbimp</WrapperTool>\r
+ <Isolated>False</Isolated>\r
+ </COMReference>\r
+ </ItemGroup>\r
+ <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />\r
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+ Other similar extension points exist, see Microsoft.Common.targets.\r
+ <Target Name="BeforeBuild">\r
+ </Target>\r
+ <Target Name="AfterBuild">\r
+ </Target>\r
+ -->\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+ <!-- \r
+ Microsoft ResX Schema \r
+ \r
+ Version 2.0\r
+ \r
+ The primary goals of this format is to allow a simple XML format \r
+ that is mostly human readable. The generation and parsing of the \r
+ various data types are done through the TypeConverter classes \r
+ associated with the data types.\r
+ \r
+ Example:\r
+ \r
+ ... ado.net/XML headers & schema ...\r
+ <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+ <resheader name="version">2.0</resheader>\r
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+ <value>[base64 mime encoded serialized .NET Framework object]</value>\r
+ </data>\r
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
+ <comment>This is a comment</comment>\r
+ </data>\r
+ \r
+ There are any number of "resheader" rows that contain simple \r
+ name/value pairs.\r
+ \r
+ Each data row contains a name, and value. The row also contains a \r
+ type or mimetype. Type corresponds to a .NET class that support \r
+ text/value conversion through the TypeConverter architecture. \r
+ Classes that don't support this are serialized and stored with the \r
+ mimetype set.\r
+ \r
+ The mimetype is used for serialized objects, and tells the \r
+ ResXResourceReader how to depersist the object. This is currently not \r
+ extensible. For a given mimetype the value must be set accordingly:\r
+ \r
+ Note - application/x-microsoft.net.object.binary.base64 is the format \r
+ that the ResXResourceWriter will generate, however the reader can \r
+ read any of the formats listed below.\r
+ \r
+ mimetype: application/x-microsoft.net.object.binary.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r
+ : and then encoded with base64 encoding.\r
+ \r
+ mimetype: application/x-microsoft.net.object.soap.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+ : and then encoded with base64 encoding.\r
+\r
+ mimetype: application/x-microsoft.net.object.bytearray.base64\r
+ value : The object must be serialized into a byte array \r
+ : using a System.ComponentModel.TypeConverter\r
+ : and then encoded with base64 encoding.\r
+ -->\r
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />\r
+ <xsd:element name="root" msdata:IsDataSet="true">\r
+ <xsd:complexType>\r
+ <xsd:choice maxOccurs="unbounded">\r
+ <xsd:element name="metadata">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" use="required" type="xsd:string" />\r
+ <xsd:attribute name="type" type="xsd:string" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" />\r
+ <xsd:attribute ref="xml:space" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="assembly">\r
+ <xsd:complexType>\r
+ <xsd:attribute name="alias" type="xsd:string" />\r
+ <xsd:attribute name="name" type="xsd:string" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="data">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />\r
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+ <xsd:attribute ref="xml:space" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="resheader">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:choice>\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:schema>\r
+ <resheader name="resmimetype">\r
+ <value>text/microsoft-resx</value>\r
+ </resheader>\r
+ <resheader name="version">\r
+ <value>2.0</value>\r
+ </resheader>\r
+ <resheader name="reader">\r
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+ <resheader name="writer">\r
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+</root>
\ No newline at end of file
--- /dev/null
+Public Class DNSServiceBrowser\r
+ Public WithEvents MyEventManager As New Bonjour.DNSSDEventManager\r
+\r
+ Private m_service As New Bonjour.DNSSDService\r
+ Private m_browser As Bonjour.DNSSDService\r
+ Private m_resolver As Bonjour.DNSSDService\r
+\r
+ Public Sub New()\r
+ MyBase.New()\r
+\r
+ 'This call is required by the Windows Form Designer.\r
+ InitializeComponent()\r
+\r
+ ComboBox1.SelectedIndex = 0\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceFound(ByVal browser As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal serviceName As String, ByVal regtype As String, ByVal domain As String) Handles MyEventManager.ServiceFound\r
+ Dim browseData As New BrowseData\r
+ browseData.ServiceName = serviceName\r
+ browseData.RegType = regtype\r
+ browseData.Domain = domain\r
+ ServiceNames.Items.Add(browseData)\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceLost(ByVal browser As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal serviceName As String, ByVal regtype As String, ByVal domain As String) Handles MyEventManager.ServiceLost\r
+ ServiceNames.Items.Remove(serviceName)\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceResolved(ByVal resolver As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal fullname As String, ByVal hostname As String, ByVal port As UShort, ByVal record As Bonjour.TXTRecord) Handles MyEventManager.ServiceResolved\r
+ m_resolver.Stop()\r
+ m_resolver = Nothing\r
+ Dim browseData As BrowseData = ServiceNames.Items.Item(ServiceNames.SelectedIndex)\r
+ NameField.Text = browseData.ServiceName\r
+ TypeField.Text = browseData.RegType\r
+ DomainField.Text = browseData.Domain\r
+ HostField.Text = hostname\r
+ PortField.Text = port\r
+\r
+ If record IsNot Nothing Then\r
+ For i As UInteger = 0 To record.GetCount() - 1\r
+ Dim key As String = record.GetKeyAtIndex(i)\r
+ If key.Length() > 0 Then\r
+ TextRecord.Items.Add(key + "=" + System.Text.Encoding.ASCII.GetString(record.GetValueAtIndex(i)))\r
+ End If\r
+ Next i\r
+ End If\r
+ End Sub\r
+ Private Sub ClearServiceInfo()\r
+ TextRecord.Items.Clear()\r
+ NameField.Text = ""\r
+ TypeField.Text = ""\r
+ DomainField.Text = ""\r
+ HostField.Text = ""\r
+ PortField.Text = ""\r
+ End Sub\r
+ Private Sub ServiceNames_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ServiceNames.SelectedIndexChanged\r
+ If m_resolver IsNot Nothing Then\r
+ m_resolver.Stop()\r
+ End If\r
+ Me.ClearServiceInfo()\r
+ Dim browseData As BrowseData = ServiceNames.Items.Item(ServiceNames.SelectedIndex)\r
+ m_resolver = m_service.Resolve(0, 0, browseData.ServiceName, browseData.RegType, browseData.Domain, MyEventManager)\r
+ End Sub\r
+ Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged\r
+ If m_browser IsNot Nothing Then\r
+ m_browser.Stop()\r
+ End If\r
+\r
+ ServiceNames.Items.Clear()\r
+ Me.ClearServiceInfo()\r
+ m_browser = m_service.Browse(0, 0, ComboBox1.Items.Item(ComboBox1.SelectedIndex), "", MyEventManager)\r
+ End Sub\r
+\r
+ Private Sub ListBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextRecord.SelectedIndexChanged\r
+\r
+ End Sub\r
+End Class\r
+Public Class BrowseData\r
+ Private m_serviceName As String\r
+ Private m_regType As String\r
+ Private m_domain As String\r
+\r
+ Property ServiceName() As String\r
+ Get\r
+ Return m_serviceName\r
+ End Get\r
+ Set(ByVal Value As String)\r
+ m_serviceName = Value\r
+ End Set\r
+ End Property\r
+\r
+ Property RegType() As String\r
+ Get\r
+ Return m_regType\r
+ End Get\r
+ Set(ByVal Value As String)\r
+ m_regType = Value\r
+ End Set\r
+ End Property\r
+\r
+ Property Domain() As String\r
+ Get\r
+ Return m_domain\r
+ End Get\r
+ Set(ByVal Value As String)\r
+ m_domain = Value\r
+ End Set\r
+ End Property\r
+\r
+ Public Overrides Function ToString() As String\r
+ Return m_serviceName\r
+ End Function\r
+\r
+End Class\r
--- /dev/null
+'------------------------------------------------------------------------------\r
+' <auto-generated>\r
+' This code was generated by a tool.\r
+' Runtime Version:2.0.50727.4918\r
+'\r
+' Changes to this file may cause incorrect behavior and will be lost if\r
+' the code is regenerated.\r
+' </auto-generated>\r
+'------------------------------------------------------------------------------\r
+\r
+Option Strict On\r
+Option Explicit On\r
+\r
+\r
+Namespace My\r
+ \r
+ 'NOTE: This file is auto-generated; do not modify it directly. To make changes,\r
+ ' or if you encounter build errors in this file, go to the Project Designer\r
+ ' (go to Project Properties or double-click the My Project node in\r
+ ' Solution Explorer), and make changes on the Application tab.\r
+ '\r
+ Partial Friend Class MyApplication\r
+ \r
+ <Global.System.Diagnostics.DebuggerStepThroughAttribute()> _\r
+ Public Sub New()\r
+ MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)\r
+ Me.IsSingleInstance = false\r
+ Me.EnableVisualStyles = true\r
+ Me.SaveMySettingsOnExit = true\r
+ Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses\r
+ End Sub\r
+ \r
+ <Global.System.Diagnostics.DebuggerStepThroughAttribute()> _\r
+ Protected Overrides Sub OnCreateMainForm()\r
+ Me.MainForm = Global.DNSServiceBrowser.VB.DNSServiceBrowser\r
+ End Sub\r
+ End Class\r
+End Namespace\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">\r
+ <MySubMain>true</MySubMain>\r
+ <MainForm>DNSServiceBrowser</MainForm>\r
+ <SingleInstance>false</SingleInstance>\r
+ <ShutdownMode>0</ShutdownMode>\r
+ <EnableVisualStyles>true</EnableVisualStyles>\r
+ <AuthenticationMode>0</AuthenticationMode>\r
+ <SaveMySettingsOnExit>true</SaveMySettingsOnExit>\r
+</MyApplicationData>
\ No newline at end of file
--- /dev/null
+Imports System\r
+Imports System.Reflection\r
+Imports System.Runtime.InteropServices\r
+\r
+' General Information about an assembly is controlled through the following \r
+' set of attributes. Change these attribute values to modify the information\r
+' associated with an assembly.\r
+\r
+' Review the values of the assembly attributes\r
+\r
+<Assembly: AssemblyTitle("VBTester")> \r
+<Assembly: AssemblyDescription("")> \r
+<Assembly: AssemblyCompany("Porchdog Software, Inc.")> \r
+<Assembly: AssemblyProduct("VBTester")> \r
+<Assembly: AssemblyCopyright("Copyright © Porchdog Software, Inc. 2009")> \r
+<Assembly: AssemblyTrademark("")> \r
+\r
+<Assembly: ComVisible(False)>\r
+\r
+'The following GUID is for the ID of the typelib if this project is exposed to COM\r
+<Assembly: Guid("fa682747-1bdc-4ddb-962e-e3e3a9291b22")> \r
+\r
+' Version information for an assembly consists of the following four values:\r
+'\r
+' Major Version\r
+' Minor Version \r
+' Build Number\r
+' Revision\r
+'\r
+' You can specify all the values or you can default the Build and Revision Numbers \r
+' by using the '*' as shown below:\r
+' <Assembly: AssemblyVersion("1.0.*")> \r
+\r
+<Assembly: AssemblyVersion("1.0.0.0")> \r
+<Assembly: AssemblyFileVersion("1.0.0.0")> \r
--- /dev/null
+'------------------------------------------------------------------------------\r
+' <auto-generated>\r
+' This code was generated by a tool.\r
+' Runtime Version:2.0.50727.3082\r
+'\r
+' Changes to this file may cause incorrect behavior and will be lost if\r
+' the code is regenerated.\r
+' </auto-generated>\r
+'------------------------------------------------------------------------------\r
+\r
+Option Strict On\r
+Option Explicit On\r
+\r
+\r
+Namespace My.Resources\r
+ \r
+ 'This class was auto-generated by the StronglyTypedResourceBuilder\r
+ 'class via a tool like ResGen or Visual Studio.\r
+ 'To add or remove a member, edit your .ResX file then rerun ResGen\r
+ 'with the /str option, or rebuild your VS project.\r
+ '<summary>\r
+ ' A strongly-typed resource class, for looking up localized strings, etc.\r
+ '</summary>\r
+ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0"), _\r
+ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _\r
+ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _\r
+ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _\r
+ Friend Module Resources\r
+ \r
+ Private resourceMan As Global.System.Resources.ResourceManager\r
+ \r
+ Private resourceCulture As Global.System.Globalization.CultureInfo\r
+ \r
+ '<summary>\r
+ ' Returns the cached ResourceManager instance used by this class.\r
+ '</summary>\r
+ <Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager\r
+ Get\r
+ If Object.ReferenceEquals(resourceMan, Nothing) Then\r
+ Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("VBTester.Resources", GetType(Resources).Assembly)\r
+ resourceMan = temp\r
+ End If\r
+ Return resourceMan\r
+ End Get\r
+ End Property\r
+ \r
+ '<summary>\r
+ ' Overrides the current thread's CurrentUICulture property for all\r
+ ' resource lookups using this strongly typed resource class.\r
+ '</summary>\r
+ <Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Friend Property Culture() As Global.System.Globalization.CultureInfo\r
+ Get\r
+ Return resourceCulture\r
+ End Get\r
+ Set(ByVal value As Global.System.Globalization.CultureInfo)\r
+ resourceCulture = value\r
+ End Set\r
+ End Property\r
+ End Module\r
+End Namespace\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+ <!-- \r
+ Microsoft ResX Schema \r
+ \r
+ Version 2.0\r
+ \r
+ The primary goals of this format is to allow a simple XML format \r
+ that is mostly human readable. The generation and parsing of the \r
+ various data types are done through the TypeConverter classes \r
+ associated with the data types.\r
+ \r
+ Example:\r
+ \r
+ ... ado.net/XML headers & schema ...\r
+ <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+ <resheader name="version">2.0</resheader>\r
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+ <value>[base64 mime encoded serialized .NET Framework object]</value>\r
+ </data>\r
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
+ <comment>This is a comment</comment>\r
+ </data>\r
+ \r
+ There are any number of "resheader" rows that contain simple \r
+ name/value pairs.\r
+ \r
+ Each data row contains a name, and value. The row also contains a \r
+ type or mimetype. Type corresponds to a .NET class that support \r
+ text/value conversion through the TypeConverter architecture. \r
+ Classes that don't support this are serialized and stored with the \r
+ mimetype set.\r
+ \r
+ The mimetype is used for serialized objects, and tells the \r
+ ResXResourceReader how to depersist the object. This is currently not \r
+ extensible. For a given mimetype the value must be set accordingly:\r
+ \r
+ Note - application/x-microsoft.net.object.binary.base64 is the format \r
+ that the ResXResourceWriter will generate, however the reader can \r
+ read any of the formats listed below.\r
+ \r
+ mimetype: application/x-microsoft.net.object.binary.base64\r
+ value : The object must be serialized with \r
+ : System.Serialization.Formatters.Binary.BinaryFormatter\r
+ : and then encoded with base64 encoding.\r
+ \r
+ mimetype: application/x-microsoft.net.object.soap.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+ : and then encoded with base64 encoding.\r
+\r
+ mimetype: application/x-microsoft.net.object.bytearray.base64\r
+ value : The object must be serialized into a byte array \r
+ : using a System.ComponentModel.TypeConverter\r
+ : and then encoded with base64 encoding.\r
+ -->\r
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+ <xsd:element name="root" msdata:IsDataSet="true">\r
+ <xsd:complexType>\r
+ <xsd:choice maxOccurs="unbounded">\r
+ <xsd:element name="metadata">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" />\r
+ <xsd:attribute name="type" type="xsd:string" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="assembly">\r
+ <xsd:complexType>\r
+ <xsd:attribute name="alias" type="xsd:string" />\r
+ <xsd:attribute name="name" type="xsd:string" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="data">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />\r
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="resheader">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:choice>\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:schema>\r
+ <resheader name="resmimetype">\r
+ <value>text/microsoft-resx</value>\r
+ </resheader>\r
+ <resheader name="version">\r
+ <value>2.0</value>\r
+ </resheader>\r
+ <resheader name="reader">\r
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+ <resheader name="writer">\r
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+</root>
\ No newline at end of file
--- /dev/null
+'------------------------------------------------------------------------------\r
+' <auto-generated>\r
+' This code was generated by a tool.\r
+' Runtime Version:2.0.50727.3082\r
+'\r
+' Changes to this file may cause incorrect behavior and will be lost if\r
+' the code is regenerated.\r
+' </auto-generated>\r
+'------------------------------------------------------------------------------\r
+\r
+Option Strict On\r
+Option Explicit On\r
+\r
+\r
+Namespace My\r
+\r
+ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _\r
+ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0"), _\r
+ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Partial Friend NotInheritable Class MySettings\r
+ Inherits Global.System.Configuration.ApplicationSettingsBase\r
+ \r
+ Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)\r
+ \r
+#Region "My.Settings Auto-Save Functionality"\r
+#If _MyType = "WindowsForms" Then\r
+ Private Shared addedHandler As Boolean\r
+\r
+ Private Shared addedHandlerLockObject As New Object\r
+\r
+ <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)\r
+ If My.Application.SaveMySettingsOnExit Then\r
+ My.Settings.Save()\r
+ End If\r
+ End Sub\r
+#End If\r
+#End Region\r
+ \r
+ Public Shared ReadOnly Property [Default]() As MySettings\r
+ Get\r
+ \r
+#If _MyType = "WindowsForms" Then\r
+ If Not addedHandler Then\r
+ SyncLock addedHandlerLockObject\r
+ If Not addedHandler Then\r
+ AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings\r
+ addedHandler = True\r
+ End If\r
+ End SyncLock\r
+ End If\r
+#End If\r
+ Return defaultInstance\r
+ End Get\r
+ End Property\r
+ End Class\r
+End Namespace\r
+\r
+Namespace My\r
+ \r
+ <Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _\r
+ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _\r
+ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _\r
+ Friend Module MySettingsProperty\r
+ \r
+ <Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _\r
+ Friend ReadOnly Property Settings() As Global.DNSServiceBrowser.VB.My.MySettings\r
+ Get\r
+ Return Global.DNSServiceBrowser.VB.My.MySettings.Default\r
+ End Get\r
+ End Property\r
+ End Module\r
+End Namespace\r
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>\r
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">\r
+ <Profiles>\r
+ <Profile Name="(Default)" />\r
+ </Profiles>\r
+ <Settings />\r
+</SettingsFile>\r
#include "stdafx.h"
#include "ExplorerPlugin.h"
#include "About.h"
+#include "WinVersRes.h"
#include <DebugServices.h>
control->SetBitmap( ::LoadBitmap( GetNonLocalizedResources(), MAKEINTRESOURCE( IDB_ABOUT ) ) );
}
+ control = ( CStatic* ) GetDlgItem( IDC_COMPONENT_VERSION );
+ check( control );
+
+ if ( control )
+ {
+ control->SetWindowText( TEXT( MASTER_PROD_VERS_STR2 ) );
+ }
+
return b;
}
Change History (most recent first):
$Log: ExplorerBar.cpp,v $
+Revision 1.5 2009/03/30 18:44:53 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.4 2006/08/14 23:24:00 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
//===========================================================================================================================
// Not called for explorer bars
-STDMETHODIMP ExplorerBar::GetCommandString(UINT idCmd, UINT uType, UINT* pwReserved, LPSTR pszName, UINT cchMax)
+STDMETHODIMP ExplorerBar::GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pwReserved, LPSTR pszName, UINT cchMax)
{
DEBUG_UNUSED( idCmd );
DEBUG_UNUSED( uType );
Change History (most recent first):
$Log: ExplorerBar.h,v $
+Revision 1.4 2009/03/30 18:46:13 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.3 2006/08/14 23:24:00 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
// IContextMenu methods
STDMETHOD( QueryContextMenu )( HMENU hContextMenu, UINT iContextMenuFirstItem, UINT idCmdFirst, UINT idCmdLast, UINT uFlags );
- STDMETHOD( GetCommandString )( UINT idCmd, UINT uType, UINT* pwReserved, LPSTR pszName, UINT cchMax );
+ STDMETHOD( GetCommandString )( UINT_PTR idCmd, UINT uType, UINT* pwReserved, LPSTR pszName, UINT cchMax );
STDMETHOD( InvokeCommand )( LPCMINVOKECOMMANDINFO lpici );
// Other
Change History (most recent first):
$Log: ExplorerBarWindow.cpp,v $
+Revision 1.23 2009/03/30 18:47:40 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.22 2006/08/14 23:24:00 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
// OnServiceEvent
//===========================================================================================================================
-LONG
+LRESULT
ExplorerBarWindow::OnServiceEvent(WPARAM inWParam, LPARAM inLParam)
{
if (WSAGETSELECTERROR(inLParam) && !(HIWORD(inLParam)))
err = UTF8StringToStringObject( inName, service->displayName );
check_noerr( err );
- service->name = strdup( inName );
+ service->name = _strdup( inName );
require_action( service->name, exit, err = kNoMemoryErr );
- service->type = strdup( inType );
+ service->type = _strdup( inType );
require_action( service->type, exit, err = kNoMemoryErr );
- service->domain = strdup( inDomain );
+ service->domain = _strdup( inDomain );
require_action( service->domain, exit, err = kNoMemoryErr );
service->ifi = inInterfaceIndex;
Change History (most recent first):
$Log: ExplorerBarWindow.h,v $
+Revision 1.9 2009/03/30 18:49:15 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.8 2006/08/14 23:24:00 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
afx_msg void OnDestroy( void );
afx_msg void OnSize( UINT inType, int inX, int inY );
afx_msg void OnDoubleClick( NMHDR *inNMHDR, LRESULT *outResult );
- afx_msg LONG OnServiceEvent( WPARAM inWParam, LPARAM inLParam );
+ afx_msg LRESULT OnServiceEvent( WPARAM inWParam, LPARAM inLParam );
// Browsing
Change History (most recent first):
$Log: ExplorerPlugin.cpp,v $
+Revision 1.10 2009/03/30 18:51:04 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.9 2006/08/14 23:24:00 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
// Prototypes
//===========================================================================================================================
-// DLL Exports
-
-extern "C" BOOL WINAPI DllMain( HINSTANCE inInstance, DWORD inReason, LPVOID inReserved );
-
-// MFC Support
-
-DEBUG_LOCAL OSStatus MFCDLLProcessAttach( HINSTANCE inInstance );
-DEBUG_LOCAL void MFCDLLProcessDetach( HINSTANCE inInstance );
-DEBUG_LOCAL void MFCDLLThreadDetach( HINSTANCE inInstance );
-
// Utilities
DEBUG_LOCAL OSStatus RegisterServer( HINSTANCE inInstance, CLSID inCLSID, LPCTSTR inName );
// Globals
//===========================================================================================================================
-HINSTANCE gInstance = NULL;
-int gDLLRefCount = 0;
-CWinApp gApp;
+HINSTANCE gInstance = NULL;
+int gDLLRefCount = 0;
+CExplorerPluginApp gApp;
#if 0
#pragma mark -
#endif
//===========================================================================================================================
-// DllMain
+// CExplorerPluginApp::CExplorerPluginApp
//===========================================================================================================================
-BOOL WINAPI DllMain( HINSTANCE inInstance, DWORD inReason, LPVOID inReserved )
+IMPLEMENT_DYNAMIC(CExplorerPluginApp, CWinApp);
+
+CExplorerPluginApp::CExplorerPluginApp()
{
- BOOL ok;
- OSStatus err;
-
- DEBUG_UNUSED( inReserved );
-
- ok = TRUE;
- switch( inReason )
- {
- case DLL_PROCESS_ATTACH:
- gInstance = inInstance;
- debug_initialize( kDebugOutputTypeWindowsEventLog, "DNSServices Bar", inInstance );
- debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelTrace );
- dlog( kDebugLevelTrace, "\nDllMain: process attach\n" );
-
- err = MFCDLLProcessAttach( inInstance );
- ok = ( err == kNoErr );
- require_noerr( err, exit );
- break;
-
- case DLL_PROCESS_DETACH:
- dlog( kDebugLevelTrace, "DllMain: process detach\n" );
- MFCDLLProcessDetach( inInstance );
- break;
-
- case DLL_THREAD_ATTACH:
- dlog( kDebugLevelTrace, "DllMain: thread attach\n" );
- break;
-
- case DLL_THREAD_DETACH:
- dlog( kDebugLevelTrace, "DllMain: thread detach\n" );
- MFCDLLThreadDetach( inInstance );
- break;
-
- default:
- dlog( kDebugLevelTrace, "DllMain: unknown reason code (%d)\n",inReason );
- break;
- }
-
+}
+
+
+//===========================================================================================================================
+// CExplorerPluginApp::~CExplorerPluginApp
+//===========================================================================================================================
+
+CExplorerPluginApp::~CExplorerPluginApp()
+{
+}
+
+
+//===========================================================================================================================
+// CExplorerPluginApp::InitInstance
+//===========================================================================================================================
+
+BOOL
+CExplorerPluginApp::InitInstance()
+{
+ wchar_t resource[MAX_PATH];
+ OSStatus err;
+ int res;
+ HINSTANCE inInstance;
+
+ inInstance = AfxGetInstanceHandle();
+ gInstance = inInstance;
+
+ debug_initialize( kDebugOutputTypeWindowsEventLog, "DNSServices Bar", inInstance );
+ debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelTrace );
+ dlog( kDebugLevelTrace, "\nCCPApp::InitInstance\n" );
+
+ res = PathForResource( inInstance, L"ExplorerPluginResources.dll", resource, MAX_PATH );
+
+ err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
+ require_noerr( err, exit );
+
+ g_nonLocalizedResources = LoadLibrary( resource );
+ translate_errno( g_nonLocalizedResources, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ g_nonLocalizedResourcesName = resource;
+
+ res = PathForResource( inInstance, L"ExplorerPluginLocalized.dll", resource, MAX_PATH );
+ err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
+ require_noerr( err, exit );
+
+ g_localizedResources = LoadLibrary( resource );
+ translate_errno( g_localizedResources, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ AfxSetResourceHandle( g_localizedResources );
+
exit:
- return( ok );
+
+ return TRUE;
+}
+
+
+//===========================================================================================================================
+// CExplorerPluginApp::ExitInstance
+//===========================================================================================================================
+
+int
+CExplorerPluginApp::ExitInstance()
+{
+ return 0;
}
+
+
//===========================================================================================================================
// DllCanUnloadNow
//===========================================================================================================================
return( err );
}
-#if 0
-#pragma mark -
-#pragma mark == MFC Support ==
-#endif
-
-//===========================================================================================================================
-// MFCDLLProcessAttach
-//===========================================================================================================================
-
-DEBUG_LOCAL OSStatus MFCDLLProcessAttach( HINSTANCE inInstance )
-{
- wchar_t resource[MAX_PATH];
- OSStatus err;
- _AFX_THREAD_STATE * threadState;
- AFX_MODULE_STATE * previousModuleState;
- BOOL ok;
- int res;
- CWinApp * app;
-
- app = NULL;
-
- // Simulate what is done in dllmodul.cpp.
-
- threadState = AfxGetThreadState();
- check( threadState );
- previousModuleState = threadState->m_pPrevModuleState;
-
- ok = AfxWinInit( inInstance, NULL, TEXT( "" ), 0 );
- require_action( ok, exit, err = kUnknownErr );
-
- app = AfxGetApp();
- require_action( ok, exit, err = kNotInitializedErr );
-
- // Before we load the resources, let's load the error string
-
- // errorMessage.LoadString( IDS_REINSTALL );
- // errorCaption.LoadString( IDS_REINSTALL_CAPTION );
-
- // Load Resources
-
- res = PathForResource( inInstance, L"ExplorerPluginResources.dll", resource, MAX_PATH );
-
- err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
- require_noerr( err, exit );
-
- g_nonLocalizedResources = LoadLibrary( resource );
- translate_errno( g_nonLocalizedResources, GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- g_nonLocalizedResourcesName = resource;
-
- res = PathForResource( inInstance, L"ExplorerPluginLocalized.dll", resource, MAX_PATH );
- err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
- require_noerr( err, exit );
-
- g_localizedResources = LoadLibrary( resource );
- translate_errno( g_localizedResources, GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- AfxSetResourceHandle( g_localizedResources );
-
- ok = app->InitInstance();
- require_action( ok, exit, err = kUnknownErr );
-
- threadState->m_pPrevModuleState = previousModuleState;
- threadState = NULL;
- AfxInitLocalData( inInstance );
- err = kNoErr;
-
-exit:
- if( err )
- {
- if( app )
- {
- app->ExitInstance();
- }
- AfxWinTerm();
- }
- if( threadState )
- {
- threadState->m_pPrevModuleState = previousModuleState;
- }
- return( err );
-}
-
-//===========================================================================================================================
-// MFCDLLProcessDetach
-//===========================================================================================================================
-
-DEBUG_LOCAL void MFCDLLProcessDetach( HINSTANCE inInstance )
-{
- CWinApp * app;
-
- // Simulate what is done in dllmodul.cpp.
-
- app = AfxGetApp();
- if( app )
- {
- app->ExitInstance();
- }
-
-#if( DEBUG )
- if( AfxGetModuleThreadState()->m_nTempMapLock != 0 )
- {
- dlog( kDebugLevelWarning, "Warning: Temp map lock count non-zero (%ld).\n", AfxGetModuleThreadState()->m_nTempMapLock );
- }
-#endif
-
- AfxLockTempMaps();
- AfxUnlockTempMaps( -1 );
-
- // Terminate the library before destructors are called.
-
- AfxWinTerm();
- AfxTermLocalData( inInstance, TRUE );
-}
-
-//===========================================================================================================================
-// MFCDLLFinalize
-//===========================================================================================================================
-
-DEBUG_LOCAL void MFCDLLThreadDetach( HINSTANCE inInstance )
-{
- // Simulate what is done in dllmodul.cpp.
-
-#if( DEBUG )
- if( AfxGetModuleThreadState()->m_nTempMapLock != 0 )
- {
- dlog( kDebugLevelWarning, "Warning: Temp map lock count non-zero (%ld).\n", AfxGetModuleThreadState()->m_nTempMapLock );
- }
-#endif
-
- AfxLockTempMaps();
- AfxUnlockTempMaps( -1 );
- AfxTermThread( inInstance );
-}
#if 0
#pragma mark -
Change History (most recent first):
$Log: ExplorerPlugin.h,v $
+Revision 1.5 2009/03/30 18:52:02 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.4 2006/08/14 23:24:00 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
*/
+#pragma once
+
//===========================================================================================================================
// Globals
//===========================================================================================================================
extern HINSTANCE GetNonLocalizedResources();
extern HINSTANCE GetLocalizedResources();
+
+class CExplorerPluginApp : public CWinApp
+{
+public:
+
+ CExplorerPluginApp();
+ virtual ~CExplorerPluginApp();
+
+protected:
+
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+
+ DECLARE_DYNAMIC(CExplorerPluginApp);
+};
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="ExplorerPlugin"\r
ProjectGUID="{BB8AC1B5-6587-4163-BDC6-788B157705CA}"\r
- SccProjectName=""\r
- SccLocalPath="">\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
- CharacterSet="1">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ Description=""\r
+ CommandLine=""\r
+ Outputs=""\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0501"\r
- StringPooling="TRUE"\r
+ PreprocessorDefinitions="_USRDLL;WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- ForceConformanceInForLoopScope="TRUE"\r
+ BufferSecurityCheck="true"\r
+ ForceConformanceInForLoopScope="true"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderFile=""\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
BrowseInformation="1"\r
WarningLevel="4"\r
- WarnAsError="FALSE"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
CallingConvention="2"\r
- CompileAs="0"/>\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"\r
- Description="Registering"\r
- CommandLine="regsvr32.exe /s /c $(OutDir)/ExplorerPlugin.dll\r
-"\r
- Outputs="$(OUTDIR)\Register.out"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
- AdditionalDependencies="../../mDNSWindows/DLL/Debug/dnssd.lib uafxcwd.lib ws2_32.lib"\r
+ AdditionalOptions="/MACHINE:I386 /IGNORE:4089 /NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib uafxcwd.lib ws2_32.lib"\r
OutputFile="$(OutDir)/ExplorerPlugin.dll"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
IgnoreDefaultLibraryNames="uafxcwd.lib"\r
ModuleDefinitionFile="./$(ProjectName).def"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
- ImportLibrary="$(OutDir)/$(ProjectName).lib"/>\r
+ ImportLibrary="$(OutDir)/$(ProjectName).lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ExplorerPlugin.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ Description=""\r
+ CommandLine=""\r
+ Outputs=""\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
- TypeLibraryName="$(OutDir)/$(ProjectName).tlb"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="_USRDLL;WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+ BrowseInformation="1"\r
+ WarningLevel="4"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/IGNORE:4089 /NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib uafxcwd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/ExplorerPlugin.dll"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ IgnoreDefaultLibraryNames="uafxcwd.lib"\r
+ ModuleDefinitionFile="./$(ProjectName).def"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ ImportLibrary="$(OutDir)/$(ProjectName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ExplorerPlugin64.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
- CharacterSet="1">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ Description=""\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- GlobalOptimizations="TRUE"\r
InlineFunctionExpansion="2"\r
FavorSizeOrSpeed="2"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501"\r
- StringPooling="TRUE"\r
+ PreprocessorDefinitions="_USRDLL;WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
RuntimeLibrary="0"\r
- BufferSecurityCheck="FALSE"\r
- EnableFunctionLevelLinking="FALSE"\r
- ForceConformanceInForLoopScope="TRUE"\r
+ BufferSecurityCheck="true"\r
+ EnableFunctionLevelLinking="false"\r
+ ForceConformanceInForLoopScope="true"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderFile=""\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
BrowseInformation="1"\r
WarningLevel="4"\r
- WarnAsError="FALSE"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
- CompileAs="0"/>\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
- AdditionalDependencies="../../mDNSWindows/DLL/Release/dnssd.lib ws2_32.lib uafxcw.lib"\r
+ AdditionalOptions="/MACHINE:I386 /IGNORE:4089 /NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib uafxcw.lib"\r
OutputFile="$(OutDir)/$(ProjectName).dll"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
IgnoreDefaultLibraryNames="uafxcw.lib"\r
ModuleDefinitionFile="./$(ProjectName).def"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
- ImportLibrary="$(IntDir)/$(ProjectName).lib"/>\r
+ ImportLibrary="$(IntDir)/$(ProjectName).lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ExplorerPlugin.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ Description=""\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
- TypeLibraryName="$(OutDir)/$(ProjectName).tlb"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="2"\r
+ FavorSizeOrSpeed="2"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="_USRDLL;WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ RuntimeLibrary="0"\r
+ BufferSecurityCheck="true"\r
+ EnableFunctionLevelLinking="false"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+ BrowseInformation="1"\r
+ WarningLevel="4"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/IGNORE:4089 /NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib uafxcw.lib"\r
+ OutputFile="$(OutDir)/$(ProjectName).dll"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ IgnoreDefaultLibraryNames="uafxcw.lib"\r
+ ModuleDefinitionFile="./$(ProjectName).def"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ ImportLibrary="$(IntDir)/$(ProjectName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ExplorerPlugin64.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Support"\r
- Filter="">\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\CommonServices.h">\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.h">\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\isocode.h">\r
+ RelativePath="..\..\mDNSWindows\isocode.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\loclibrary.c">\r
+ RelativePath="..\..\mDNSWindows\loclibrary.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\loclibrary.h">\r
+ RelativePath="..\..\mDNSWindows\loclibrary.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\WinServices.cpp">\r
+ RelativePath="..\..\mDNSWindows\WinServices.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\WinServices.h">\r
+ RelativePath="..\..\mDNSWindows\WinServices.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">\r
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+ >\r
<File\r
- RelativePath="About.cpp">\r
+ RelativePath="About.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="ClassFactory.cpp">\r
+ RelativePath="ClassFactory.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerBar.cpp">\r
+ RelativePath="ExplorerBar.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerBarWindow.cpp">\r
+ RelativePath="ExplorerBarWindow.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerPlugin.cpp">\r
+ RelativePath="ExplorerPlugin.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerPlugin.def">\r
+ RelativePath="ExplorerPlugin.def"\r
+ >\r
</File>\r
<File\r
- RelativePath="LoginDialog.cpp">\r
+ RelativePath="LoginDialog.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="StdAfx.cpp">\r
+ RelativePath="StdAfx.cpp"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
<File\r
- RelativePath=".\About.h">\r
+ RelativePath=".\About.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ClassFactory.h">\r
+ RelativePath="ClassFactory.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerBar.h">\r
+ RelativePath="ExplorerBar.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerBarWindow.h">\r
+ RelativePath="ExplorerBarWindow.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerPlugin.h">\r
+ RelativePath="ExplorerPlugin.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="LoginDialog.h">\r
+ RelativePath="LoginDialog.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="Resource.h">\r
+ RelativePath="Resource.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="resource_dll.h">\r
+ RelativePath="resource_dll.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="StdAfx.h">\r
+ RelativePath="StdAfx.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"\r
+ >\r
<File\r
- RelativePath="ExplorerPlugin.rc">\r
+ RelativePath="ExplorerPlugin.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
<Globals>\r
<Global\r
Name="RESOURCE_FILE"\r
- Value="ExplorerPlugin.rc"/>\r
+ Value="ExplorerPlugin.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
BEGIN\r
CONTROL "",IDC_ABOUT_BACKGROUND,"Static",SS_BITMAP | SS_REALSIZEIMAGE,0,0,\r
220,86\r
- CONTROL MASTER_PROD_VERS_STR3,IDC_COMPONENT,"Static",\r
+ CONTROL "Explorer Plugin",IDC_COMPONENT,"Static",\r
SS_SIMPLE | WS_GROUP,92,10,122,8\r
- LTEXT "Copyright (c) 2004-2005 Apple Computer, Inc. All rights reserved. Apple and the Apple logo are trademarks of Apple Computer, Inc., registered in the U.S. and other countries.",\r
+ CONTROL "",IDC_COMPONENT_VERSION,"Static",\r
+ SS_SIMPLE | WS_GROUP,142,10,122,8\r
+ LTEXT "Copyright (c) 2004-2007 Apple Inc. All rights reserved. Apple and the Apple logo are trademarks of Apple Inc., registered in the U.S. and other countries.",\r
IDC_LEGAL,92,31,123,50,0,WS_EX_RTLREADING\r
END\r
\r
IDS_NAME "Bonjour"\r
IDS_WEB_SITES "Web Sites"\r
IDS_PRINTERS "Printers"\r
- IDS_MDNSRESPONDER_NOT_AVAILABLE "Bonjour Service Not Available"\r
+ IDS_MDNSRESPONDER_NOT_AVAILABLE "Bonjour Service is not available."\r
IDS_FIREWALL "Check firewall settings"\r
END\r
\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="ExplorerPluginLocRes"\r
- ProjectGUID="{BB8AC1B5-6587-4163-BDC6-788B157705CA}"\r
- SccProjectName=""\r
- SccLocalPath="">\r
+ ProjectGUID="{1643427B-F226-4AD6-B413-97DA64D5C6B4}"\r
+ RootNamespace="ExplorerPluginLocRes"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug\ExplorerPlugin.Resources\en.lproj"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
- CharacterSet="1">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"\r
- StringPooling="TRUE"\r
+ StringPooling="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- ForceConformanceInForLoopScope="TRUE"\r
+ ForceConformanceInForLoopScope="true"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderFile=""\r
AssemblerListingLocation=".\Debug/"\r
ProgramDataBaseFileName=".\Debug/"\r
BrowseInformation="1"\r
WarningLevel="4"\r
- WarnAsError="FALSE"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
CallingConvention="2"\r
- CompileAs="0"/>\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\ExplorerPlugin.Resources mkdir $(OutDir)\ExplorerPlugin.Resources
if not exist $(OutDir)\ExplorerPlugin.Resources\en.lproj mkdir $(OutDir)\ExplorerPlugin.Resources\en.lproj
"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
AdditionalDependencies=""\r
- OutputFile="$(OutDir)/ExplorerPluginLocalized.dll"\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\en.lproj\ExplorerPluginLocalized.dll"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
IgnoreDefaultLibraryNames=""\r
ModuleDefinitionFile=""\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
- ResourceOnlyDLL="TRUE"\r
- ImportLibrary="$(OutDir)/$(ProjectName).lib"/>\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(OutDir)/$(ProjectName).lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
- TypeLibraryName="$(OutDir)/$(ProjectName).tlb"/>\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"\r
+ StringPooling="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation=".\Debug/"\r
+ ObjectFile=".\Debug/"\r
+ ProgramDataBaseFileName=".\Debug/"\r
+ BrowseInformation="1"\r
+ WarningLevel="4"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
- <Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Debug\ExplorerPlugin.Resources mkdir Debug\ExplorerPlugin.Resources\r
-if not exist Debug\ExplorerPlugin.Resources\en.lproj mkdir Debug\ExplorerPlugin.Resources\en.lproj\r
-"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\ExplorerPlugin.Resources mkdir $(OutDir)\ExplorerPlugin.Resources
if not exist $(OutDir)\ExplorerPlugin.Resources\en.lproj mkdir $(OutDir)\ExplorerPlugin.Resources\en.lproj
"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
+ AdditionalDependencies=""\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\en.lproj\ExplorerPluginLocalized.dll"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ IgnoreDefaultLibraryNames=""\r
+ ModuleDefinitionFile=""\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(OutDir)/$(ProjectName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release\ExplorerPlugin.Resources\en.lproj"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
- CharacterSet="1">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- GlobalOptimizations="TRUE"\r
InlineFunctionExpansion="2"\r
FavorSizeOrSpeed="2"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"\r
- StringPooling="TRUE"\r
+ StringPooling="true"\r
RuntimeLibrary="0"\r
- BufferSecurityCheck="FALSE"\r
- EnableFunctionLevelLinking="FALSE"\r
- ForceConformanceInForLoopScope="TRUE"\r
+ BufferSecurityCheck="false"\r
+ EnableFunctionLevelLinking="false"\r
+ ForceConformanceInForLoopScope="true"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderFile=""\r
AssemblerListingLocation=".\Release/"\r
ProgramDataBaseFileName=".\Release/"\r
BrowseInformation="1"\r
WarningLevel="4"\r
- WarnAsError="FALSE"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
- CompileAs="0"/>\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\ExplorerPlugin.Resources mkdir $(OutDir)\ExplorerPlugin.Resources
if not exist $(OutDir)\ExplorerPlugin.Resources\en.lproj mkdir $(OutDir)\ExplorerPlugin.Resources\en.lproj
"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
AdditionalDependencies=""\r
- OutputFile="$(OutDir)/ExplorerPluginLocalized.dll"\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\en.lproj\ExplorerPluginLocalized.dll"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
IgnoreDefaultLibraryNames=""\r
ModuleDefinitionFile=""\r
ProgramDatabaseFile=""\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
- ResourceOnlyDLL="TRUE"\r
- ImportLibrary="$(IntDir)/$(ProjectName).lib"/>\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(IntDir)/$(ProjectName).lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources\en.lproj" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources\en.lproj"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources\en.lproj"
:END"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
- TypeLibraryName="$(OutDir)/$(ProjectName).tlb"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="2"\r
+ FavorSizeOrSpeed="2"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"\r
+ StringPooling="true"\r
+ RuntimeLibrary="0"\r
+ BufferSecurityCheck="false"\r
+ EnableFunctionLevelLinking="false"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation=".\Release/"\r
+ ObjectFile=".\Release/"\r
+ ProgramDataBaseFileName=".\Release/"\r
+ BrowseInformation="1"\r
+ WarningLevel="4"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Release mkdir Release\r
-if not exist "Release\ExplorerPlugin.Resources" mkdir "Release\ExplorerPlugin.Resources"\r
-if not exist "Release\ExplorerPlugin.Resources\en.lproj" mkdir "Release\ExplorerPlugin.Resources\en.lproj"\r
-"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\ExplorerPlugin.Resources mkdir $(OutDir)\ExplorerPlugin.Resources
if not exist $(OutDir)\ExplorerPlugin.Resources\en.lproj mkdir $(OutDir)\ExplorerPlugin.Resources\en.lproj
"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
+ AdditionalDependencies=""\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\en.lproj\ExplorerPluginLocalized.dll"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ IgnoreDefaultLibraryNames=""\r
+ ModuleDefinitionFile=""\r
+ ProgramDatabaseFile=""\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(IntDir)/$(ProjectName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources\en.lproj" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources\en.lproj"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources\en.lproj"
:END"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
<File\r
- RelativePath="resource_loc_res.h">\r
+ RelativePath="resource_loc_res.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"\r
+ >\r
<File\r
- RelativePath="ExplorerPluginLocRes.rc">\r
+ RelativePath="ExplorerPluginLocRes.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
<Globals>\r
<Global\r
Name="RESOURCE_FILE"\r
- Value="ExplorerPluginLocRes.rc"/>\r
+ Value="ExplorerPluginLocRes.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="ExplorerPluginRes"\r
- ProjectGUID="{BB8AC1B5-6587-4163-BDC6-788B157705CA}"\r
- SccProjectName=""\r
- SccLocalPath="">\r
+ ProjectGUID="{871B1492-B4A4-4B57-9237-FA798484D7D7}"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug\ExplorerPlugin.Resources"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
- CharacterSet="1">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"\r
- StringPooling="TRUE"\r
+ StringPooling="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- ForceConformanceInForLoopScope="TRUE"\r
+ ForceConformanceInForLoopScope="true"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderFile=""\r
AssemblerListingLocation=".\Debug/"\r
ProgramDataBaseFileName=".\Debug/"\r
BrowseInformation="1"\r
WarningLevel="4"\r
- WarnAsError="FALSE"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
CallingConvention="2"\r
- CompileAs="0"/>\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Debug\ExplorerPlugin.Resources mkdir Debug\ExplorerPlugin.Resources"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
- OutputFile="$(OutDir)\ExplorerPluginResources.dll"\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\ExplorerPluginResources.dll"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
IgnoreDefaultLibraryNames=""\r
ModuleDefinitionFile=""\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
- ResourceOnlyDLL="TRUE"\r
- ImportLibrary="$(OutDir)/$(ProjectName).lib"/>\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(OutDir)/$(ProjectName).lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
- TypeLibraryName="$(OutDir)/$(ProjectName).tlb"/>\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
- <Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"\r
+ StringPooling="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation=".\Debug/"\r
+ ObjectFile=".\Debug/"\r
+ ProgramDataBaseFileName=".\Debug/"\r
+ BrowseInformation="1"\r
+ WarningLevel="4"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Debug\ExplorerPlugin.Resources mkdir Debug\ExplorerPlugin.Resources"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Debug\ExplorerPlugin.Resources mkdir Debug\ExplorerPlugin.Resources"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\ExplorerPluginResources.dll"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ IgnoreDefaultLibraryNames=""\r
+ ModuleDefinitionFile=""\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(OutDir)/$(ProjectName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release\ExplorerPlugin.Resources"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
- CharacterSet="1">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- GlobalOptimizations="TRUE"\r
InlineFunctionExpansion="2"\r
FavorSizeOrSpeed="2"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"\r
- StringPooling="TRUE"\r
+ StringPooling="true"\r
RuntimeLibrary="0"\r
- BufferSecurityCheck="FALSE"\r
- EnableFunctionLevelLinking="FALSE"\r
- ForceConformanceInForLoopScope="TRUE"\r
+ BufferSecurityCheck="false"\r
+ EnableFunctionLevelLinking="false"\r
+ ForceConformanceInForLoopScope="true"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderFile=""\r
AssemblerListingLocation=".\Release/"\r
ProgramDataBaseFileName=".\Release/"\r
BrowseInformation="1"\r
WarningLevel="4"\r
- WarnAsError="FALSE"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
- CompileAs="0"/>\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Release mkdir Release
if not exist "Release\ExplorerPlugin.Resources" mkdir "Release\ExplorerPlugin.Resources"
"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
- OutputFile="$(OutDir)\ExplorerPluginResources.dll"\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\ExplorerPluginResources.dll"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
IgnoreDefaultLibraryNames=""\r
ModuleDefinitionFile=""\r
ProgramDatabaseFile=""\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
- ResourceOnlyDLL="TRUE"\r
- ImportLibrary="$(IntDir)/$(ProjectName).lib"/>\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(IntDir)/$(ProjectName).lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources"
:END"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
- TypeLibraryName="$(OutDir)/$(ProjectName).tlb"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
+ TypeLibraryName="$(OutDir)/$(ProjectName).tlb"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="2"\r
+ FavorSizeOrSpeed="2"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"\r
+ StringPooling="true"\r
+ RuntimeLibrary="0"\r
+ BufferSecurityCheck="false"\r
+ EnableFunctionLevelLinking="false"\r
+ ForceConformanceInForLoopScope="true"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation=".\Release/"\r
+ ObjectFile=".\Release/"\r
+ ProgramDataBaseFileName=".\Release/"\r
+ BrowseInformation="1"\r
+ WarningLevel="4"\r
+ WarnAsError="false"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ CompileAs="0"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Release mkdir Release\r
-if not exist "Release\ExplorerPlugin.Resources" mkdir "Release\ExplorerPlugin.Resources"\r
-"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Release mkdir Release
if not exist "Release\ExplorerPlugin.Resources" mkdir "Release\ExplorerPlugin.Resources"
"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "\r
+ OutputFile="$(OutDir)\ExplorerPlugin.Resources\ExplorerPluginResources.dll"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ IgnoreDefaultLibraryNames=""\r
+ ModuleDefinitionFile=""\r
+ ProgramDatabaseFile=""\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(IntDir)/$(ProjectName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\ExplorerPlugin.Resources"
:END"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
<File\r
- RelativePath="resource_res.h">\r
+ RelativePath="resource_res.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"\r
+ >\r
<File\r
- RelativePath="res\about.bmp">\r
+ RelativePath="res\about.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\about.bmp">\r
+ RelativePath=".\about.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\button-2k.ico">\r
+ RelativePath="res\button-2k.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\button-xp.ico">\r
+ RelativePath="res\button-xp.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\cold.ico">\r
+ RelativePath=".\res\cold.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="ExplorerPluginRes.rc">\r
+ RelativePath="ExplorerPluginRes.rc"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\hot.ico">\r
+ RelativePath=".\hot.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\logo.bmp">\r
+ RelativePath="res\logo.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\logo.bmp">\r
+ RelativePath=".\logo.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath="Web.ico">\r
+ RelativePath="Web.ico"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
<Globals>\r
<Global\r
Name="RESOURCE_FILE"\r
- Value="ExplorerPluginRes.rc"/>\r
+ Value="ExplorerPluginRes.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.Wiz97_3"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="amd64"
+ name="Microsoft.Windows.Wiz97_3"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="amd64"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
#define IDS_FIREWALL 111\r
#define IDC_COMPONENT 1001\r
#define IDC_LEGAL 1002\r
+#define IDC_COMPONENT_VERSION 1003\r
#define IDC_LOGIN_USERNAME_TEXT 1182\r
#define IDC_LOGIN_PASSWORD_TEXT 1183\r
#define ID_Menu 40001\r
#define IDS_ABOUT_URL 148\r
#define IDC_COMPONENT 1001\r
#define IDC_LEGAL 1002\r
+#define IDC_COMPONENT_VERSION 1003\r
#define IDC_LOGIN_USERNAME_TEXT 1182\r
#define IDC_LOGIN_PASSWORD_TEXT 1183\r
#define ID_Menu 40001\r
#define IDB_ABOUT 119\r
#define IDC_COMPONENT 1001\r
#define IDC_LEGAL 1002\r
+#define IDC_COMPONENT_VERSION 1003\r
#define IDC_LOGIN_USERNAME_TEXT 1182\r
#define IDC_LOGIN_PASSWORD_TEXT 1183\r
#define ID_Menu 40001\r
import com.apple.dnssd.*;
-class BrowserApp implements ListSelectionListener, ResolveListener
+class BrowserApp implements ListSelectionListener, ResolveListener, Runnable
{
static BrowserApp app;
JFrame frame;
JList domainPane, servicesPane, servicePane;
DNSSDService servicesBrowser, serviceBrowser, domainBrowser;
JLabel hostLabel, portLabel;
+ String hostNameForUpdate;
+ int portForUpdate;
public BrowserApp()
{
serviceList.getNthServiceName( newSel),
serviceList.getNthRegType( newSel),
serviceList.getNthDomain( newSel),
- new SwingResolveListener( this));
+ this);
}
}
}
catch ( Exception ex) { terminateWithException( ex); }
}
+ public void run()
+ {
+ hostLabel.setText( hostNameForUpdate);
+ portLabel.setText( String.valueOf( portForUpdate));
+ }
+
public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
String hostName, int port, TXTRecord txtRecord)
{
- hostLabel.setText( hostName);
- portLabel.setText( String.valueOf( port));
+ // We want to update GUI on the AWT event dispatching thread, but we can't stop
+ // the resolve from that thread, since stop() is synchronized with this callback.
+ // So, we stop the resolve on this thread, then invokeAndWait on the AWT event thread.
+
+ resolver.stop();
+
+ hostNameForUpdate = hostName;
+ portForUpdate = port;
+
+ try {
+ SwingUtilities.invokeAndWait(this);
+ }
+ catch ( Exception e)
+ {
+ e.printStackTrace();
+ }
}
public void operationFailed( DNSSDService service, int errorCode)
{
+ service.stop();
// handle failure here
}
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="JavaSamples"\r
ProjectGUID="{A987A0C1-344F-475C-869C-F082EB11EEBA}"\r
- Keyword="MakeFileProj">\r
+ Keyword="MakeFileProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
OutputDirectory="Debug"\r
IntermediateDirectory="Debug"\r
- ConfigurationType="0">\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
<Tool\r
Name="VCNMakeTool"\r
BuildCommandLine="nmake /f nmakefile DEBUG=1 DNS_SD=..\..\mDNSWindows\Java\build\debug\dns_sd.jar"\r
ReBuildCommandLine="nmake /f nmakefile DEBUG=1 DNS_SD=..\..\mDNSWindows\Java\build\debug\dns_sd.jar"\r
- CleanCommandLine="nmake /f nmakefile DEBUG=1 CLEAN"/>\r
+ CleanCommandLine="nmake /f nmakefile DEBUG=1 CLEAN"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
OutputDirectory="Release"\r
IntermediateDirectory="Release"\r
- ConfigurationType="0">\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake /f nmakefile DNS_SD=..\..\mDNSWindows\Java\build\prod\dns_sd.jar"\r
+ ReBuildCommandLine="nmake /f nmakefile DNS_SD=..\..\mDNSWindows\Java\build\prod\dns_sd.jar"\r
+ CleanCommandLine="nmake /f nmakefile CLEAN"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake /f nmakefile DEBUG=1 DNS_SD=..\..\mDNSWindows\Java\build\debug\dns_sd.jar"\r
+ ReBuildCommandLine="nmake /f nmakefile DEBUG=1 DNS_SD=..\..\mDNSWindows\Java\build\debug\dns_sd.jar"\r
+ CleanCommandLine="nmake /f nmakefile DEBUG=1 CLEAN"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
<Tool\r
Name="VCNMakeTool"\r
BuildCommandLine="nmake /f nmakefile DNS_SD=..\..\mDNSWindows\Java\build\prod\dns_sd.jar"\r
ReBuildCommandLine="nmake /f nmakefile DNS_SD=..\..\mDNSWindows\Java\build\prod\dns_sd.jar"\r
- CleanCommandLine="nmake /f nmakefile CLEAN"/>\r
+ CleanCommandLine="nmake /f nmakefile CLEAN"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
+++ /dev/null
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-import javax.swing.*;
-import com.apple.dnssd.*;
-
-
-/** Use this to schedule ResolveListener callbacks via SwingUtilities.invokeAndWait(). */
-
-public class SwingResolveListener implements Runnable, ResolveListener
-{
- /** Create a listener for DNSSD that will call your listener on the Swing/AWT event thread. */
- public SwingResolveListener( ResolveListener listener)
- { fListener = listener; }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- fResolver = service;
- fErrorCode = errorCode;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
- String hostName, int port, TXTRecord txtRecord)
- {
- fResolver = resolver;
- fFlags = flags;
- fIndex = ifIndex;
- fFullName = fullName;
- fHostName = hostName;
- fPort = port;
- fTXTRecord = txtRecord;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void run()
- {
- if ( fErrorCode != 0)
- fListener.operationFailed( fResolver, fErrorCode);
- else
- fListener.serviceResolved( fResolver, fFlags, fIndex, fFullName, fHostName, fPort, fTXTRecord);
- }
-
- protected void schedule()
- {
- try {
- SwingUtilities.invokeAndWait( this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected ResolveListener fListener;
-
- protected DNSSDService fResolver;
- protected int fFlags;
- protected int fIndex;
- protected int fErrorCode;
- protected String fFullName;
- protected String fHostName;
- protected int fPort;
- protected TXTRecord fTXTRecord;
-}
-
#############################################################################
-all: setup Java
+all: setup Java postbuild
# 'setup' sets up the build directory structure the way we want
setup:
@if not exist $(BAOBJ) mkdir $(BAOBJ)
@if not exist $(BUILDDIR) mkdir $(BUILDDIR)
+postbuild:
+ @if not "%RC_XBS%"=="YES" GOTO END
+ @if not exist "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java"
+ @copy "nmakefile" "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java"
+ @copy "BrowserApp.java" "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java"
+ @copy "SimpleChat.java" "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java"
+ @copy "Swing*.java" "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java"
+ @copy "$(BUILDDIR)\*.jar" "$(DSTROOT)\Program Files\Bonjour SDK\Samples\Java"
+ @:END
+
# clean removes targets and objects
clean:
@if exist $(OBJDIR) $(RMDIR) $(OBJDIR)
$(BUILDDIR)\SimpleChat.jar: $(SIMPLECHATOBJ) $(SIMPLECHATMAN)
$(JAR) -cfm $@ $(SIMPLECHATMAN) -C $(SCOBJ) .
-BROWSERAPPOBJ = $(BAOBJ)\SwingResolveListener.class \
- $(BAOBJ)\BrowserApp.class
+BROWSERAPPOBJ = $(BAOBJ)\BrowserApp.class
BROWSERAPPMAN = BrowserApp.manifest
$(BUILDDIR)\BrowserApp.jar: $(BROWSERAPPOBJ) $(BROWSERAPPMAN)
# limitations under the License.
#
# $Log: Makefile,v $
+# Revision 1.12 2008/09/05 17:37:08 cheshire
+# Need to include ClientCommon.c when building dns-sd
+#
# Revision 1.11 2007/05/29 19:57:33 cheshire
# Use "-Wall" for stricter compiler warnings
#
build:
mkdir build
-build/dns-sd: build dns-sd.c
+build/dns-sd: build dns-sd.c ClientCommon.c
cc $(filter %.c %.o, $+) $(LIBS) -I../mDNSShared -Wall -o $@
-build/dns-sd64: build dns-sd.c
+build/dns-sd64: build dns-sd.c ClientCommon.c
cc $(filter %.c %.o, $+) $(LIBS) -I../mDNSShared -Wall -o $@ -m64
# Note, we can make a 'fat' version of dns-sd using 'lipo', as shown below, but we
--- /dev/null
+/* -*- 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: Logger.cpp,v $
+Revision 1.3 2009/06/11 23:32:12 herscher
+<rdar://problem/4458913> Follow the app data folder naming convention of Safari/iTunes on Windows
+
+Revision 1.2 2009/06/11 23:11:53 herscher
+<rdar://problem/4458913> Log to user's app data folder
+
+Revision 1.1 2009/06/11 22:27:14 herscher
+<rdar://problem/4458913> Add comprehensive logging during printer installation process.
+
+ */
+
+#include "stdafx.h"
+#include "Logger.h"
+#include "DebugServices.h"
+#include <string>
+
+
+Logger::Logger()
+{
+ std::string tmp;
+ char path[ MAX_PATH ];
+ HRESULT err;
+ BOOL ok;
+
+ err = SHGetFolderPathA( NULL, CSIDL_LOCAL_APPDATA, NULL, 0, path );
+ require_noerr( err, exit );
+
+ tmp = path;
+
+ // Create Logs subdir
+ tmp += "\\Apple";
+ ok = CreateDirectoryA( tmp.c_str(), NULL );
+ require_action( ( ok || ( GetLastError() == ERROR_ALREADY_EXISTS ) ), exit, err = -1 );
+
+ // Create Logs subdir
+ tmp += "\\Bonjour";
+ ok = CreateDirectoryA( tmp.c_str(), NULL );
+ require_action( ( ok || ( GetLastError() == ERROR_ALREADY_EXISTS ) ), exit, err = -1 );
+
+ // Create log file
+ tmp += "\\PrinterSetupLog.txt";
+ open( tmp.c_str());
+
+ *this << currentTime() << " Log started" << std::endl;
+
+exit:
+
+ return;
+}
+
+
+Logger::~Logger()
+{
+ *this << currentTime() << " Log finished" << std::endl;
+ flush();
+}
+
+
+std::string
+Logger::currentTime()
+{
+ time_t ltime;
+ struct tm now;
+ int err;
+ std::string ret;
+
+ time( <ime );
+ err = localtime_s( &now, <ime );
+
+ if ( !err )
+ {
+ char temp[ 64 ];
+
+ strftime( temp, sizeof( temp ), "%m/%d/%y %I:%M:%S %p", &now );
+ ret = temp;
+ }
+
+ return ret;
+}
--- /dev/null
+/* -*- 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: Logger.h,v $
+Revision 1.1 2009/06/11 22:27:15 herscher
+<rdar://problem/4458913> Add comprehensive logging during printer installation process.
+
+
+ */
+
+#ifndef _Logger_h
+#define _Logger_h
+
+#include <fstream>
+#include <string>
+
+
+class Logger : public std::ofstream
+{
+public:
+
+ Logger();
+ ~Logger();
+
+ std::string
+ currentTime();
+};
+
+
+#define require_noerr_with_log( LOG, MESSAGE, ERR, LABEL ) \
+ do \
+ { \
+ int_least32_t localErr; \
+ localErr = (int_least32_t)( ERR ); \
+ if( localErr != 0 ) \
+ { \
+ log << log.currentTime() << " [ERROR] " << MESSAGE << " returned " << ERR << std::endl; \
+ log << log.currentTime() << " [WHERE] " << "\"" << __FILE__ << "\", \"" << __FUNCTION__ << "\", line " << __LINE__ << std::endl << std::endl; \
+ goto LABEL; \
+ } \
+ } while( 0 )
+
+
+#define require_action_with_log( LOG, X, LABEL, ACTION ) \
+ do \
+ { \
+ if( !( X ) ) \
+ { \
+ log << log.currentTime() << " [ERROR] " << #X << std::endl; \
+ log << log.currentTime() << " [WHERE] " << "\"" << __FILE__ << "\", \"" << __FUNCTION__ << "\", line " << __LINE__ << std::endl << std::endl; \
+ { ACTION; } \
+ goto LABEL; \
+ } \
+ } while( 0 )
+
+#endif
END\r
\r
\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// RT_MANIFEST\r
-//\r
-\r
-IDR_MANIFEST RT_MANIFEST "res\\PrinterSetupWizard.manifest"\r
-\r
/////////////////////////////////////////////////////////////////////////////\r
//\r
// String Table\r
<?xml version="1.0" encoding="windows-1251"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="PrinterSetupWizard"\r
ProjectGUID="{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}"\r
- Keyword="MFCProj">\r
+ Keyword="MFCProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories=".;../../mDNSWindows;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0501;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ BufferSecurityCheck="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
CallingConvention="0"\r
- DisableSpecificWarnings="4702"/>\r
+ DisableSpecificWarnings="4702"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../../mDNSWindows/DLL/Debug/dnssd.lib ws2_32.lib iphlpapi.lib winspool.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib iphlpapi.lib winspool.lib setupapi.lib"\r
OutputFile="$(OutDir)/PrinterWizard.exe"\r
LinkIncremental="2"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
EntryPointSymbol="wWinMainCRTStartup"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\PrinterSetupWizard.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories=".;../../mDNSWindows;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="0"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib iphlpapi.lib winspool.lib setupapi.lib"\r
+ OutputFile="$(OutDir)/PrinterWizard.exe"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ EntryPointSymbol="wWinMainCRTStartup"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\PrinterSetupWizard64.manifest"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
InlineFunctionExpansion="1"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories=".;../../mDNSWindows;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0501;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="FALSE"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
RuntimeLibrary="0"\r
- EnableFunctionLevelLinking="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
- DisableSpecificWarnings="4702"/>\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../../mDNSWindows/DLL/Release/dnssd.lib ws2_32.lib iphlpapi.lib winspool.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib iphlpapi.lib winspool.lib setupapi.lib"\r
OutputFile="$(OutDir)/PrinterWizard.exe"\r
LinkIncremental="1"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
EntryPointSymbol="wWinMainCRTStartup"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\PrinterSetupWizard.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories=".;../../mDNSWindows;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib iphlpapi.lib winspool.lib setupapi.lib"\r
+ OutputFile="$(OutDir)/PrinterWizard.exe"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ EntryPointSymbol="wWinMainCRTStartup"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\PrinterSetupWizard64.manifest"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">\r
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+ >\r
<File\r
- RelativePath=".\About.cpp">\r
+ RelativePath=".\About.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="FirstPage.cpp">\r
+ RelativePath="FirstPage.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\FourthPage.cpp">\r
+ RelativePath=".\FourthPage.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="PrinterSetupWizardApp.cpp">\r
+ RelativePath="PrinterSetupWizardApp.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="PrinterSetupWizardSheet.cpp">\r
+ RelativePath="PrinterSetupWizardSheet.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="SecondPage.cpp">\r
+ RelativePath="SecondPage.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="stdafx.cpp">\r
+ RelativePath="stdafx.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\StdioFileEx.cpp">\r
+ RelativePath=".\StdioFileEx.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="ThirdPage.cpp">\r
+ RelativePath="ThirdPage.cpp"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
<File\r
- RelativePath=".\About.h">\r
+ RelativePath=".\About.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="FirstPage.h">\r
+ RelativePath="FirstPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\FourthPage.h">\r
+ RelativePath=".\FourthPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="PrinterSetupWizardApp.h">\r
+ RelativePath="PrinterSetupWizardApp.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="PrinterSetupWizardSheet.h">\r
+ RelativePath="PrinterSetupWizardSheet.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="resource.h">\r
+ RelativePath="resource.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="resource_exe.h">\r
+ RelativePath="resource_exe.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="SecondPage.h">\r
+ RelativePath="SecondPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="stdafx.h">\r
+ RelativePath="stdafx.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\StdioFileEx.h">\r
+ RelativePath=".\StdioFileEx.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ThirdPage.h">\r
+ RelativePath="ThirdPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\UtilTypes.h">\r
+ RelativePath=".\UtilTypes.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"\r
+ >\r
<File\r
- RelativePath="res\about.bmp">\r
+ RelativePath="res\about.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\banner_icon.bmp">\r
+ RelativePath="res\banner_icon.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\Info.ico">\r
+ RelativePath="res\Info.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\NetworkPrinter.ico">\r
+ RelativePath="res\NetworkPrinter.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\Print.ico">\r
+ RelativePath="res\Print.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\PrinterSetupWizard.manifest">\r
+ RelativePath="res\PrinterSetupWizard.manifest"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ ExcludedFromBuild="true"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ ExcludedFromBuild="true"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ ExcludedFromBuild="true"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ ExcludedFromBuild="true"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ </FileConfiguration>\r
</File>\r
<File\r
- RelativePath="PrinterSetupWizard.rc">\r
+ RelativePath="PrinterSetupWizard.rc"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\watermark.bmp">\r
+ RelativePath="res\watermark.bmp"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Support"\r
- Filter="">\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\CommonServices.h">\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.h">\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dns_sd.h">\r
+ RelativePath="..\..\mDNSShared\dns_sd.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\isocode.h">\r
+ RelativePath="..\..\mDNSWindows\isocode.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\loclibrary.c">\r
+ RelativePath="..\..\mDNSWindows\loclibrary.c"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
- DisableSpecificWarnings="4201"/>\r
+ DisableSpecificWarnings="4201"\r
+ />\r
</FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ DisableSpecificWarnings="4201"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSWindows\loclibrary.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\Logger.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\loclibrary.h">\r
+ RelativePath=".\Logger.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\WinServices.cpp">\r
+ RelativePath="..\..\mDNSWindows\WinServices.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSWindows\WinServices.h">\r
+ RelativePath="..\..\mDNSWindows\WinServices.h"\r
+ >\r
</File>\r
</Filter>\r
<File\r
- RelativePath="ReadMe.txt">\r
+ RelativePath="ReadMe.txt"\r
+ >\r
</File>\r
</Files>\r
<Globals>\r
<Global\r
Name="RESOURCE_FILE"\r
- Value="PrinterSetupWizard.rc"/>\r
+ Value="PrinterSetupWizard.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
Change History (most recent first):
$Log: PrinterSetupWizardApp.cpp,v $
+Revision 1.10 2009/05/26 05:38:18 herscher
+<rdar://problem/6123821> use HeapSetInformation(HeapEnableTerminationOnCorruption) in dns-sd.exe and PrinterWizard.exe
+
Revision 1.9 2006/08/14 23:24:09 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#define new DEBUG_NEW
#endif
+#ifndef HeapEnableTerminationOnCorruption
+# define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS) 1
+#endif
+
+
// Stash away pointers to our resource DLLs
static HINSTANCE g_nonLocalizedResources = NULL;
int res;
OSStatus err = kNoErr;
+ HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
+
//
// initialize the debugging framework
//
LTEXT "",IDC_PRINTER_MODEL,172,104,113,8\r
LTEXT "",IDC_PRINTER_PROTOCOL,172,117,113,8\r
LTEXT "",IDC_PRINTER_DEFAULT,172,130,113,8\r
- LTEXT "To complete the installation, click Finish.",IDC_STATIC,116,187,\r
- 171,8\r
+ LTEXT "To complete the installation, click Finish.",IDC_STATIC,116,180,171,8\r
+ LTEXT "To change these settings, click Back.",IDC_STATIC,116,190,171,8\r
END\r
\r
IDD_DIALOG1 DIALOGEX 0, 0, 265, 130\r
IDS_INSTALL_ERROR_CAPTION "Error"\r
IDS_INSTALL_ERROR_MESSAGE \r
"You do not have sufficient access to your computer to connect to the selected printer."\r
+ IDS_BAD_INF_FILE "The specified location does not contain information about your printer"\r
+ IDS_BAD_INF_FILE_CAPTION "Select Device"\r
IDS_MANUFACTURER_HEADING "Manufacturer"\r
IDS_MODEL_HEADING "Model"\r
IDS_NO_PRINTERS "No Bonjour Printers are available"\r
<?xml version="1.0" encoding="windows-1251"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="PrinterSetupWizardLocRes"\r
- ProjectGUID="{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}"\r
- Keyword="MFCProj">\r
+ ProjectGUID="{967F5375-0176-43D3-ADA3-22EE25551C37}"\r
+ Keyword="MFCProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug\PrinterWizard.Resources\en.lproj"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0400;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ BufferSecurityCheck="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="4"\r
CallingConvention="0"\r
- DisableSpecificWarnings="4702"/>\r
+ DisableSpecificWarnings="4702"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\PrinterWizard.Resources mkdir $(OutDir)\PrinterWizard.Resources
if not exist $(OutDir)\PrinterWizard.Resources\en.lproj mkdir $(OutDir)\PrinterWizard.Resources\en.lproj
"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- OutputFile="$(OutDir)/PrinterWizardLocalized.dll"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\en.lproj\PrinterWizardLocalized.dll"\r
LinkIncremental="2"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
SubSystem="2"\r
EntryPointSymbol=""\r
- ResourceOnlyDLL="TRUE"\r
+ ResourceOnlyDLL="true"\r
ImportLibrary="$(OutDir)/Localized.lib"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0400;UNICODE;_UNICODE"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="0"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Debug\PrinterWizard.Resources mkdir Debug\PrinterWizard.Resources\r
-if not exist Debug\PrinterWizard.Resources\en.lproj mkdir Debug\PrinterWizard.Resources\en.lproj\r
-"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\PrinterWizard.Resources mkdir $(OutDir)\PrinterWizard.Resources
if not exist $(OutDir)\PrinterWizard.Resources\en.lproj mkdir $(OutDir)\PrinterWizard.Resources\en.lproj
"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\en.lproj\PrinterWizardLocalized.dll"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ EntryPointSymbol=""\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(OutDir)/Localized.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release\PrinterWizard.Resources\en.lproj"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
InlineFunctionExpansion="1"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0400;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="FALSE"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
RuntimeLibrary="0"\r
- EnableFunctionLevelLinking="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
- DisableSpecificWarnings="4702"/>\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\PrinterWizard.Resources mkdir $(OutDir)\PrinterWizard.Resources
if not exist $(OutDir)\PrinterWizard.Resources\en.lproj mkdir $(OutDir)\PrinterWizard.Resources\en.lproj
"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- OutputFile="$(OutDir)/PrinterWizardLocalized.dll"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\en.lproj\PrinterWizardLocalized.dll"\r
LinkIncremental="1"\r
- GenerateDebugInformation="FALSE"\r
+ GenerateDebugInformation="false"\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
EntryPointSymbol=""\r
- ResourceOnlyDLL="TRUE"\r
+ ResourceOnlyDLL="true"\r
ImportLibrary="$(IntDir)/$(TargetName).lib"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources\en.lproj" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources\en.lproj"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources\en.lproj"
:END"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
- <Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0400;UNICODE;_UNICODE"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Release mkdir Release\r
-if not exist "Release\PrinterWizard.Resources" mkdir "Release\PrinterWizard.Resources"\r
-if not exist "Release\PrinterWizard.Resources\en.lproj" mkdir "Release\PrinterWizard.Resources\en.lproj"\r
-"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist $(OutDir)\PrinterWizard.Resources mkdir $(OutDir)\PrinterWizard.Resources
if not exist $(OutDir)\PrinterWizard.Resources\en.lproj mkdir $(OutDir)\PrinterWizard.Resources\en.lproj
"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\en.lproj\PrinterWizardLocalized.dll"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="false"\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ EntryPointSymbol=""\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(IntDir)/$(TargetName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources\en.lproj" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources\en.lproj"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources\en.lproj"
:END"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
<File\r
- RelativePath="resource_loc_dll.h">\r
+ RelativePath="resource_loc_dll.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"\r
+ >\r
<File\r
- RelativePath="PrinterSetupWizardLocRes.rc">\r
+ RelativePath="PrinterSetupWizardLocRes.rc"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\PrinterSetupWizardLocRes.rc2">\r
+ RelativePath="res\PrinterSetupWizardLocRes.rc2"\r
+ >\r
</File>\r
</Filter>\r
<File\r
- RelativePath="ReadMe.txt">\r
+ RelativePath="ReadMe.txt"\r
+ >\r
</File>\r
</Files>\r
<Globals>\r
<Global\r
Name="RESOURCE_FILE"\r
- Value="PrinterSetupWizardLocRes.rc"/>\r
+ Value="PrinterSetupWizardLocRes.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
<?xml version="1.0" encoding="windows-1251"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="PrinterSetupWizardRes"\r
- ProjectGUID="{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}"\r
- Keyword="MFCProj">\r
+ ProjectGUID="{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}"\r
+ Keyword="MFCProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug\PrinterWizard.Resources"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0400;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ BufferSecurityCheck="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="4"\r
CallingConvention="0"\r
- DisableSpecificWarnings="4702"/>\r
+ DisableSpecificWarnings="4702"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Debug\PrinterWizard.Resources mkdir Debug\PrinterWizard.Resources"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- OutputFile="$(OutDir)/PrinterWizardResources.dll"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\PrinterWizardResources.dll"\r
LinkIncremental="2"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
SubSystem="2"\r
EntryPointSymbol=""\r
- ResourceOnlyDLL="TRUE"\r
+ ResourceOnlyDLL="true"\r
ImportLibrary="$(OutDir)/Localized.lib"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUGS;DEBUG=1;WINVER=0x0400;UNICODE;_UNICODE"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="0"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Debug\PrinterWizard.Resources mkdir Debug\PrinterWizard.Resources"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Debug\PrinterWizard.Resources mkdir Debug\PrinterWizard.Resources"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\PrinterWizardResources.dll"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ EntryPointSymbol=""\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(OutDir)/Localized.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release\PrinterWizard.Resources"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
InlineFunctionExpansion="1"\r
- OmitFramePointers="TRUE"\r
+ OmitFramePointers="true"\r
AdditionalIncludeDirectories="..\..\mDNSWindows"\r
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0400;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="FALSE"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
RuntimeLibrary="0"\r
- EnableFunctionLevelLinking="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
- DisableSpecificWarnings="4702"/>\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Release mkdir Release
if not exist "Release\PrinterWizard.Resources" mkdir "Release\PrinterWizard.Resources"
"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- OutputFile="$(OutDir)/PrinterWizardResources.dll"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\PrinterWizardResources.dll"\r
LinkIncremental="1"\r
- GenerateDebugInformation="FALSE"\r
+ GenerateDebugInformation="false"\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
EntryPointSymbol=""\r
- ResourceOnlyDLL="TRUE"\r
+ ResourceOnlyDLL="true"\r
ImportLibrary="$(IntDir)/$(TargetName).lib"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources"
:END"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
- <Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
+ OmitFramePointers="true"\r
+ AdditionalIncludeDirectories="..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;WINVER=0x0400;UNICODE;_UNICODE"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"\r
- Description="Building Output Directories"\r
- CommandLine="if not exist Release mkdir Release\r
-if not exist "Release\PrinterWizard.Resources" mkdir "Release\PrinterWizard.Resources"\r
-"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"/>\r
+ AdditionalIncludeDirectories="$(IntDir);../../mDNSWindows"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ Description="Building Output Directories"\r
+ CommandLine="if not exist Release mkdir Release
if not exist "Release\PrinterWizard.Resources" mkdir "Release\PrinterWizard.Resources"
"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ OutputFile="$(OutDir)\PrinterWizard.Resources\PrinterWizardResources.dll"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="false"\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ EntryPointSymbol=""\r
+ ResourceOnlyDLL="true"\r
+ ImportLibrary="$(IntDir)/$(TargetName).lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)\PrinterWizard.Resources"
:END"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl;inc">\r
+ Filter="h;hpp;hxx;hm;inl;inc"\r
+ >\r
<File\r
- RelativePath="resource_dll.h">\r
+ RelativePath="resource_dll.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"\r
+ >\r
<File\r
- RelativePath=".\res\about.bmp">\r
+ RelativePath=".\res\about.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\banner_icon.bmp">\r
+ RelativePath="res\banner_icon.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\Info.ico">\r
+ RelativePath=".\res\Info.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\NetworkPrinter.ico">\r
+ RelativePath=".\res\NetworkPrinter.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\Print.ico">\r
+ RelativePath=".\res\Print.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\Printer.bmp">\r
+ RelativePath=".\res\Printer.bmp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\Printer.ico">\r
+ RelativePath=".\res\Printer.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\res\Printer2.ico">\r
+ RelativePath=".\res\Printer2.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\PrinterSetupWizard.ico">\r
+ RelativePath="res\PrinterSetupWizard.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="PrinterSetupWizardRes.rc">\r
+ RelativePath="PrinterSetupWizardRes.rc"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\PrinterSetupWizardRes.rc2">\r
+ RelativePath="res\PrinterSetupWizardRes.rc2"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\watermark.bmp">\r
+ RelativePath="res\watermark.bmp"\r
+ >\r
</File>\r
</Filter>\r
<File\r
- RelativePath="ReadMe.txt">\r
+ RelativePath="ReadMe.txt"\r
+ >\r
</File>\r
</Files>\r
<Globals>\r
<Global\r
Name="RESOURCE_FILE"\r
- Value="PrinterSetupWizardRes.rc"/>\r
+ Value="PrinterSetupWizardRes.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
Change History (most recent first):
$Log: PrinterSetupWizardSheet.cpp,v $
+Revision 1.40 2009/06/18 18:05:50 herscher
+<rdar://problem/4694554> Eliminate the first screen of Printer Wizard and maybe combine others ("I'm Feeling Lucky")
+
+Revision 1.39 2009/06/11 22:27:16 herscher
+<rdar://problem/4458913> Add comprehensive logging during printer installation process.
+
+Revision 1.38 2009/05/27 04:49:02 herscher
+<rdar://problem/4417884> Consider setting DoubleSpool for LPR queues to improve compatibility
+
+Revision 1.37 2009/03/30 19:17:37 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/6141389> Printer Wizard crashes on launch when Bonjour Service isn't running
+<rdar://problem/5258789> Buffer overflow in PrinterWizard when printer dns hostname is too long
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
+Revision 1.36 2008/10/23 22:33:23 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
Revision 1.35 2006/08/14 23:24:09 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
//
// Installs a printer with Windows.
//
-// NOTE: this works one of two ways, depending on whether
+// Note: this works one of two ways, depending on whether
// there are drivers already installed for this printer.
// If there are, then we can just create a port with XcvData,
// and then call AddPrinter. If not, we use the printui.dll
OSStatus
CPrinterSetupWizardSheet::InstallPrinter(Printer * printer)
{
+ Logger log;
Service * service;
BOOL ok;
- OSStatus err;
+ OSStatus err = 0;
service = printer->services.front();
check( service );
//
hThread = (HANDLE) _beginthreadex_compat( NULL, 0, InstallDriverThread, printer, 0, &threadID );
err = translate_errno( hThread, (OSStatus) GetLastError(), kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "_beginthreadex_compat()", err, exit );
//
// go modal
TranslateMessage(&msg);
DispatchMessage(&msg);
}
-
+
//
// Wait until child process exits.
//
dwResult = WaitForSingleObject( hThread, INFINITE );
err = translate_errno( dwResult == WAIT_OBJECT_0, errno_compat(), err = kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "WaitForSingleObject()", err, exit );
//
// check the return value of thread
//
- require_noerr( m_driverThreadExitCode, exit );
+ require_noerr_with_log( log, "thread exit code", m_driverThreadExitCode, exit );
//
// now we know that the driver was successfully installed
if ( service->type == kPDLServiceType )
{
- err = InstallPrinterPDLAndLPR( printer, service, PROTOCOL_RAWTCP_TYPE );
- require_noerr( err, exit );
+ err = InstallPrinterPDLAndLPR( printer, service, PROTOCOL_RAWTCP_TYPE, log );
+ require_noerr_with_log( log, "InstallPrinterPDLAndLPR()", err, exit );
}
else if ( service->type == kLPRServiceType )
{
- err = InstallPrinterPDLAndLPR( printer, service, PROTOCOL_LPR_TYPE );
- require_noerr( err, exit );
+ err = InstallPrinterPDLAndLPR( printer, service, PROTOCOL_LPR_TYPE, log );
+ require_noerr_with_log( log, "InstallPrinterPDLAndLPR()", err, exit );
}
else if ( service->type == kIPPServiceType )
{
- err = InstallPrinterIPP( printer, service );
- require_noerr( err, exit );
+ err = InstallPrinterIPP( printer, service, log );
+ require_noerr_with_log( log, "InstallPrinterIPP()", err, exit );
}
else
{
- err = kUnknownErr;
- require_noerr( err, exit );
+ require_action_with_log( log, ( service->type == kPDLServiceType ) || ( service->type == kLPRServiceType ) || ( service->type == kIPPServiceType ), exit, err = kUnknownErr );
}
printer->installed = true;
{
ok = SetDefaultPrinter( printer->actualName );
err = translate_errno( ok, errno_compat(), err = kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "SetDefaultPrinter()", err, exit );
}
exit:
OSStatus
-CPrinterSetupWizardSheet::InstallPrinterPDLAndLPR(Printer * printer, Service * service, DWORD protocol )
+CPrinterSetupWizardSheet::InstallPrinterPDLAndLPR(Printer * printer, Service * service, DWORD protocol, Logger & log )
{
PRINTER_DEFAULTS printerDefaults = { NULL, NULL, SERVER_ACCESS_ADMINISTER };
DWORD dwStatus;
ok = OpenPrinter(L",XcvMonitor Standard TCP/IP Port", &hXcv, &printerDefaults);
err = translate_errno( ok, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "OpenPrinter()", err, exit );
//
// BUGBUG: MSDN said this is not required, but my experience shows it is required
pOutputData = NULL;
}
- require_action( pOutputData, exit, err = kNoMemoryErr );
+ require_action_with_log( log, pOutputData, exit, err = kNoMemoryErr );
//
// setup the port
//
ZeroMemory(&portData, sizeof(PORT_DATA_1));
- wcscpy(portData.sztPortName, printer->portName);
+
+ require_action_with_log( log, wcslen(printer->portName) < sizeof_array(portData.sztPortName), exit, err = kSizeErr );
+ wcscpy_s(portData.sztPortName, printer->portName);
portData.dwPortNumber = service->portNumber;
portData.dwVersion = 1;
+ portData.dwDoubleSpool = 1;
portData.dwProtocol = protocol;
portData.cbSize = sizeof PORT_DATA_1;
portData.dwReserved = 0L;
- wcscpy(portData.sztQueue, q->name);
- wcscpy(portData.sztIPAddress, service->hostname);
- wcscpy(portData.sztHostAddress, service->hostname);
+ require_action_with_log( log, wcslen(q->name) < sizeof_array(portData.sztQueue), exit, err = kSizeErr );
+ wcscpy_s(portData.sztQueue, q->name);
+
+ require_action_with_log( log, wcslen( service->hostname ) < sizeof_array(portData.sztHostAddress), exit, err = kSizeErr );
+ wcscpy_s( portData.sztHostAddress, service->hostname );
ok = XcvData(hXcv, L"AddPort", (PBYTE) &portData, sizeof(PORT_DATA_1), pOutputData, cbInputData, &cbOutputNeeded, &dwStatus);
err = translate_errno( ok, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "XcvData()", err, exit );
//
// add the printer
hPrinter = AddPrinter(NULL, 2, (LPBYTE) &pInfo);
err = translate_errno( hPrinter, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "AddPrinter()", err, exit );
exit:
OSStatus
-CPrinterSetupWizardSheet::InstallPrinterIPP(Printer * printer, Service * service)
+CPrinterSetupWizardSheet::InstallPrinterIPP(Printer * printer, Service * service, Logger & log)
{
DEBUG_UNUSED( service );
hPrinter = AddPrinter(NULL, 2, (LPBYTE)&pInfo);
err = translate_errno( hPrinter, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
+ require_noerr_with_log( log, "AddPrinter()", err, exit );
exit:
}
else
{
- CPrinterSetupWizardSheet::WizardException exc;
-
- exc.text.LoadString( IDS_NO_MDNSRESPONDER_SERVICE_TEXT );
- exc.caption.LoadString( IDS_ERROR_CAPTION );
-
- throw(exc);
+ CString text, caption;
+
+ text.LoadString( IDS_NO_MDNSRESPONDER_SERVICE_TEXT );
+ caption.LoadString( IDS_ERROR_CAPTION );
+
+ MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION);
+
+ _exit( 0 );
}
}
void CPrinterSetupWizardSheet::Init(void)
{
- AddPage(&m_pgFirst);
AddPage(&m_pgSecond);
AddPage(&m_pgThird);
AddPage(&m_pgFourth);
}
-LONG
+LRESULT
CPrinterSetupWizardSheet::OnSocketEvent(WPARAM inWParam, LPARAM inLParam)
{
if (WSAGETSELECTERROR(inLParam) && !(HIWORD(inLParam)))
}
-LONG
+LRESULT
CPrinterSetupWizardSheet::OnProcessEvent(WPARAM inWParam, LPARAM inLParam)
{
DEBUG_UNUSED(inLParam);
Change History (most recent first):
$Log: PrinterSetupWizardSheet.h,v $
+Revision 1.14 2009/06/11 22:27:16 herscher
+<rdar://problem/4458913> Add comprehensive logging during printer installation process.
+
+Revision 1.13 2009/03/30 19:18:49 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.12 2006/08/14 23:24:09 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#include "thirdpage.h"
#include "fourthpage.h"
#include "UtilTypes.h"
+#include "Logger.h"
#include "dns_sd.h"
#include <stdexcept>
#include <map>
//
// handles end of process event
//
- virtual LONG
+ virtual LRESULT
OnProcessEvent(WPARAM inWParam, LPARAM inLParam);
- virtual LONG
+ virtual LRESULT
OnSocketEvent(WPARAM inWParam, LPARAM inLParam);
virtual BOOL
InstallPrinter(Printer * printer);
OSStatus
- InstallPrinterPDLAndLPR(Printer * printer, Service * service, DWORD protocol);
+ InstallPrinterPDLAndLPR(Printer * printer, Service * service, DWORD protocol, Logger & log);
OSStatus
- InstallPrinterIPP(Printer * printer, Service * service);
+ InstallPrinterIPP(Printer * printer, Service * service, Logger & log);
static unsigned WINAPI
InstallDriverThread( LPVOID inParam );
Change History (most recent first):
$Log: SecondPage.cpp,v $
+Revision 1.20 2009/06/18 18:05:50 herscher
+<rdar://problem/4694554> Eliminate the first screen of Printer Wizard and maybe combine others ("I'm Feeling Lucky")
+
Revision 1.19 2006/08/14 23:24:09 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
OnAddPrinter( *it, false );
}
- // And if we hit 'Back' from page 3, then re-select printer
-
- if ( ( psheet->GetLastPage() == psheet->GetPage( 2 ) ) && printer )
+ if ( ( !printer && ( psheet->m_printers.size() > 0 ) ) || ( printer != psheet->GetSelectedPrinter() ) )
{
+ if ( !printer )
+ {
+ printer = psheet->m_printers.front();
+ }
+
psheet->SetSelectedPrinter( printer );
- m_browseList.Select( printer->item, TVGN_FIRSTVISIBLE );
+ }
+
+ if ( printer )
+ {
+ m_browseList.SelectItem( printer->item );
+ ::SetFocus( m_browseList );
}
exit:
bool moreComing )
{
CPrinterSetupWizardSheet * psheet;
+ Printer * selectedPrinter;
OSStatus err = kNoErr;
check( IsWindow( m_hWnd ) );
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
+
+ selectedPrinter = psheet->GetSelectedPrinter();
printer->item = m_browseList.InsertItem(printer->displayName);
m_browseList.EnableWindow(TRUE);
}
+ if ( !selectedPrinter )
+ {
+ psheet->SetSelectedPrinter( printer );
+ m_browseList.SelectItem( printer->item );
+ ::SetFocus( m_browseList );
+ }
+
exit:
if (!moreComing)
Change History (most recent first):
$Log: ThirdPage.cpp,v $
+Revision 1.41 2009/06/18 18:05:50 herscher
+<rdar://problem/4694554> Eliminate the first screen of Printer Wizard and maybe combine others ("I'm Feeling Lucky")
+
+Revision 1.40 2009/05/29 20:43:36 herscher
+<rdar://problem/6928136> Printer Wizard doesn't work correctly in Windows 7 64 bit
+
+Revision 1.39 2009/05/27 06:25:49 herscher
+<rdar://problem/4176334> Need error dialog when selecting bad INF file
+
+Revision 1.38 2009/05/27 04:59:57 herscher
+<rdar://problem/4517393> COMPATIBILITY WITH HP CLJ4700
+<rdar://problem/6142138> Compatibility with Samsung print driver files
+
Revision 1.37 2007/06/08 06:30:26 herscher
<rdar://problem/5257700> Fix uninitialized pointers when detecting generic PCL and PS drivers
#include <dns_sd.h>
#include <tcpxcv.h>
#include <winspool.h>
+#include <setupapi.h>
// local variable is initialize but not referenced
#pragma warning(disable:4189)
#define kGenericPCLColorDriver L"HP Color LaserJet 4550 PCL"
#define kGenericPCLDriver L"HP LaserJet 4050 Series PCL"
-//
-// states for parsing ntprint.inf
-//
-enum PrinterParsingState
-{
- Looking,
- ParsingManufacturers,
- ParsingModels,
- ParsingStrings
-};
// CThirdPage dialog
// ------------------------------------------------------
// LoadPrintDriverDefsFromFile
//
-// This function does all the heavy lifting in parsing inf
-// files. It is called to parse both ntprint.inf, and driver
-// files that might be shipped on a printer's installation
-// disk
-//
-// The inf file is not totally parsed. I only want to determine
-// the manufacturer and models that are involved. I leave it
-// to printui.dll to actually copy the driver files to the
-// right places.
-//
-// I was aiming to parse as little as I could so as not to
-// duplicate the parsing code that is contained in Windows. There
-// are no public APIs for parsing inf files.
-//
-// That part of the inf file that we're interested in has a fairly
-// easy format. Tags are strings that are enclosed in brackets.
-// We are only interested in [MANUFACTURERS] and models.
-//
// The only potentially opaque thing about this function is the
// checkForDuplicateModels flag. The problem here is that ntprint.inf
// doesn't contain duplicate models, and it has hundreds of models
OSStatus
CThirdPage::LoadPrintDriverDefsFromFile(Manufacturers & manufacturers, const CString & filename, bool checkForDuplicateModels )
{
- PrinterParsingState state = Looking;
- Manufacturers::iterator iter = manufacturers.end();
- CStdioFileEx file;
- CFileException feError;
- CString s;
- OSStatus err;
- BOOL ok;
-
- typedef std::map<CString, CString> StringMap;
+ HINF handle = INVALID_HANDLE_VALUE;
+ const TCHAR * section = TEXT( "Manufacturer" );
+ LONG sectionCount;
+ TCHAR line[ 1000 ];
+ CString klass;
+ INFCONTEXT manufacturerContext;
+ BOOL ok;
+ OSStatus err = 0;
+
+ // Make sure we can open the file
+ handle = SetupOpenInfFile( filename, NULL, INF_STYLE_WIN4, NULL );
+ translate_errno( handle != INVALID_HANDLE_VALUE, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
- StringMap strings;
-
- ok = file.Open( filename, CFile::modeRead|CFile::typeText, &feError);
- err = translate_errno( ok, errno_compat(), kUnknownErr );
+ // Make sure it's a printer file
+ ok = SetupGetLineText( NULL, handle, TEXT( "Version" ), TEXT( "Class" ), line, sizeof( line ), NULL );
+ translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
+ klass = line;
+ require_action( klass == TEXT( "Printer" ), exit, err = kUnknownErr );
- check ( state == Looking );
- check ( iter == manufacturers.end() );
+ sectionCount = SetupGetLineCount( handle, section );
+ translate_errno( sectionCount != -1, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
- //
- // first, parse the file looking for string sections
- //
- while (file.ReadString(s))
+ memset( &manufacturerContext, 0, sizeof( manufacturerContext ) );
+
+ for ( LONG i = 0; i < sectionCount; i++ )
{
- //
- // check for comment
- //
- if (s.Find(';') == 0)
+ Manufacturers::iterator iter;
+ Manufacturer * manufacturer;
+ CString manufacturerName;
+ CString temp;
+ CStringList modelSectionNameDecl;
+ CString modelSectionName;
+ CString baseModelName;
+ CString model;
+ INFCONTEXT modelContext;
+ LONG modelCount;
+ POSITION p;
+
+ if ( i == 0 )
{
- continue;
- }
-
- //
- // check for tag
- //
- else if (s.Find('[') == 0)
- {
- //
- // handle any capitalization issues here
- //
- CString tag = s;
-
- tag.MakeLower();
-
- if (tag == L"[strings]")
- {
- state = ParsingStrings;
- }
- else
- {
- state = Looking;
- }
+ ok = SetupFindFirstLine( handle, section, NULL, &manufacturerContext );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
}
else
{
- switch (state)
- {
- case ParsingStrings:
- {
- int curPos = 0;
-
- if (s.GetLength() > 0)
- {
- CString key = s.Tokenize(L"=",curPos);
- CString val = s.Tokenize(L"=",curPos);
-
- //
- // get rid of all delimiters
- //
- key.Trim();
- val.Remove('"');
-
- //
- // and store it
- //
- strings[key] = val;
- }
- }
- break;
- }
+ ok = SetupFindNextLine( &manufacturerContext, &manufacturerContext );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
}
- }
-
- file.Close();
- ok = file.Open( filename, CFile::modeRead|CFile::typeText, &feError);
- err = translate_errno( ok, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
-
- state = Looking;
+ ok = SetupGetStringField( &manufacturerContext, 0, line, sizeof( line ), NULL );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+ manufacturerName = line;
- check ( iter == manufacturers.end() );
+ ok = SetupGetLineText( &manufacturerContext, handle, NULL, NULL, line, sizeof( line ), NULL );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
- while (file.ReadString(s))
- {
+ // Try to find some model section name that has entries. Explanation of int file structure
+ // can be found at:
//
- // check for comment
- //
- if (s.Find(';') == 0)
+ // <http://msdn.microsoft.com/en-us/library/ms794359.aspx>
+ Split( line, ',', modelSectionNameDecl );
+
+ p = modelSectionNameDecl.GetHeadPosition();
+ modelSectionName = modelSectionNameDecl.GetNext( p );
+ modelCount = SetupGetLineCount( handle, modelSectionName );
+ baseModelName = modelSectionName;
+
+ while ( modelCount <= 0 && p )
{
- continue;
+ CString targetOSVersion;
+
+ targetOSVersion = modelSectionNameDecl.GetNext( p );
+ modelSectionName = baseModelName + TEXT( "." ) + targetOSVersion;
+ modelCount = SetupGetLineCount( handle, modelSectionName );
}
- //
- // check for tag
- //
- else if (s.Find('[') == 0)
+ if ( modelCount > 0 )
{
- //
- // handle any capitalization issues here
- //
- CString tag = s;
+ manufacturerName = NormalizeManufacturerName( manufacturerName );
- tag.MakeLower();
+ iter = manufacturers.find( manufacturerName );
- if (tag == L"[manufacturer]")
+ if ( iter != manufacturers.end() )
{
- state = ParsingManufacturers;
+ manufacturer = iter->second;
+ require_action( manufacturer, exit, err = kUnknownErr );
}
else
{
- CString name;
- int curPos;
-
- //
- // remove the leading and trailing delimiters
- //
- s.Remove('[');
- s.Remove(']');
-
- //
- // <rdar://problem/4826126>
- //
- // Ignore decorations in model declarations
- //
- curPos = 0;
- name = s.Tokenize( L".", curPos );
-
- //
- // check to see if this is a printer entry
- //
- iter = manufacturers.find( name );
-
- if (iter != manufacturers.end())
+ try
{
- state = ParsingModels;
+ manufacturer = new Manufacturer;
}
- else
+ catch (...)
{
- state = Looking;
+ manufacturer = NULL;
}
- }
- }
- //
- // only look at this if the line isn't empty, or
- // if it isn't a comment
- //
- else if ((s.GetLength() > 0) && (s.Find(';') != 0))
- {
- switch (state)
- {
- //
- // if we're parsing manufacturers, then we will parse
- // an entry of the form key=val, where key is a delimited
- // string specifying a manufacturer name, and val is
- // a tag that is used later in the file. the key is
- // delimited by either '"' (quotes) or '%' (percent sign).
- //
- // the tag is used further down the file when models are
- // declared. this allows multiple manufacturers to exist
- // in a single inf file.
- //
- case ParsingManufacturers:
- {
- Manufacturer * manufacturer;
- int curPos = 0;
-
- CString key = s.Tokenize(L"=",curPos);
- CString val = s.Tokenize(L"=",curPos);
-
- try
- {
- manufacturer = new Manufacturer;
- }
- catch (...)
- {
- manufacturer = NULL;
- }
-
- require_action( manufacturer, exit, err = kNoMemoryErr );
-
- //
- // if it's a variable, look it up
- //
- if (key.Find('%') == 0)
- {
- StringMap::iterator it;
- key.Remove('%');
-
- it = strings.find(key);
-
- if (it != strings.end())
- {
- key = it->second;
- }
- }
- else
- {
- key.Remove('"');
- }
-
- val.TrimLeft();
- val.TrimRight();
-
- //
- // why is there no consistency in inf files?
- //
- if (val.GetLength() == 0)
- {
- val = key;
- }
+ require_action( manufacturer, exit, err = kNoMemoryErr );
- //
- // fix the manufacturer name if necessary
- //
- curPos = 0;
- val = val.Tokenize(L",", curPos);
+ manufacturer->name = manufacturerName;
+ manufacturers[ manufacturerName ] = manufacturer;
+ }
- for ( ;; )
- {
- CString decoration;
-
- decoration = val.Tokenize( L",", curPos );
-
- if ( decoration.GetLength() > 0 )
- {
- manufacturer->decorations.push_back( decoration );
- }
- else
- {
- break;
- }
- }
+ memset( &modelContext, 0, sizeof( modelContext ) );
- manufacturer->name = NormalizeManufacturerName( key );
- manufacturer->tag = val;
+ for ( LONG j = 0; j < modelCount; j++ )
+ {
+ CString modelName;
+ Model * model;
- manufacturers[val] = manufacturer;
+ if ( j == 0 )
+ {
+ ok = SetupFindFirstLine( handle, modelSectionName, NULL, &modelContext );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
}
- break;
-
- case ParsingModels:
+ else
{
- check( iter != manufacturers.end() );
-
- Model * model;
- int curPos = 0;
-
- CString name = s.Tokenize(L"=",curPos);
- CString description = s.Tokenize(L"=",curPos);
-
- if (name.Find('%') == 0)
- {
- StringMap::iterator it;
-
- name.Remove('%');
+ SetupFindNextLine( &modelContext, &modelContext );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+ }
- it = strings.find(name);
+ ok = SetupGetStringField( &modelContext, 0, line, sizeof( line ), NULL );
+ err = translate_errno( ok, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
- if (it != strings.end())
- {
- name = it->second;
- }
- }
- else
- {
- name.Remove('"');
- }
+ modelName = line;
- name.Trim();
- description.Trim();
-
- //
- // If true, see if we've seen this guy before
- //
- if (checkForDuplicateModels == true)
- {
- if ( MatchModel( iter->second, ConvertToModelName( name ) ) != NULL )
- {
- continue;
- }
- }
-
- //
- // Stock Vista printer inf files embed guids in the model
- // declarations for Epson printers. Let's ignore those.
- //
- if ( name.Find( L"{", 0 ) != -1 )
+ if (checkForDuplicateModels == true)
+ {
+ if ( MatchModel( manufacturer, ConvertToModelName( modelName ) ) != NULL )
{
continue;
}
+ }
- try
- {
- model = new Model;
- }
- catch (...)
- {
- model = NULL;
- }
-
- require_action( model, exit, err = kNoMemoryErr );
-
- model->infFileName = filename;
- model->displayName = name;
- model->name = name;
- model->driverInstalled = false;
-
- iter->second->models.push_back(model);
+ //
+ // Stock Vista printer inf files embed guids in the model
+ // declarations for Epson printers. Let's ignore those.
+ //
+ if ( modelName.Find( TEXT( "{" ), 0 ) != -1 )
+ {
+ continue;
}
- break;
- default:
+ try
+ {
+ model = new Model;
+ }
+ catch (...)
{
- // pay no attention if we are in any other state
+ model = NULL;
}
- break;
+
+ require_action( model, exit, err = kNoMemoryErr );
+
+ model->infFileName = filename;
+ model->displayName = modelName;
+ model->name = modelName;
+ model->driverInstalled = false;
+
+ manufacturer->models.push_back(model);
}
}
}
exit:
- file.Close();
+ if ( handle != INVALID_HANDLE_VALUE )
+ {
+ SetupCloseInfFile( handle );
+ handle = NULL;
+ }
- return (err);
+ return err;
}
+
// -------------------------------------------------------
// LoadPrintDriverDefs
//
// and try and match the printer
//
- if ( psheet->GetLastPage() == psheet->GetPage(1) )
+ if ( psheet->GetLastPage() == psheet->GetPage(0) )
{
MatchPrinter( m_manufacturers, printer, service, true );
+
+ if ( ( m_manufacturerSelected != NULL ) && ( m_modelSelected != NULL ) )
+ {
+ GetParent()->PostMessage(PSM_SETCURSEL, 2 );
+ }
}
else
{
break;
}
+ else
+ {
+ CString errorMessage;
+ CString errorCaption;
+
+ errorMessage.LoadString( IDS_BAD_INF_FILE );
+ errorCaption.LoadString( IDS_BAD_INF_FILE_CAPTION );
+
+ MessageBox( errorMessage, errorCaption, MB_OK );
+ }
}
else
{
return;
}
+
+
+void
+CThirdPage::Split( const CString & string, TCHAR ch, CStringList & components )
+{
+ CString temp;
+ int n;
+
+ temp = string;
+
+ while ( ( n = temp.Find( ch ) ) != -1 )
+ {
+ components.AddTail( temp.Left( n ) );
+ temp = temp.Right( temp.GetLength() - ( n + 1 ) );
+ }
+
+ components.AddTail( temp );
+}
Change History (most recent first):
$Log: ThirdPage.h,v $
+Revision 1.10 2009/05/29 20:43:37 herscher
+<rdar://problem/6928136> Printer Wizard doesn't work correctly in Windows 7 64 bit
+
Revision 1.9 2007/04/13 23:42:20 herscher
<rdar://problem/4580061> mDNS: Printers added using Bonjour should be set as the default printer.
afx_msg void OnLvnItemchangedPrinterModel(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnBnClickedDefaultPrinter();
private:
+
+ void
+ Split( const CString & string, TCHAR ch, CStringList & components );
+
CButton m_defaultPrinterCtrl;
+
public:
CStatic m_printerSelectionText;
CStatic * m_printerImage;
Change History (most recent first):
$Log: UtilTypes.h,v $
+Revision 1.18 2009/05/29 20:43:37 herscher
+<rdar://problem/6928136> Printer Wizard doesn't work correctly in Windows 7 64 bit
+
+Revision 1.17 2009/05/27 04:59:57 herscher
+<rdar://problem/4517393> COMPATIBILITY WITH HP CLJ4700
+<rdar://problem/6142138> Compatibility with Samsung print driver files
+
Revision 1.16 2007/04/20 22:58:10 herscher
<rdar://problem/4826126> mDNS: Printer Wizard doesn't offer generic HP printers or generic PS support on Vista RC2
typedef std::list<Printer*> Printers;
typedef std::list<Service*> Services;
typedef std::list<Model*> Models;
- typedef std::list<CString> Decorations;
struct Printer
{
struct Manufacturer
{
CString name;
- CString tag;
Models models;
- Decorations decorations;
Model*
find( const CString & name );
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-<assemblyIdentity
- version="1.0.0.0"
- processorArchitecture="X86"
- name="Microsoft.Windows.Wiz97_3"
- type="win32"
-/>
-<description>Your app description here</description>
-<dependency>
- <dependentAssembly>
- <assemblyIdentity
- type="win32"
- name="Microsoft.Windows.Common-Controls"
- version="6.0.0.0"
- processorArchitecture="X86"
- publicKeyToken="6595b64144ccf1df"
- language="*"
- />
- </dependentAssembly>
-</dependency>
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.PrinterSetupWizard" type="win32"/>
+ <description>Printer Setup Wizard</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
</assembly>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="amd64" name="Apple.Bonjour.PrinterSetupWizard" type="win32"/>
+ <description>Printer Setup Wizard</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
+</assembly>
// Microsoft Visual C++ generated include file.\r
// Used by PrinterSetupWizard.rc\r
//\r
-#define IDR_MANIFEST 1\r
#define IDM_ABOUTBOX 0x0010\r
#define IDD_ABOUTBOX 100\r
#define IDS_ABOUTBOX 101\r
#define IDI_PRINTER 141\r
#define IDS_REINSTALL 142\r
#define IDS_REINSTALL_CAPTION 143\r
+#define IDC_INFO 144\r
+#define IDS_PRINTER_UNAVAILABLE 145\r
+#define IDS_BAD_INF_FILE 150\r
+#define IDS_BAD_INF_FILE_CAPTION 151\r
#define IDC_BUTTON1 1000\r
#define IDC_LIST1 1000\r
#define IDC_BROWSE_LIST 1000\r
// Microsoft Visual C++ generated include file.\r
// Used by PrinterSetupWizardLocRes.rc\r
//\r
-#define IDR_MANIFEST 1\r
#define IDM_ABOUTBOX 0x0010\r
#define IDD_ABOUTBOX 100\r
#define IDS_ABOUTBOX 101\r
#define IDS_REINSTALL_CAPTION 143\r
#define IDC_INFO 144\r
#define IDS_PRINTER_UNAVAILABLE 145\r
+#define IDS_BAD_INF_FILE 150\r
+#define IDS_BAD_INF_FILE_CAPTION 151\r
#define IDC_BUTTON1 1000\r
#define IDC_LIST1 1000\r
#define IDC_BROWSE_LIST 1000\r
// Microsoft Visual C++ generated include file.\r
// Used by PrinterSetupWizard.rc\r
//\r
-#define IDR_MANIFEST 1\r
#define IDM_ABOUTBOX 0x0010\r
#define IDD_ABOUTBOX 100\r
#define IDS_ABOUTBOX 101\r
#define IDI_PRINTER 141\r
#define IDS_REINSTALL 142\r
#define IDS_REINSTALL_CAPTION 143\r
+#define IDC_INFO 144\r
+#define IDS_PRINTER_UNAVAILABLE 145\r
+#define IDS_BAD_INF_FILE 150\r
+#define IDS_BAD_INF_FILE_CAPTION 151\r
#define IDC_BUTTON1 1000\r
#define IDC_LIST1 1000\r
#define IDC_BROWSE_LIST 1000\r
-<VisualStudioProject>\r
- <CSHARP\r
- ProjectType = "Local"\r
- ProductVersion = "7.0.9466"\r
- SchemaVersion = "1.0"\r
- ProjectGuid = "{726DED99-34D0-45F3-9F4D-C7068DF4BCDA}"\r
- >\r
- <Build>\r
- <Settings\r
- ApplicationIcon = "App.ico"\r
- AssemblyKeyContainerName = ""\r
- AssemblyName = "SimpleChat.NET"\r
- AssemblyOriginatorKeyFile = ""\r
- DefaultClientScript = "JScript"\r
- DefaultHTMLPageLayout = "Grid"\r
- DefaultTargetSchema = "IE50"\r
- DelaySign = "false"\r
- OutputType = "WinExe"\r
- RootNamespace = "SimpleChat.NET"\r
- StartupObject = ""\r
- >\r
- <Config\r
- Name = "Debug"\r
- AllowUnsafeBlocks = "false"\r
- BaseAddress = "285212672"\r
- CheckForOverflowUnderflow = "false"\r
- ConfigurationOverrideFile = ""\r
- DefineConstants = "DEBUG;TRACE"\r
- DocumentationFile = ""\r
- DebugSymbols = "true"\r
- FileAlignment = "4096"\r
- IncrementalBuild = "true"\r
- Optimize = "false"\r
- OutputPath = "bin\Debug\"\r
- RegisterForComInterop = "false"\r
- RemoveIntegerChecks = "false"\r
- TreatWarningsAsErrors = "false"\r
- WarningLevel = "4"\r
- />\r
- <Config\r
- Name = "Release"\r
- AllowUnsafeBlocks = "false"\r
- BaseAddress = "285212672"\r
- CheckForOverflowUnderflow = "false"\r
- ConfigurationOverrideFile = ""\r
- DefineConstants = "TRACE"\r
- DocumentationFile = ""\r
- DebugSymbols = "false"\r
- FileAlignment = "4096"\r
- IncrementalBuild = "false"\r
- Optimize = "true"\r
- OutputPath = "bin\Release\"\r
- RegisterForComInterop = "false"\r
- RemoveIntegerChecks = "false"\r
- TreatWarningsAsErrors = "false"\r
- WarningLevel = "4"\r
- />\r
- </Settings>\r
- <References>\r
- <Reference\r
- Name = "System"\r
- AssemblyName = "System"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"\r
- />\r
- <Reference\r
- Name = "System.Data"\r
- AssemblyName = "System.Data"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"\r
- />\r
- <Reference\r
- Name = "System.Drawing"\r
- AssemblyName = "System.Drawing"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"\r
- />\r
- <Reference\r
- Name = "System.Windows.Forms"\r
- AssemblyName = "System.Windows.Forms"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"\r
- />\r
- <Reference\r
- Name = "System.XML"\r
- AssemblyName = "System.XML"\r
- HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"\r
- />\r
- <Reference\r
- Name = "dnssd.NET"\r
- AssemblyName = "dnssd.NET"\r
- HintPath = "..\..\mDNSWindows\DLL.NET\Release\dnssd.NET.dll"\r
- />\r
- </References>\r
- </Build>\r
- <Files>\r
- <Include>\r
- <File\r
- RelPath = "App.ico"\r
- BuildAction = "Content"\r
- />\r
- <File\r
- RelPath = "AssemblyInfo.cs"\r
- BuildAction = "Compile"\r
- />\r
- <File\r
- RelPath = "SimpleChat.cs"\r
- SubType = "Form"\r
- BuildAction = "Compile"\r
- />\r
- <File\r
- RelPath = "SimpleChat.resx"\r
- DependentUpon = "SimpleChat.cs"\r
- BuildAction = "EmbeddedResource"\r
- />\r
- </Include>\r
- </Files>\r
- </CSHARP>\r
-</VisualStudioProject>\r
-\r
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <PropertyGroup>\r
+ <ProjectType>Local</ProjectType>\r
+ <ProductVersion>8.0.50727</ProductVersion>\r
+ <SchemaVersion>2.0</SchemaVersion>\r
+ <ProjectGuid>{726DED99-34D0-45F3-9F4D-C7068DF4BCDA}</ProjectGuid>\r
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+ <ApplicationIcon>App.ico</ApplicationIcon>\r
+ <AssemblyKeyContainerName>\r
+ </AssemblyKeyContainerName>\r
+ <AssemblyName>SimpleChat.NET</AssemblyName>\r
+ <AssemblyOriginatorKeyFile>\r
+ </AssemblyOriginatorKeyFile>\r
+ <DefaultClientScript>JScript</DefaultClientScript>\r
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>\r
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>\r
+ <DelaySign>false</DelaySign>\r
+ <OutputType>WinExe</OutputType>\r
+ <RootNamespace>SimpleChat.NET</RootNamespace>\r
+ <StartupObject>\r
+ </StartupObject>\r
+ <FileUpgradeFlags>\r
+ </FileUpgradeFlags>\r
+ <UpgradeBackupLocation>\r
+ </UpgradeBackupLocation>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+ <OutputPath>bin\Debug\</OutputPath>\r
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\r
+ <BaseAddress>285212672</BaseAddress>\r
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>\r
+ <ConfigurationOverrideFile>\r
+ </ConfigurationOverrideFile>\r
+ <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+ <DocumentationFile>\r
+ </DocumentationFile>\r
+ <DebugSymbols>true</DebugSymbols>\r
+ <FileAlignment>4096</FileAlignment>\r
+ <Optimize>false</Optimize>\r
+ <RegisterForComInterop>false</RegisterForComInterop>\r
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>\r
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\r
+ <WarningLevel>4</WarningLevel>\r
+ <DebugType>full</DebugType>\r
+ <ErrorReport>prompt</ErrorReport>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+ <OutputPath>bin\Release\</OutputPath>\r
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\r
+ <BaseAddress>285212672</BaseAddress>\r
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>\r
+ <ConfigurationOverrideFile>\r
+ </ConfigurationOverrideFile>\r
+ <DefineConstants>TRACE</DefineConstants>\r
+ <DocumentationFile>\r
+ </DocumentationFile>\r
+ <DebugSymbols>false</DebugSymbols>\r
+ <FileAlignment>4096</FileAlignment>\r
+ <Optimize>true</Optimize>\r
+ <RegisterForComInterop>false</RegisterForComInterop>\r
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>\r
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\r
+ <WarningLevel>4</WarningLevel>\r
+ <DebugType>none</DebugType>\r
+ <ErrorReport>prompt</ErrorReport>\r
+ </PropertyGroup>\r
+ <ItemGroup>\r
+ <Reference Include="System">\r
+ <Name>System</Name>\r
+ </Reference>\r
+ <Reference Include="System.Data">\r
+ <Name>System.Data</Name>\r
+ </Reference>\r
+ <Reference Include="System.Drawing">\r
+ <Name>System.Drawing</Name>\r
+ </Reference>\r
+ <Reference Include="System.Windows.Forms">\r
+ <Name>System.Windows.Forms</Name>\r
+ </Reference>\r
+ <Reference Include="System.XML">\r
+ <Name>System.XML</Name>\r
+ </Reference>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Content Include="App.ico" />\r
+ <Compile Include="AssemblyInfo.cs" />\r
+ <Compile Include="SimpleChat.cs">\r
+ <SubType>Form</SubType>\r
+ </Compile>\r
+ <EmbeddedResource Include="SimpleChat.resx">\r
+ <DependentUpon>SimpleChat.cs</DependentUpon>\r
+ <SubType>Designer</SubType>\r
+ </EmbeddedResource>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <COMReference Include="Bonjour">\r
+ <Guid>{18FBED6D-F2B7-4EC8-A4A4-46282E635308}</Guid>\r
+ <VersionMajor>1</VersionMajor>\r
+ <VersionMinor>0</VersionMinor>\r
+ <Lcid>0</Lcid>\r
+ <WrapperTool>tlbimp</WrapperTool>\r
+ <Isolated>False</Isolated>\r
+ </COMReference>\r
+ </ItemGroup>\r
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />\r
+ <PropertyGroup>\r
+ <PreBuildEvent>\r
+ </PreBuildEvent>\r
+ <PostBuildEvent>\r
+ </PostBuildEvent>\r
+ </PropertyGroup>\r
+</Project>
\ No newline at end of file
Change History (most recent first):
$Log: SimpleChat.cs,v $
+Revision 1.7 2009/06/04 20:21:19 herscher
+<rdar://problem/3948252> Update code to work with DNSSD COM component
+
Revision 1.6 2006/08/14 23:24:21 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
using System.Net.Sockets;
using System.Data;
using System.Text;
-using Apple.DNSSD;
+using Bonjour;
namespace SimpleChat.NET
{
/// </summary>
///
- //
- // PeerData
- //
- // Holds onto the information associated with a peer on the network
- //
- public class PeerData
- {
- public int InterfaceIndex;
- public String Name;
- public String Type;
- public String Domain;
- public IPAddress Address;
- public int Port;
-
- public override String
- ToString()
- {
- return Name;
- }
-
- public override bool
- Equals(object other)
- {
- bool result = false;
-
- if (other != null)
- {
- if ((object) this == other)
- {
- result = true;
- }
- else if (other is PeerData)
- {
- PeerData otherPeerData = (PeerData) other;
-
- result = (this.Name == otherPeerData.Name);
- }
- }
-
- return result;
- }
-
- public override int
- GetHashCode()
- {
- return Name.GetHashCode();
- }
- };
-
- //
- // ResolveData
- //
- // Holds onto the information associated with the resolution
- // of a DNSService
- //
- public class ResolveData
- {
- public int InterfaceIndex;
- public String FullName;
- public String HostName;
- public int Port;
- public Byte[] TxtRecord;
-
- public override String
- ToString()
- {
- return FullName;
- }
- };
-
-
- //
- // SocketStateObject
- //
- // Holds onto the data associated with an asynchronous
- // socket operation
- //
- class SocketStateObject
+ public class SimpleChat : System.Windows.Forms.Form
{
- public const int BUFFER_SIZE = 1024;
- private Socket m_socket;
- public byte[] m_buffer;
- public bool m_complete;
- public StringBuilder m_sb = new StringBuilder();
-
- public SocketStateObject(Socket socket)
- {
- m_buffer = new byte[BUFFER_SIZE];
- m_complete = false;
- m_socket = socket;
- }
-
- public Socket
- WorkSocket
- {
- get
- {
- return m_socket;
- }
- }
- }
- public class Form1 : System.Windows.Forms.Form
- {
- private System.Windows.Forms.ComboBox comboBox1;
- private System.Windows.Forms.TextBox textBox2;
- private System.Windows.Forms.Button button1;
- private System.Windows.Forms.Label label1;
- private ServiceRef registrar = null;
- private ServiceRef browser = null;
- private ServiceRef resolver = null;
- private String myName;
+ private System.Windows.Forms.ComboBox comboBox1;
+ private System.Windows.Forms.TextBox textBox2;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Label label1;\r
+ private Bonjour.DNSSDEventManager m_eventManager = null;\r
+ private Bonjour.DNSSDService m_service = null;\r
+ private Bonjour.DNSSDService m_registrar = null;\r
+ private Bonjour.DNSSDService m_browser = null;\r
+ private Bonjour.DNSSDService m_resolver = null;
+ private String m_name;\r
+ private Socket m_socket = null;\r
+ private const int BUFFER_SIZE = 1024;\r
+ public byte[] m_buffer = new byte[BUFFER_SIZE];\r
+ public bool m_complete = false;\r
+ public StringBuilder m_sb = new StringBuilder();\r
+ delegate void ReadMessageCallback(String data);\r
+ ReadMessageCallback m_readMessageCallback;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
-
- //
- // These all of our callbacks. These are invoked in the context
- // of the main (GUI) thread. The DNSService callbacks Invoke()
- // them
- delegate void RegisterServiceCallback(String name);
- delegate void AddPeerCallback(PeerData data);
- delegate void RemovePeerCallback(PeerData data);
- delegate void ResolveServiceCallback(ResolveData data);
- delegate void ResolveAddressCallback(System.Net.IPAddress address);
- delegate void ReadMessageCallback(String data);
-
- RegisterServiceCallback registerServiceCallback;
- AddPeerCallback addPeerCallback;
- RemovePeerCallback removePeerCallback;
- ResolveServiceCallback resolveServiceCallback;
- ResolveAddressCallback resolveAddressCallback;
- ReadMessageCallback readMessageCallback;
private System.Windows.Forms.RichTextBox richTextBox1;
+ // ServiceRegistered
//
- // The socket that we will be reading data from
- //
- Socket socket = null;
-
- //
- // OnRegisterService
- //
- // The name that we are passed might be different than the
- // name we called Register with. So we hold onto this name
- // rather than the name we Register with.
- //
- // This is called (indirectly) from OnRegisterReply().
- //
- private void
- OnRegisterService
- (
- String name
- )
- {
- myName = name;
- }
-
- //
- // OnAddPeer
- //
- // Called when DNSServices detects a new P2P Chat peer has
- // joined.
- //
- // This is called (indirectly) from OnBrowseReply()
- //
- private void
- OnAddPeer
- (
- PeerData peer
- )
- {
- comboBox1.Items.Add(peer);
-
- if (comboBox1.Items.Count == 1)
- {
- comboBox1.SelectedIndex = 0;
- }
- }
-
- //
- // OnRemovePeer
- //
- // Called when DNSServices detects a P2P peer has left
- // the network
- //
- // This is called (indirectly) from OnBrowseReply()
- //
- private void
- OnRemovePeer
- (
- PeerData peer
- )
- {
- comboBox1.Items.Remove(peer);
- }
-
- //
- // OnResolveService
- //
- // Called when DNSServices has resolved a service.
- //
- // This is called (indirectly) from OnResolveService()
- //
- private void
- OnResolveService
- (
- ResolveData data
- )
- {
- resolver.Dispose();
-
- PeerData peer = (PeerData) comboBox1.SelectedItem;
-
- peer.Port = data.Port;
-
- try
- {
- resolver = DNSService.QueryRecord(0, 0, data.HostName, /* ns_t_a */ 1, /* ns_t_c */ 1, new DNSService.QueryRecordReply(OnQueryRecordReply));
- }
- catch
- {
- MessageBox.Show("QueryRecord Failed", "Error");
- Application.Exit();
- }
- }
-
- //
- // OnResolveAddress
- //
- // Called when DNSServices has finished a query operation
- //
- // This is called (indirectly) from OnQueryRecordReply()
- //
- private void
- OnResolveAddress
- (
- System.Net.IPAddress address
- )
- {
- resolver.Dispose();
-
- PeerData peer = (PeerData) comboBox1.SelectedItem;
-
- peer.Address = address;
- }
-
- //
- // OnReadMessage
- //
- // Called when there is data to be read on a socket
- //
- // This is called (indirectly) from OnReadSocket()
- //
- private void
- OnReadMessage
- (
- String msg
- )
- {
- int rgb = 0;
-
- for (int i = 0; i < msg.Length && msg[i] != ':'; i++)
- {
- rgb = rgb ^ ((int) msg[i] << (i % 3 + 2) * 8);
- }
-
- Color color = Color.FromArgb(rgb & 0x007F7FFF);
-
- richTextBox1.SelectionColor = color;
-
- richTextBox1.AppendText(msg + "\n");
- }
-
- //
- // OnRegisterReply
- //
- // Called by DNSServices core as a result of DNSService.Register()
+ // Called by DNSServices core as a result of Register()
// call
- //
- // This is called from a worker thread by DNSService core.
- //
- private void
- OnRegisterReply
- (
- ServiceRef sdRef,
- ServiceFlags flags,
- ErrorCode errorCode,
- String name,
- String regtype,
- String domain)
- {
- if (errorCode == ErrorCode.NoError)
- {
- Invoke(registerServiceCallback, new Object[]{name});
- }
- else
- {
- MessageBox.Show("OnRegisterReply returned an error code " + errorCode, "Error");
- }
- }
-
-
- //
- // OnBrowseReply
- //
- // Called by DNSServices core as a result of DNSService.Browse()
- // call
- //
- // This is called from a worker thread by DNSService core.
- //
- private void
- OnBrowseReply
- (
- ServiceRef sdRef,
- ServiceFlags flags,
- int interfaceIndex,
- ErrorCode errorCode,
- String name,
- String type,
- String domain)
- {
- if (errorCode == ErrorCode.NoError)
- {
- PeerData peer = new PeerData();
-
- peer.InterfaceIndex = interfaceIndex;
- peer.Name = name;
- peer.Type = type;
- peer.Domain = domain;
- peer.Address = null;
-
- if ((flags & ServiceFlags.Add) != 0)
- {
- Invoke(addPeerCallback, new Object[]{peer});
- }
- else if ((flags == 0) || ((flags & ServiceFlags.MoreComing) != 0))
- {
- Invoke(removePeerCallback, new Object[]{peer});
- }
- }
- else
- {
- MessageBox.Show("OnBrowseReply returned an error code " + errorCode, "Error");
- }
- }
-
- //
- // OnResolveReply
+ //\r
+\r
+ public void\r
+ ServiceRegistered\r
+ (\r
+ DNSSDService service,\r
+ DNSSDFlags flags,\r
+ String name,\r
+ String regType,\r
+ String domain\r
+ )\r
+ {\r
+ m_name = name;\r
+\r
+ try\r
+ {\r
+ m_browser = m_service.Browse(0, 0, "_p2pchat._udp", null, m_eventManager);\r
+ }\r
+ catch\r
+ {\r
+ MessageBox.Show("Browse Failed", "Error");\r
+ Application.Exit();\r
+ }\r
+ }
+
+ //
+ // ServiceFound
+ //
+ // Called by DNSServices core as a result of a Browse call
+ //
+
+ public void
+ ServiceFound
+ (
+ DNSSDService sref,
+ DNSSDFlags flags,
+ uint ifIndex,
+ String serviceName,
+ String regType,
+ String domain
+ )
+ {\r
+ if (serviceName != m_name)\r
+ {\r
+ PeerData peer = new PeerData();\r
+\r
+ peer.InterfaceIndex = ifIndex;\r
+ peer.Name = serviceName;\r
+ peer.Type = regType;\r
+ peer.Domain = domain;\r
+ peer.Address = null;\r
+\r
+ comboBox1.Items.Add(peer);\r
+\r
+ if (comboBox1.Items.Count == 1)\r
+ {\r
+ comboBox1.SelectedIndex = 0;\r
+ }\r
+ }
+ }\r
+\r
+ //\r
+ // ServiceLost\r
+ //\r
+ // Called by DNSServices core as a result of a Browse call\r
+ //\r
+\r
+ public void\r
+ ServiceLost\r
+ (\r
+ DNSSDService sref,\r
+ DNSSDFlags flags,\r
+ uint ifIndex,\r
+ String serviceName,\r
+ String regType,\r
+ String domain\r
+ )\r
+ {\r
+ PeerData peer = new PeerData();\r
+\r
+ peer.InterfaceIndex = ifIndex;\r
+ peer.Name = serviceName;\r
+ peer.Type = regType;\r
+ peer.Domain = domain;\r
+ peer.Address = null;\r
+\r
+ comboBox1.Items.Remove(peer);\r
+ }
+
+ //
+ // ServiceResolved
//
// Called by DNSServices core as a result of DNSService.Resolve()
// call
//
- // This is called from a worker thread by DNSService core.
- //
- private void
- OnResolveReply
- (
- ServiceRef sdRef,
- ServiceFlags flags,
- int interfaceIndex,
- ErrorCode errorCode,
- String fullName,
- String hostName,
- int port,
- Byte[] txtRecord
- )
- {
- if (errorCode == ErrorCode.NoError)
- {
- ResolveData data = new ResolveData();
-
- data.InterfaceIndex = interfaceIndex;
- data.FullName = fullName;
- data.HostName = hostName;
- data.Port = port;
- data.TxtRecord = txtRecord;
-
- Invoke(resolveServiceCallback, new Object[]{data});
- }
- else
- {
- MessageBox.Show("OnResolveReply returned an error code: " + errorCode, "Error");
- }
+\r
+ public void\r
+ ServiceResolved\r
+ (\r
+ DNSSDService sref,\r
+ DNSSDFlags flags,\r
+ uint ifIndex,\r
+ String fullName,\r
+ String hostName,\r
+ ushort port,\r
+ TXTRecord txtRecord\r
+ )
+ {\r
+ m_resolver.Stop();\r
+ m_resolver = null;\r
+\r
+ PeerData peer = (PeerData)comboBox1.SelectedItem;\r
+\r
+ peer.Port = port;\r
+\r
+ try\r
+ {\r
+ m_resolver = m_service.QueryRecord(0, ifIndex, hostName, DNSSDRRType.kDNSSDType_A, DNSSDRRClass.kDNSSDClass_IN, m_eventManager );\r
+ }\r
+ catch\r
+ {\r
+ MessageBox.Show("QueryRecord Failed", "Error");\r
+ Application.Exit();\r
+ }
}
//
- // OnQueryRecordReply
+ // QueryAnswered
//
// Called by DNSServices core as a result of DNSService.QueryRecord()
// call
//
- // This is called from a worker thread by DNSService core.
- //
- private void
- OnQueryRecordReply
+
+ public void
+ QueryAnswered
(
- ServiceRef sdRef,
- ServiceFlags flags,
- int interfaceIndex,
- ErrorCode errorCode,
- String fullName,
- int rrtype,
- int rrclass,
- Byte[] rdata,
- int ttl
- )
- {
- if (errorCode == ErrorCode.NoError)
- {
- uint bits = BitConverter.ToUInt32(rdata, 0);
- System.Net.IPAddress data = new System.Net.IPAddress(bits);
-
- Invoke(resolveAddressCallback, new Object[]{data});
- }
- else
- {
- MessageBox.Show("OnQueryRecordReply returned an error code: " + errorCode, "Error");
- }
- }
+ DNSSDService service,
+ DNSSDFlags flags,
+ uint ifIndex,
+ String fullName,
+ DNSSDRRType rrtype,
+ DNSSDRRClass rrclass,
+ Object rdata,
+ uint ttl
+ )
+ {\r
+ m_resolver.Stop();\r
+ m_resolver = null;\r
+\r
+ PeerData peer = (PeerData) comboBox1.SelectedItem;\r
+
+ uint bits = BitConverter.ToUInt32( (Byte[])rdata, 0);
+ System.Net.IPAddress address = new System.Net.IPAddress(bits);
+
+ peer.Address = address;
+ }\r
+\r
+ public void\r
+ OperationFailed\r
+ (\r
+ DNSSDService service,\r
+ DNSSDError error\r
+ )\r
+ {\r
+ MessageBox.Show("Operation returned an error code " + error, "Error");\r
+ }\r
+\r
+ //\r
+ // OnReadMessage\r
+ //\r
+ // Called when there is data to be read on a socket\r
+ //\r
+ // This is called (indirectly) from OnReadSocket()\r
+ //\r
+ private void\r
+ OnReadMessage\r
+ (\r
+ String msg\r
+ )\r
+ {\r
+ int rgb = 0;\r
+\r
+ for (int i = 0; i < msg.Length && msg[i] != ':'; i++)\r
+ {\r
+ rgb = rgb ^ ((int)msg[i] << (i % 3 + 2) * 8);\r
+ }\r
+\r
+ Color color = Color.FromArgb(rgb & 0x007F7FFF);\r
+ richTextBox1.SelectionColor = color;\r
+ richTextBox1.AppendText(msg + Environment.NewLine);\r
+ }
//
// OnReadSocket
IAsyncResult ar
)
{
- SocketStateObject so = (SocketStateObject) ar.AsyncState;
- Socket s = so.WorkSocket;
-
try
{
- if (s == null)
- {
- return;
- }
-
- int read = s.EndReceive(ar);
+ int read = m_socket.EndReceive(ar);
if (read > 0)
{
- String msg = Encoding.UTF8.GetString(so.m_buffer, 0, read);
-
- Invoke(readMessageCallback, new Object[]{msg});
+ String msg = Encoding.UTF8.GetString(m_buffer, 0, read);
+ Invoke(m_readMessageCallback, new Object[]{msg});
}
- s.BeginReceive(so.m_buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(OnReadSocket), so);
+ m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReadSocket), this);
}
catch
{
}
- public Form1()
+ public SimpleChat()
{
//
// Required for Windows Form Designer support
//
- InitializeComponent();
-
- registerServiceCallback = new RegisterServiceCallback(OnRegisterService);
- addPeerCallback = new AddPeerCallback(OnAddPeer);
- removePeerCallback = new RemovePeerCallback(OnRemovePeer);
- resolveServiceCallback = new ResolveServiceCallback(OnResolveService);
- resolveAddressCallback = new ResolveAddressCallback(OnResolveAddress);
- readMessageCallback = new ReadMessageCallback(OnReadMessage);
+ InitializeComponent();\r
+\r
+ try\r
+ {\r
+ m_service = new DNSSDService();\r
+ }\r
+ catch\r
+ {\r
+ MessageBox.Show("Bonjour Service is not available", "Error");\r
+ Application.Exit();\r
+ }\r
+\r
+ m_eventManager = new DNSSDEventManager();\r
+ m_eventManager.ServiceRegistered += new _IDNSSDEvents_ServiceRegisteredEventHandler(this.ServiceRegistered);\r
+ m_eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);\r
+ m_eventManager.ServiceLost += new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);\r
+ m_eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);\r
+ m_eventManager.QueryRecordAnswered += new _IDNSSDEvents_QueryRecordAnsweredEventHandler(this.QueryAnswered);\r
+ m_eventManager.OperationFailed += new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
+
+ m_readMessageCallback = new ReadMessageCallback(OnReadMessage);
this.Load += new System.EventHandler(this.Form1_Load);
components.Dispose();
}
- if (registrar != null)
+ if (m_registrar != null)
{
- registrar.Dispose();
+ m_registrar.Stop();
}
- if (browser != null)
+ if (m_browser != null)
{
- browser.Dispose();
- }
+ m_browser.Stop();
+ }\r
+\r
+ if (m_resolver != null)\r
+ {\r
+ m_resolver.Stop();\r
+ }\r
+\r
+ m_eventManager.ServiceFound -= new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);\r
+ m_eventManager.ServiceLost -= new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);\r
+ m_eventManager.ServiceResolved -= new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);\r
+ m_eventManager.QueryRecordAnswered -= new _IDNSSDEvents_QueryRecordAnsweredEventHandler(this.QueryAnswered);\r
+ m_eventManager.OperationFailed -= new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
}
base.Dispose( disposing );
}
//
// create the socket and bind to INADDR_ANY
//
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.Bind(localEP);
- localEP = (IPEndPoint) socket.LocalEndPoint;
+ m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ m_socket.Bind(localEP);
+ localEP = (IPEndPoint) m_socket.LocalEndPoint;
//
// start asynchronous read
//
- SocketStateObject so = new SocketStateObject(socket);
- socket.BeginReceive(so.m_buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(this.OnReadSocket), so);
+ m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(this.OnReadSocket), this);
try
{
//
// start the register and browse operations
//
- registrar = DNSService.Register(0, 0, System.Environment.UserName, "_p2pchat._udp", null, null, localEP.Port, null, new DNSService.RegisterReply(OnRegisterReply));
- browser = DNSService.Browse(0, 0, "_p2pchat._udp", null, new DNSService.BrowseReply(OnBrowseReply));
+ m_registrar = m_service.Register( 0, 0, System.Environment.UserName, "_p2pchat._udp", null, null, ( ushort ) localEP.Port, null, m_eventManager );
}
catch
{
- MessageBox.Show("DNSServices Not Available", "Error");
+ MessageBox.Show("Bonjour service is not available", "Error");
Application.Exit();
}
}
[STAThread]
static void Main()
{
- Application.Run(new Form1());
+ Application.Run(new SimpleChat());
}
//
{
PeerData peer = (PeerData) comboBox1.SelectedItem;
- String message = myName + ": " + textBox2.Text;
+ String message = m_name + ": " + textBox2.Text;
Byte[] bytes = Encoding.UTF8.GetBytes(message);
-
- UdpClient udpSocket = new UdpClient(peer.Address.ToString(), peer.Port);
- udpSocket.Send(bytes, bytes.Length);
+ IPEndPoint endPoint = new IPEndPoint( peer.Address, peer.Port );\r
+\r
+ m_socket.SendTo(bytes, endPoint);
richTextBox1.SelectionColor = Color.Black;
private void textBox2_TextChanged(object sender, System.EventArgs e)
{
PeerData peer = (PeerData) comboBox1.SelectedItem;
-
- if ((peer.Address != null) && (textBox2.Text.Length > 0))
- {
- button1.Enabled = true;
- }
- else
- {
- button1.Enabled = false;
- }
+ button1.Enabled = ((peer.Address != null) && (textBox2.Text.Length > 0));
}
//
try
{
- resolver = DNSService.Resolve(0, 0, peer.Name, peer.Type, peer.Domain, new DNSService.ResolveReply(OnResolveReply));
+ m_resolver = m_service.Resolve(0, peer.InterfaceIndex, peer.Name, peer.Type, peer.Domain, m_eventManager);
}
catch
{
Application.Exit();
}
}
- }
+ }\r
+\r
+ //\r
+ // PeerData\r
+ //\r
+ // Holds onto the information associated with a peer on the network\r
+ //\r
+ public class PeerData\r
+ {\r
+ public uint InterfaceIndex;\r
+ public String Name;\r
+ public String Type;\r
+ public String Domain;\r
+ public IPAddress Address;\r
+ public int Port;\r
+\r
+ public override String\r
+ ToString()\r
+ {\r
+ return Name;\r
+ }\r
+\r
+ public override bool\r
+ Equals(object other)\r
+ {\r
+ bool result = false;\r
+\r
+ if (other != null)\r
+ {\r
+ if ((object)this == other)\r
+ {\r
+ result = true;\r
+ }\r
+ else if (other is PeerData)\r
+ {\r
+ PeerData otherPeerData = (PeerData)other;\r
+\r
+ result = (this.Name == otherPeerData.Name);\r
+ }\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+ public override int\r
+ GetHashCode()\r
+ {\r
+ return Name.GetHashCode();\r
+ }\r
+ };
}
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
</resheader>\r
<data name="$this.Name">\r
- <value>Form1</value>\r
+ <value>SimpleChat.NET</value>\r
</data>\r
</root>
\ No newline at end of file
--- /dev/null
+'------------------------------------------------------------------------------\r
+' <auto-generated>\r
+' This code was generated by a tool.\r
+' Runtime Version:2.0.50727.4918\r
+'\r
+' Changes to this file may cause incorrect behavior and will be lost if\r
+' the code is regenerated.\r
+' </auto-generated>\r
+'------------------------------------------------------------------------------\r
+\r
+Option Strict On\r
+Option Explicit On\r
+\r
+\r
+Namespace My\r
+ \r
+ 'NOTE: This file is auto-generated; do not modify it directly. To make changes,\r
+ ' or if you encounter build errors in this file, go to the Project Designer\r
+ ' (go to Project Properties or double-click the My Project node in\r
+ ' Solution Explorer), and make changes on the Application tab.\r
+ '\r
+ Partial Friend Class MyApplication\r
+ \r
+ <Global.System.Diagnostics.DebuggerStepThroughAttribute()> _\r
+ Public Sub New()\r
+ MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)\r
+ Me.IsSingleInstance = false\r
+ Me.EnableVisualStyles = true\r
+ Me.SaveMySettingsOnExit = true\r
+ Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses\r
+ End Sub\r
+ \r
+ <Global.System.Diagnostics.DebuggerStepThroughAttribute()> _\r
+ Protected Overrides Sub OnCreateMainForm()\r
+ Me.MainForm = Global.SimpleChat.VB.SimpleChat\r
+ End Sub\r
+ End Class\r
+End Namespace\r
--- /dev/null
+<?xml version="1.0" encoding="utf-16"?>\r
+<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">\r
+ <MySubMain>true</MySubMain>\r
+ <MainForm>SimpleChat</MainForm>\r
+ <SingleInstance>false</SingleInstance>\r
+ <ShutdownMode>0</ShutdownMode>\r
+ <EnableVisualStyles>true</EnableVisualStyles>\r
+ <AuthenticationMode>0</AuthenticationMode>\r
+ <SaveMySettingsOnExit>true</SaveMySettingsOnExit>\r
+</MyApplicationData>
\ No newline at end of file
--- /dev/null
+Imports System\r
+Imports System.Reflection\r
+Imports System.Runtime.InteropServices\r
+\r
+' General Information about an assembly is controlled through the following \r
+' set of attributes. Change these attribute values to modify the information\r
+' associated with an assembly.\r
+\r
+' Review the values of the assembly attributes\r
+\r
+<Assembly: AssemblyTitle("SimpleChat.VB")> \r
+<Assembly: AssemblyDescription("")> \r
+<Assembly: AssemblyCompany("Microsoft")> \r
+<Assembly: AssemblyProduct("SimpleChat.VB")> \r
+<Assembly: AssemblyCopyright("Copyright © Microsoft 2009")> \r
+<Assembly: AssemblyTrademark("")> \r
+\r
+<Assembly: ComVisible(False)>\r
+\r
+'The following GUID is for the ID of the typelib if this project is exposed to COM\r
+<Assembly: Guid("a07d7322-054b-4fda-a670-d75f589804c8")> \r
+\r
+' Version information for an assembly consists of the following four values:\r
+'\r
+' Major Version\r
+' Minor Version \r
+' Build Number\r
+' Revision\r
+'\r
+' You can specify all the values or you can default the Build and Revision Numbers \r
+' by using the '*' as shown below:\r
+' <Assembly: AssemblyVersion("1.0.*")> \r
+\r
+<Assembly: AssemblyVersion("1.0.0.0")> \r
+<Assembly: AssemblyFileVersion("1.0.0.0")> \r
--- /dev/null
+'------------------------------------------------------------------------------\r
+' <auto-generated>\r
+' This code was generated by a tool.\r
+' Runtime Version:2.0.50727.4918\r
+'\r
+' Changes to this file may cause incorrect behavior and will be lost if\r
+' the code is regenerated.\r
+' </auto-generated>\r
+'------------------------------------------------------------------------------\r
+\r
+Option Strict On\r
+Option Explicit On\r
+\r
+\r
+Namespace My.Resources\r
+ \r
+ 'This class was auto-generated by the StronglyTypedResourceBuilder\r
+ 'class via a tool like ResGen or Visual Studio.\r
+ 'To add or remove a member, edit your .ResX file then rerun ResGen\r
+ 'with the /str option, or rebuild your VS project.\r
+ '<summary>\r
+ ' A strongly-typed resource class, for looking up localized strings, etc.\r
+ '</summary>\r
+ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0"), _\r
+ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _\r
+ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _\r
+ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _\r
+ Friend Module Resources\r
+ \r
+ Private resourceMan As Global.System.Resources.ResourceManager\r
+ \r
+ Private resourceCulture As Global.System.Globalization.CultureInfo\r
+ \r
+ '<summary>\r
+ ' Returns the cached ResourceManager instance used by this class.\r
+ '</summary>\r
+ <Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager\r
+ Get\r
+ If Object.ReferenceEquals(resourceMan, Nothing) Then\r
+ Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SimpleChat.VB.Resources", GetType(Resources).Assembly)\r
+ resourceMan = temp\r
+ End If\r
+ Return resourceMan\r
+ End Get\r
+ End Property\r
+ \r
+ '<summary>\r
+ ' Overrides the current thread's CurrentUICulture property for all\r
+ ' resource lookups using this strongly typed resource class.\r
+ '</summary>\r
+ <Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Friend Property Culture() As Global.System.Globalization.CultureInfo\r
+ Get\r
+ Return resourceCulture\r
+ End Get\r
+ Set(ByVal value As Global.System.Globalization.CultureInfo)\r
+ resourceCulture = value\r
+ End Set\r
+ End Property\r
+ End Module\r
+End Namespace\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+ <!-- \r
+ Microsoft ResX Schema \r
+ \r
+ Version 2.0\r
+ \r
+ The primary goals of this format is to allow a simple XML format \r
+ that is mostly human readable. The generation and parsing of the \r
+ various data types are done through the TypeConverter classes \r
+ associated with the data types.\r
+ \r
+ Example:\r
+ \r
+ ... ado.net/XML headers & schema ...\r
+ <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+ <resheader name="version">2.0</resheader>\r
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+ <value>[base64 mime encoded serialized .NET Framework object]</value>\r
+ </data>\r
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
+ <comment>This is a comment</comment>\r
+ </data>\r
+ \r
+ There are any number of "resheader" rows that contain simple \r
+ name/value pairs.\r
+ \r
+ Each data row contains a name, and value. The row also contains a \r
+ type or mimetype. Type corresponds to a .NET class that support \r
+ text/value conversion through the TypeConverter architecture. \r
+ Classes that don't support this are serialized and stored with the \r
+ mimetype set.\r
+ \r
+ The mimetype is used for serialized objects, and tells the \r
+ ResXResourceReader how to depersist the object. This is currently not \r
+ extensible. For a given mimetype the value must be set accordingly:\r
+ \r
+ Note - application/x-microsoft.net.object.binary.base64 is the format \r
+ that the ResXResourceWriter will generate, however the reader can \r
+ read any of the formats listed below.\r
+ \r
+ mimetype: application/x-microsoft.net.object.binary.base64\r
+ value : The object must be serialized with \r
+ : System.Serialization.Formatters.Binary.BinaryFormatter\r
+ : and then encoded with base64 encoding.\r
+ \r
+ mimetype: application/x-microsoft.net.object.soap.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+ : and then encoded with base64 encoding.\r
+\r
+ mimetype: application/x-microsoft.net.object.bytearray.base64\r
+ value : The object must be serialized into a byte array \r
+ : using a System.ComponentModel.TypeConverter\r
+ : and then encoded with base64 encoding.\r
+ -->\r
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+ <xsd:element name="root" msdata:IsDataSet="true">\r
+ <xsd:complexType>\r
+ <xsd:choice maxOccurs="unbounded">\r
+ <xsd:element name="metadata">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" />\r
+ <xsd:attribute name="type" type="xsd:string" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="assembly">\r
+ <xsd:complexType>\r
+ <xsd:attribute name="alias" type="xsd:string" />\r
+ <xsd:attribute name="name" type="xsd:string" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="data">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />\r
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="resheader">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:choice>\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:schema>\r
+ <resheader name="resmimetype">\r
+ <value>text/microsoft-resx</value>\r
+ </resheader>\r
+ <resheader name="version">\r
+ <value>2.0</value>\r
+ </resheader>\r
+ <resheader name="reader">\r
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+ <resheader name="writer">\r
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+</root>
\ No newline at end of file
--- /dev/null
+'------------------------------------------------------------------------------\r
+' <auto-generated>\r
+' This code was generated by a tool.\r
+' Runtime Version:2.0.50727.4918\r
+'\r
+' Changes to this file may cause incorrect behavior and will be lost if\r
+' the code is regenerated.\r
+' </auto-generated>\r
+'------------------------------------------------------------------------------\r
+\r
+Option Strict On\r
+Option Explicit On\r
+\r
+\r
+Namespace My\r
+\r
+ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _\r
+ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0"), _\r
+ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Partial Friend NotInheritable Class MySettings\r
+ Inherits Global.System.Configuration.ApplicationSettingsBase\r
+ \r
+ Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)\r
+ \r
+#Region "My.Settings Auto-Save Functionality"\r
+#If _MyType = "WindowsForms" Then\r
+ Private Shared addedHandler As Boolean\r
+\r
+ Private Shared addedHandlerLockObject As New Object\r
+\r
+ <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _\r
+ Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)\r
+ If My.Application.SaveMySettingsOnExit Then\r
+ My.Settings.Save()\r
+ End If\r
+ End Sub\r
+#End If\r
+#End Region\r
+ \r
+ Public Shared ReadOnly Property [Default]() As MySettings\r
+ Get\r
+ \r
+#If _MyType = "WindowsForms" Then\r
+ If Not addedHandler Then\r
+ SyncLock addedHandlerLockObject\r
+ If Not addedHandler Then\r
+ AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings\r
+ addedHandler = True\r
+ End If\r
+ End SyncLock\r
+ End If\r
+#End If\r
+ Return defaultInstance\r
+ End Get\r
+ End Property\r
+ End Class\r
+End Namespace\r
+\r
+Namespace My\r
+ \r
+ <Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _\r
+ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _\r
+ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _\r
+ Friend Module MySettingsProperty\r
+ \r
+ <Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _\r
+ Friend ReadOnly Property Settings() As Global.SimpleChat.VB.My.MySettings\r
+ Get\r
+ Return Global.SimpleChat.VB.My.MySettings.Default\r
+ End Get\r
+ End Property\r
+ End Module\r
+End Namespace\r
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>\r
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">\r
+ <Profiles>\r
+ <Profile Name="(Default)" />\r
+ </Profiles>\r
+ <Settings />\r
+</SettingsFile>\r
--- /dev/null
+<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _\r
+Partial Class SimpleChat\r
+ Inherits System.Windows.Forms.Form\r
+\r
+ 'Form overrides dispose to clean up the component list.\r
+ <System.Diagnostics.DebuggerNonUserCode()> _\r
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)\r
+ Try\r
+ If disposing AndAlso components IsNot Nothing Then\r
+ components.Dispose()\r
+ End If\r
+ Finally\r
+ MyBase.Dispose(disposing)\r
+ End Try\r
+ End Sub\r
+\r
+ 'Required by the Windows Form Designer\r
+ Private components As System.ComponentModel.IContainer\r
+\r
+ 'NOTE: The following procedure is required by the Windows Form Designer\r
+ 'It can be modified using the Windows Form Designer. \r
+ 'Do not modify it using the code editor.\r
+ <System.Diagnostics.DebuggerStepThrough()> _\r
+ Private Sub InitializeComponent()\r
+ Me.TextBox1 = New System.Windows.Forms.TextBox\r
+ Me.TextBox2 = New System.Windows.Forms.TextBox\r
+ Me.TalkTo = New System.Windows.Forms.Label\r
+ Me.ComboBox1 = New System.Windows.Forms.ComboBox\r
+ Me.Button1 = New System.Windows.Forms.Button\r
+ Me.SuspendLayout()\r
+ '\r
+ 'TextBox1\r
+ '\r
+ Me.TextBox1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)\r
+ Me.TextBox1.Location = New System.Drawing.Point(12, 12)\r
+ Me.TextBox1.Multiline = True\r
+ Me.TextBox1.Name = "TextBox1"\r
+ Me.TextBox1.ReadOnly = True\r
+ Me.TextBox1.Size = New System.Drawing.Size(459, 362)\r
+ Me.TextBox1.TabIndex = 0\r
+ '\r
+ 'TextBox2\r
+ '\r
+ Me.TextBox2.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _\r
+ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)\r
+ Me.TextBox2.Location = New System.Drawing.Point(13, 431)\r
+ Me.TextBox2.Name = "TextBox2"\r
+ Me.TextBox2.Size = New System.Drawing.Size(374, 20)\r
+ Me.TextBox2.TabIndex = 1\r
+ '\r
+ 'TalkTo\r
+ '\r
+ Me.TalkTo.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.TalkTo.AutoSize = True\r
+ Me.TalkTo.Location = New System.Drawing.Point(13, 395)\r
+ Me.TalkTo.Name = "TalkTo"\r
+ Me.TalkTo.Size = New System.Drawing.Size(43, 13)\r
+ Me.TalkTo.TabIndex = 2\r
+ Me.TalkTo.Text = "Talk to:"\r
+ '\r
+ 'ComboBox1\r
+ '\r
+ Me.ComboBox1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)\r
+ Me.ComboBox1.FormattingEnabled = True\r
+ Me.ComboBox1.Location = New System.Drawing.Point(63, 392)\r
+ Me.ComboBox1.Name = "ComboBox1"\r
+ Me.ComboBox1.Size = New System.Drawing.Size(324, 21)\r
+ Me.ComboBox1.TabIndex = 3\r
+ '\r
+ 'Button1\r
+ '\r
+ Me.Button1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)\r
+ Me.Button1.Location = New System.Drawing.Point(409, 430)\r
+ Me.Button1.Name = "Button1"\r
+ Me.Button1.Size = New System.Drawing.Size(59, 23)\r
+ Me.Button1.TabIndex = 4\r
+ Me.Button1.Text = "Send"\r
+ Me.Button1.UseVisualStyleBackColor = True\r
+ '\r
+ 'SimpleChat\r
+ '\r
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)\r
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font\r
+ Me.ClientSize = New System.Drawing.Size(483, 462)\r
+ Me.Controls.Add(Me.Button1)\r
+ Me.Controls.Add(Me.ComboBox1)\r
+ Me.Controls.Add(Me.TalkTo)\r
+ Me.Controls.Add(Me.TextBox2)\r
+ Me.Controls.Add(Me.TextBox1)\r
+ Me.Name = "SimpleChat"\r
+ Me.Text = "SimpleChat.VB"\r
+ Me.ResumeLayout(False)\r
+ Me.PerformLayout()\r
+\r
+ End Sub\r
+ Friend WithEvents TextBox1 As System.Windows.Forms.TextBox\r
+ Friend WithEvents TextBox2 As System.Windows.Forms.TextBox\r
+ Friend WithEvents TalkTo As System.Windows.Forms.Label\r
+ Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox\r
+ Friend WithEvents Button1 As System.Windows.Forms.Button\r
+\r
+End Class\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <PropertyGroup>\r
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+ <ProductVersion>8.0.50727</ProductVersion>\r
+ <SchemaVersion>2.0</SchemaVersion>\r
+ <ProjectGuid>{5ACED234-EB98-415E-9974-B54A70789821}</ProjectGuid>\r
+ <OutputType>WinExe</OutputType>\r
+ <StartupObject>SimpleChat.VB.My.MyApplication</StartupObject>\r
+ <RootNamespace>SimpleChat.VB</RootNamespace>\r
+ <AssemblyName>SimpleChat.VB</AssemblyName>\r
+ <MyType>WindowsForms</MyType>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+ <DebugSymbols>true</DebugSymbols>\r
+ <DebugType>full</DebugType>\r
+ <DefineDebug>true</DefineDebug>\r
+ <DefineTrace>true</DefineTrace>\r
+ <OutputPath>bin\Debug\</OutputPath>\r
+ <DocumentationFile>SimpleChat.VB.xml</DocumentationFile>\r
+ <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+ <DebugType>pdbonly</DebugType>\r
+ <DefineDebug>false</DefineDebug>\r
+ <DefineTrace>true</DefineTrace>\r
+ <Optimize>true</Optimize>\r
+ <OutputPath>bin\Release\</OutputPath>\r
+ <DocumentationFile>SimpleChat.VB.xml</DocumentationFile>\r
+ <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>\r
+ </PropertyGroup>\r
+ <ItemGroup>\r
+ <Reference Include="System" />\r
+ <Reference Include="System.Data" />\r
+ <Reference Include="System.Deployment" />\r
+ <Reference Include="System.Drawing" />\r
+ <Reference Include="System.Windows.Forms" />\r
+ <Reference Include="System.Xml" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Import Include="Microsoft.VisualBasic" />\r
+ <Import Include="System" />\r
+ <Import Include="System.Collections" />\r
+ <Import Include="System.Collections.Generic" />\r
+ <Import Include="System.Data" />\r
+ <Import Include="System.Drawing" />\r
+ <Import Include="System.Diagnostics" />\r
+ <Import Include="System.Windows.Forms" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Compile Include="SimpleChat.vb">\r
+ <SubType>Form</SubType>\r
+ </Compile>\r
+ <Compile Include="SimpleChat.Designer.vb">\r
+ <DependentUpon>SimpleChat.vb</DependentUpon>\r
+ <SubType>Form</SubType>\r
+ </Compile>\r
+ <Compile Include="My Project\AssemblyInfo.vb" />\r
+ <Compile Include="My Project\Application.Designer.vb">\r
+ <AutoGen>True</AutoGen>\r
+ <DependentUpon>Application.myapp</DependentUpon>\r
+ </Compile>\r
+ <Compile Include="My Project\Resources.Designer.vb">\r
+ <AutoGen>True</AutoGen>\r
+ <DesignTime>True</DesignTime>\r
+ <DependentUpon>Resources.resx</DependentUpon>\r
+ </Compile>\r
+ <Compile Include="My Project\Settings.Designer.vb">\r
+ <AutoGen>True</AutoGen>\r
+ <DependentUpon>Settings.settings</DependentUpon>\r
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>\r
+ </Compile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <EmbeddedResource Include="SimpleChat.resx">\r
+ <SubType>Designer</SubType>\r
+ <DependentUpon>SimpleChat.vb</DependentUpon>\r
+ </EmbeddedResource>\r
+ <EmbeddedResource Include="My Project\Resources.resx">\r
+ <Generator>VbMyResourcesResXFileCodeGenerator</Generator>\r
+ <LastGenOutput>Resources.Designer.vb</LastGenOutput>\r
+ <CustomToolNamespace>My.Resources</CustomToolNamespace>\r
+ <SubType>Designer</SubType>\r
+ </EmbeddedResource>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <None Include="My Project\Application.myapp">\r
+ <Generator>MyApplicationCodeGenerator</Generator>\r
+ <LastGenOutput>Application.Designer.vb</LastGenOutput>\r
+ </None>\r
+ <None Include="My Project\Settings.settings">\r
+ <Generator>SettingsSingleFileGenerator</Generator>\r
+ <CustomToolNamespace>My</CustomToolNamespace>\r
+ <LastGenOutput>Settings.Designer.vb</LastGenOutput>\r
+ </None>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <COMReference Include="Bonjour">\r
+ <Guid>{18FBED6D-F2B7-4EC8-A4A4-46282E635308}</Guid>\r
+ <VersionMajor>1</VersionMajor>\r
+ <VersionMinor>0</VersionMinor>\r
+ <Lcid>0</Lcid>\r
+ <WrapperTool>tlbimp</WrapperTool>\r
+ <Isolated>False</Isolated>\r
+ </COMReference>\r
+ </ItemGroup>\r
+ <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />\r
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+ Other similar extension points exist, see Microsoft.Common.targets.\r
+ <Target Name="BeforeBuild">\r
+ </Target>\r
+ <Target Name="AfterBuild">\r
+ </Target>\r
+ -->\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+ <!-- \r
+ Microsoft ResX Schema \r
+ \r
+ Version 2.0\r
+ \r
+ The primary goals of this format is to allow a simple XML format \r
+ that is mostly human readable. The generation and parsing of the \r
+ various data types are done through the TypeConverter classes \r
+ associated with the data types.\r
+ \r
+ Example:\r
+ \r
+ ... ado.net/XML headers & schema ...\r
+ <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+ <resheader name="version">2.0</resheader>\r
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+ <value>[base64 mime encoded serialized .NET Framework object]</value>\r
+ </data>\r
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
+ <comment>This is a comment</comment>\r
+ </data>\r
+ \r
+ There are any number of "resheader" rows that contain simple \r
+ name/value pairs.\r
+ \r
+ Each data row contains a name, and value. The row also contains a \r
+ type or mimetype. Type corresponds to a .NET class that support \r
+ text/value conversion through the TypeConverter architecture. \r
+ Classes that don't support this are serialized and stored with the \r
+ mimetype set.\r
+ \r
+ The mimetype is used for serialized objects, and tells the \r
+ ResXResourceReader how to depersist the object. This is currently not \r
+ extensible. For a given mimetype the value must be set accordingly:\r
+ \r
+ Note - application/x-microsoft.net.object.binary.base64 is the format \r
+ that the ResXResourceWriter will generate, however the reader can \r
+ read any of the formats listed below.\r
+ \r
+ mimetype: application/x-microsoft.net.object.binary.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r
+ : and then encoded with base64 encoding.\r
+ \r
+ mimetype: application/x-microsoft.net.object.soap.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+ : and then encoded with base64 encoding.\r
+\r
+ mimetype: application/x-microsoft.net.object.bytearray.base64\r
+ value : The object must be serialized into a byte array \r
+ : using a System.ComponentModel.TypeConverter\r
+ : and then encoded with base64 encoding.\r
+ -->\r
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />\r
+ <xsd:element name="root" msdata:IsDataSet="true">\r
+ <xsd:complexType>\r
+ <xsd:choice maxOccurs="unbounded">\r
+ <xsd:element name="metadata">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" use="required" type="xsd:string" />\r
+ <xsd:attribute name="type" type="xsd:string" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" />\r
+ <xsd:attribute ref="xml:space" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="assembly">\r
+ <xsd:complexType>\r
+ <xsd:attribute name="alias" type="xsd:string" />\r
+ <xsd:attribute name="name" type="xsd:string" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="data">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />\r
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+ <xsd:attribute ref="xml:space" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="resheader">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:choice>\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:schema>\r
+ <resheader name="resmimetype">\r
+ <value>text/microsoft-resx</value>\r
+ </resheader>\r
+ <resheader name="version">\r
+ <value>2.0</value>\r
+ </resheader>\r
+ <resheader name="reader">\r
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+ <resheader name="writer">\r
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+</root>
\ No newline at end of file
--- /dev/null
+\r
+Imports System.Net\r
+Imports System.Net.Sockets\r
+Imports System.Data\r
+Imports System.Text\r
+\r
+Public Class SimpleChat\r
+ Public WithEvents MyEventManager As New Bonjour.DNSSDEventManager\r
+ Private m_service As New Bonjour.DNSSDService\r
+ Private m_registrar As Bonjour.DNSSDService\r
+ Private m_browser As Bonjour.DNSSDService\r
+ Private m_resolver As Bonjour.DNSSDService\r
+ Private m_socket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)\r
+ Private m_port As Integer\r
+ Private m_buffer(1024 * 32) As Byte\r
+ Private m_async As IAsyncResult\r
+ Public Delegate Sub SocketDelegate(ByVal msg As String)\r
+ Private m_socketDelegate As SocketDelegate\r
+ Private m_name As String\r
+\r
+ Public Sub New()\r
+ MyBase.New()\r
+\r
+ 'This call is required by the Windows Form Designer.\r
+ InitializeComponent()\r
+\r
+ Button1.Enabled = False\r
+\r
+ m_socketDelegate = New SocketDelegate(AddressOf MessageReceived)\r
+\r
+ Dim endPoint As New IPEndPoint(IPAddress.Any, 0)\r
+ m_socket.Bind(endPoint)\r
+ endPoint = m_socket.LocalEndPoint\r
+ m_port = endPoint.Port\r
+\r
+ Dim txtRecord As Bonjour.TXTRecord\r
+ m_async = m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial, New AsyncCallback(AddressOf OnReceive), Me)\r
+ m_registrar = m_service.Register(0, 0, Environment.UserName, "_p2pchat._udp", vbNullString, vbNullString, m_port, txtRecord, MyEventManager)\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceRegistered(ByVal registrar As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal name As String, ByVal regType As String, ByVal domain As String) Handles MyEventManager.ServiceRegistered\r
+ m_name = name\r
+ m_browser = m_service.Browse(0, 0, regType, vbNullString, MyEventManager)\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceFound(ByVal browser As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal serviceName As String, ByVal regtype As String, ByVal domain As String) Handles MyEventManager.ServiceFound\r
+ If (serviceName <> m_name) Then\r
+ Dim peer As PeerData = New PeerData\r
+ peer.InterfaceIndex = ifIndex\r
+ peer.Name = serviceName\r
+ peer.Type = regtype\r
+ peer.Domain = domain\r
+ ComboBox1.Items.Add(peer)\r
+ ComboBox1.SelectedIndex = 0\r
+ End If\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceLost(ByVal browser As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal serviceName As String, ByVal regtype As String, ByVal domain As String) Handles MyEventManager.ServiceLost\r
+ ComboBox1.Items.Remove(serviceName)\r
+ End Sub\r
+ Public Sub MyEventManager_ServiceResolved(ByVal resolver As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal fullname As String, ByVal hostname As String, ByVal port As UShort, ByVal record As Bonjour.TXTRecord) Handles MyEventManager.ServiceResolved\r
+ m_resolver.Stop()\r
+ Dim peer As PeerData = ComboBox1.SelectedItem\r
+ peer.Port = port\r
+ m_resolver = m_service.QueryRecord(0, ifIndex, hostname, Bonjour.DNSSDRRType.kDNSSDType_A, Bonjour.DNSSDRRClass.kDNSSDClass_IN, MyEventManager)\r
+ End Sub\r
+ Public Sub MyEventManager_QueryAnswered(ByVal resolver As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal fullName As String, ByVal rrtype As Bonjour.DNSSDRRType, ByVal rrclass As Bonjour.DNSSDRRClass, ByVal rdata As Object, ByVal ttl As UInteger) Handles MyEventManager.QueryRecordAnswered\r
+ m_resolver.Stop()\r
+ Dim peer As PeerData = ComboBox1.SelectedItem
+ Dim bits As UInteger = BitConverter.ToUInt32(rdata, 0)
+ Dim address As IPAddress = New System.Net.IPAddress(bits)
+ peer.Address = address\r
+ End Sub\r
+ Public Sub MyEventManager_OperationFailed(ByVal registrar As Bonjour.DNSSDService, ByVal errorCode As Bonjour.DNSSDError) Handles MyEventManager.OperationFailed\r
+ MessageBox.Show("Operation failed error code: " + errorCode)\r
+ End Sub\r
+\r
+ Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click\r
+ Dim peer As PeerData = ComboBox1.SelectedItem
+ Dim message As String = m_name + ": " + TextBox2.Text
+ Dim bytes As Byte() = Encoding.UTF8.GetBytes(message)
+ Dim endPoint As IPEndPoint = New IPEndPoint(peer.Address, peer.Port)
+ m_socket.SendTo(bytes, 0, bytes.Length, 0, endPoint)
+ TextBox1.AppendText(TextBox2.Text + Environment.NewLine)
+ TextBox2.Text = ""\r
+ End Sub\r
+\r
+ Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged\r
+ Dim peer As PeerData = ComboBox1.SelectedItem\r
+ m_resolver = m_service.Resolve(0, peer.InterfaceIndex, peer.Name, peer.Type, peer.Domain, MyEventManager)\r
+ End Sub\r
+ Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged\r
+ Dim peer As PeerData = ComboBox1.SelectedItem\r
+ If ((peer.Address IsNot Nothing) And TextBox2.Text.Length > 0) Then\r
+ Button1.Enabled = True\r
+ Else\r
+ Button1.Enabled = False\r
+ End If\r
+ End Sub\r
+ Public Sub MessageReceived(ByVal msg As System.String)\r
+ TextBox1.AppendText(msg)\r
+ End Sub\r
+ Private Sub OnReceive(ByVal ar As IAsyncResult)\r
+ Dim bytesReceived As Integer = m_socket.EndReceive(ar)\r
+ If (bytesReceived > 0) Then\r
+ Dim msg As String = Encoding.UTF8.GetString(m_buffer, 0, bytesReceived)\r
+ Me.Invoke(m_socketDelegate, msg)\r
+ End If\r
+ m_async = m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial, New AsyncCallback(AddressOf OnReceive), Me)\r
+ End Sub\r
+End Class\r
+\r
+Public Class PeerData\r
+ Public InterfaceIndex As UInteger\r
+ Public Name As String\r
+ Public Type As String\r
+ Public Domain As String\r
+ Public Address As IPAddress\r
+ Public Port As UShort\r
+\r
+ Overrides Function ToString() As String\r
+ Return Name\r
+ End Function\r
+End Class\r
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2008 Apple Inc. All rights reserved.
*
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
* ("Apple") in consideration of your agreement to the following terms, and your
#include <ctype.h>
#include <stdio.h> // For stdout, stderr
#include <stdlib.h> // For exit()
-#include <string.h> // For strlen(), strcpy(), bzero()
+#include <string.h> // For strlen(), strcpy()
#include <errno.h> // For errno, EINTR
#include <time.h>
#include <sys/types.h> // For u_char
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
+ #include <Iphlpapi.h>
#include <process.h>
typedef int pid_t;
#define getpid _getpid
#define strcasecmp _stricmp
#define snprintf _snprintf
static const char kFilePathSep = '\\';
+ #ifndef HeapEnableTerminationOnCorruption
+ # define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1
+ #endif
+ #if !defined(IFNAMSIZ)
+ #define IFNAMSIZ 16
+ #endif
+ #define if_nametoindex if_nametoindex_win
+ #define if_indextoname if_indextoname_win
+
+ typedef PCHAR (WINAPI * if_indextoname_funcptr_t)(ULONG index, PCHAR name);
+ typedef ULONG (WINAPI * if_nametoindex_funcptr_t)(PCSTR name);
+
+ unsigned if_nametoindex_win(const char *ifname)
+ {
+ HMODULE library;
+ unsigned index = 0;
+
+ // 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_win( unsigned ifindex, char *ifname)
+ {
+ HMODULE library;
+ char * name = NULL;
+
+ // 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;
+ }
+
#else
#include <unistd.h> // For getopt() and optind
#include <netdb.h> // For getaddrinfo()
#include "dns_sd.h"
+#include "ClientCommon.h"
+
#if TEST_NEW_CLIENTSTUB
#include "../mDNSShared/dnssd_ipc.c"
#include "../mDNSShared/dnssd_clientlib.c"
static char myhinfoW[14] = "\002PC\012Windows XP";
static char myhinfoX[ 9] = "\003Mac\004OS X";
static char updatetest[3] = "\002AA";
-static char bigNULL[8200];
+static char bigNULL[8192]; // 8K is maximum rdata we support
// Note: the select() implementation on Windows (Winsock2) fails with any timeout much larger than this
#define LONG_TIME 100000000
#define DomainMsg(X) (((X) & kDNSServiceFlagsDefault) ? "(Default)" : \
((X) & kDNSServiceFlagsAdd) ? "Added" : "Removed")
-static const char *GetNextLabel(const char *cstr, char label[64])
- {
- char *ptr = label;
- while (*cstr && *cstr != '.') // While we have characters in the label...
- {
- char c = *cstr++;
- if (c == '\\')
- {
- c = *cstr++;
- if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
- {
- int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
- int v1 = cstr[ 0] - '0';
- int v2 = cstr[ 1] - '0';
- int val = v0 * 100 + v1 * 10 + v2;
- if (val <= 255) { c = (char)val; cstr += 2; } // If valid three-digit decimal value, use it
- }
- }
- *ptr++ = c;
- if (ptr >= label+64) return(NULL);
- }
- if (*cstr) cstr++; // Skip over the trailing dot (if present)
- *ptr++ = 0;
- return(cstr);
- }
+#define MAX_LABELS 128
static void DNSSD_API enum_reply(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t ifIndex,
DNSServiceErrorType errorCode, const char *replyDomain, void *context)
DNSServiceFlags partialflags = flags & ~(kDNSServiceFlagsMoreComing | kDNSServiceFlagsAdd | kDNSServiceFlagsDefault);
int labels = 0, depth = 0, i, initial = 0;
char text[64];
- const char *label[128];
+ const char *label[MAX_LABELS];
(void)sdref; // Unused
(void)ifIndex; // Unused
else printf(" ");
// 2. Count the labels
- while (*replyDomain)
+ while (replyDomain && *replyDomain && labels < MAX_LABELS)
{
label[labels++] = replyDomain;
replyDomain = GetNextLabel(replyDomain, text);
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
+static int CopyLabels(char *dst, const char *lim, const char **srcp, int labels)
+ {
+ const char *src = *srcp;
+ while (*src != '.' || --labels > 0)
+ {
+ if (*src == '\\') *dst++ = *src++; // Make sure "\." doesn't confuse us
+ if (!*src || dst >= lim) return -1;
+ *dst++ = *src++;
+ if (!*src || dst >= lim) return -1;
+ }
+ *dst++ = 0;
+ *srcp = src + 1; // skip over final dot
+ return 0;
+ }
+
+static void DNSSD_API zonedata_resolve(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char *fullname, const char *hosttarget, uint16_t opaqueport, uint16_t txtLen, const unsigned char *txt, void *context)
+ {
+ union { uint16_t s; u_char b[2]; } port = { opaqueport };
+ uint16_t PortAsNumber = ((uint16_t)port.b[0]) << 8 | port.b[1];
+
+ const char *p = fullname;
+ char n[kDNSServiceMaxDomainName];
+ char t[kDNSServiceMaxDomainName];
+
+ const unsigned char *max = txt + txtLen;
+
+ (void)sdref; // Unused
+ (void)ifIndex; // Unused
+ (void)context; // Unused
+
+ //if (!(flags & kDNSServiceFlagsAdd)) return;
+ if (errorCode) { printf("Error code %d\n", errorCode); return; }
+
+ if (CopyLabels(n, n + kDNSServiceMaxDomainName, &p, 3)) return; // Fetch name+type
+ p = fullname;
+ if (CopyLabels(t, t + kDNSServiceMaxDomainName, &p, 1)) return; // Skip first label
+ if (CopyLabels(t, t + kDNSServiceMaxDomainName, &p, 2)) return; // Fetch next two labels (service type)
+
+ if (num_printed++ == 0)
+ {
+ printf("\n");
+ printf("; To direct clients to browse a different domain, substitute that domain in place of '@'\n");
+ printf("%-47s PTR %s\n", "lb._dns-sd._udp", "@");
+ printf("\n");
+ printf("; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.\n");
+ printf("; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local\n");
+ printf("; names with the correct fully-qualified (unicast) domain name of the target host offering the service.\n");
+ }
+
+ printf("\n");
+ printf("%-47s PTR %s\n", t, n);
+ printf("%-47s SRV 0 0 %d %s ; Replace with unicast FQDN of target host\n", n, PortAsNumber, hosttarget);
+ printf("%-47s TXT ", n);
+
+ while (txt < max)
+ {
+ const unsigned char *const end = txt + 1 + txt[0];
+ txt++; // Skip over length byte
+ printf(" \"");
+ while (txt<end)
+ {
+ if (*txt == '\\' || *txt == '\"') printf("\\");
+ printf("%c", *txt++);
+ }
+ printf("\"");
+ }
+ printf("\n");
+
+ DNSServiceRefDeallocate(sdref);
+ free(context);
+
+ if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
+ }
+
+static void DNSSD_API zonedata_browse(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char *replyName, const char *replyType, const char *replyDomain, void *context)
+ {
+ DNSServiceRef *newref;
+
+ (void)sdref; // Unused
+ (void)context; // Unused
+
+ if (!(flags & kDNSServiceFlagsAdd)) return;
+ if (errorCode) { printf("Error code %d\n", errorCode); return; }
+
+ newref = malloc(sizeof(*newref));
+ *newref = client;
+ DNSServiceResolve(newref, kDNSServiceFlagsShareConnection, ifIndex, replyName, replyType, replyDomain, zonedata_resolve, newref);
+ }
+
static void DNSSD_API browse_reply(DNSServiceRef sdref, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
const char *replyName, const char *replyType, const char *replyDomain, void *context)
{
if (errorCode) printf("Error code %d\n", errorCode);
else
{
- printf("%s can be reached at %s:%u", fullname, hosttarget, PortAsNumber);
+ printf("%s can be reached at %s:%u (interface %d)", fullname, hosttarget, PortAsNumber, ifIndex);
if (flags) printf(" Flags: %X", flags);
// Don't show degenerate TXT records containing nothing but a single empty string
if (txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); }
const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
if (a0 == (const char *)1) a0 = argv[0];
+#if defined(_WIN32)
+ HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
+#endif
+
+#if TEST_NEW_CLIENTSTUB
+ printf("Using embedded copy of dnssd_clientstub instead of system library\n");
if (sizeof(argv) == 8) printf("Running in 64-bit mode\n");
+#endif
// Test code for TXTRecord functions
//TXTRecordRef txtRecord;
}
if (argc < 2) goto Fail; // Minimum command line is the command name and one argument
- operation = getfirstoption(argc, argv, "EFBLRPQCAUNTMISV"
+ operation = getfirstoption(argc, argv, "EFBZLRPQCAUNTMISV"
#if HAS_NAT_PMP_API
"X"
#endif
err = DNSServiceBrowse(&client, 0, opinterface, typ, dom, browse_reply, NULL);
break;
+ case 'Z': typ = (argc < opi+1) ? "" : argv[opi+0];
+ dom = (argc < opi+2) ? "" : argv[opi+1]; // Missing domain argument is the same as empty string i.e. use system default(s)
+ typ = gettype(buffer, typ);
+ if (dom[0] == '.' && dom[1] == 0) dom[0] = 0; // We allow '.' on the command line as a synonym for empty string
+ printf("Browsing for %s%s%s\n", typ, dom[0] ? "." : "", dom);
+ err = DNSServiceCreateConnection(&client);
+ sc1 = client;
+ err = DNSServiceBrowse(&sc1, kDNSServiceFlagsShareConnection, opinterface, typ, dom, zonedata_browse, NULL);
+ break;
+
case 'L': if (argc < opi+2) goto Fail;
typ = (argc < opi+2) ? "" : argv[opi+1];
dom = (argc < opi+3) ? "local" : argv[opi+2];
typ = gettype(buffer, typ);
if (dom[0] == '.' && dom[1] == 0) dom = "local"; // We allow '.' on the command line as a synonym for "local"
printf("Lookup %s.%s.%s\n", argv[opi+0], typ, dom);
- err = DNSServiceResolve(&client, 0, opinterface, argv[opi+0], typ, dom, (DNSServiceResolveReply)resolve_reply, NULL);
+ err = DNSServiceResolve(&client, 0, opinterface, argv[opi+0], typ, dom, resolve_reply, NULL);
break;
case 'R': if (argc < opi+4) goto Fail;
err = RegisterProxyAddressRecord(client_pa, argv[opi+4], argv[opi+5]);
//err = RegisterProxyAddressRecord(client_pa, "two", argv[opi+5]);
if (err) break;
- err = RegisterService(&client, argv[opi+0], argv[opi+1], argv[opi+2], argv[opi+4], argv[opi+3], argc-(opi+6), argv+(opi+6));
+ err = RegisterService(&client, argv[opi+0], gettype(buffer, argv[opi+1]), argv[opi+2], argv[opi+4], argv[opi+3], argc-(opi+6), argv+(opi+6));
//DNSServiceRemoveRecord(client_pa, record, 0);
//DNSServiceRemoveRecord(client_pa, record, 0);
break;
case 'S': {
Opaque16 registerPort = { { 0x23, 0x45 } };
+ unsigned char txtrec[16] = "\xF" "/path=test.html";
+ DNSRecordRef rec;
+ unsigned char nulrec[4] = "1234";
+
err = DNSServiceCreateConnection(&client);
if (err) { fprintf(stderr, "DNSServiceCreateConnection failed %ld\n", (long int)err); return (-1); }
"_http._tcp", "local", NULL, registerPort.NotAnInteger, 0, NULL, reg_reply, NULL);
if (err) { fprintf(stderr, "SharedConnection DNSServiceRegister failed %ld\n", (long int)err); return (-1); }
+ err = DNSServiceUpdateRecord(sc3, NULL, 0, sizeof(txtrec), txtrec, 0);
+ if (err) { fprintf(stderr, "SharedConnection DNSServiceUpdateRecord failed %ld\n", (long int)err); return (-1); }
+
+ err = DNSServiceAddRecord(sc3, &rec, 0, kDNSServiceType_NULL, sizeof(nulrec), nulrec, 0);
+ if (err) { fprintf(stderr, "SharedConnection DNSServiceAddRecord failed %ld\n", (long int)err); return (-1); }
+
+ err = DNSServiceRemoveRecord(sc3, rec, 0);
+ if (err) { fprintf(stderr, "SharedConnection DNSServiceRemoveRecord failed %ld\n", (long int)err); return (-1); }
+
break;
}
fprintf(stderr, "%s -L <Name> <Type> <Domain> (Look up a service instance)\n", a0);
fprintf(stderr, "%s -R <Name> <Type> <Domain> <Port> [<TXT>...] (Register a service)\n", a0);
fprintf(stderr, "%s -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Proxy)\n", a0);
+ fprintf(stderr, "%s -Z <Type> <Domain> (Output results in Zone File format)\n", a0);
fprintf(stderr, "%s -Q <FQDN> <rrtype> <rrclass> (Generic query for any record type)\n", a0);
fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", a0);
#if HAS_NAT_PMP_API
#if HAS_ADDRINFO_API
fprintf(stderr, "%s -G v4/v6/v4v6 <Hostname> (Get address information for hostname)\n", a0);
#endif
+ fprintf(stderr, "%s -V (Get version of currently running daemon / system service)\n", a0);
+
fprintf(stderr, "%s -A (Test Adding/Updating/Deleting a record)\n", a0);
fprintf(stderr, "%s -U (Test updating a TXT record)\n", a0);
fprintf(stderr, "%s -N (Test adding a large NULL record)\n", a0);
fprintf(stderr, "%s -M (Test creating a registration with multiple TXT records)\n", a0);
fprintf(stderr, "%s -I (Test registering and then immediately updating TXT record)\n", a0);
fprintf(stderr, "%s -S (Test multiple operations on a shared socket)\n", a0);
- fprintf(stderr, "%s -V (Get version of currently running daemon / system service)\n", a0);
return 0;
}
// The "@(#) " pattern is a special prefix the "what" command looks for
const char VersionString_SCCS[] = "@(#) dns-sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = VersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
include /Developer/Makefiles/pb_makefiles/platform.make
-MVERS = "mDNSResponder-176.3"
+MVERS = "mDNSResponder-212.1"
DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
All private LLQ operations are TSIG-enabled and sent over a secure
encrypted TLS channel. To accommodate service providers who don't want
to have to keep open a large number of TLS connections to a large number
-of client machines, the server has the option of dropping the TSL
+of client machines, the server has the option of dropping the TLS
connection after initial LLQ setup and sending subsequent events and
refreshes using unencrypted UDP packets. This results in less load on
the server, at the cost of slightly lower security (LLQs can only be set
+++ /dev/null
-<buildResults>\r\r
- <dest dir="ExplorerPluginModule_msm">\r\r
- <dest dir="Program Files/Bonjour">\r\r
- <src file="Clients/ExplorerPlugin/Release/*.dll"/>\r\r
- </dest>\r\r
- </dest>\r\r
- <dest dir="JavaModule_msm">\r\r
- <dest dir="Program Files/Bonjour">\r\r
- <src file="mDNSWindows/Java/build/prod/dns_sd.jar"/>\r\r
- </dest>\r\r
- <dest dir="System32">\r\r
- <src file="mDNSWindows/Java/build/prod/jdns_sd.dll"/>\r\r
- </dest>\r\r
- </dest>\r\r
- <dest dir="mDNSResponder_msm">\r\r
- <dest dir="Program Files/Bonjour">\r\r
- <src file="mDNSWindows/SystemService/Release/mDNSResponder.exe"/>\r\r
- <src file="mDNSWindows/mdnsNSP/Release/mdnsNSP.dll"/>\r\r
- </dest>\r\r
- <dest dir="System32">\r\r
- <src file="mDNSWindows/DLL/Release/dnssd.dll"/>\r\r
- <src file="Clients/DNS-SD.VisualStudio/Release/dns-sd.exe"/>\r\r
- </dest>\r\r
- </dest>\r\r
- <dest dir="PrinterSetupModule_msm">\r\r
- <dest dir="Program Files/Bonjour">\r\r
- <src file="Clients/PrinterSetupWizard/Release/*.exe"/>\r\r
- <src file="Clients/PrinterSetupWizard/Release/*.dll"/>\r\r
- </dest>\r\r
- </dest>\r\r
- <dest dir="sdk_root/Program Files/Bonjour SDK">\r
- <dest dir="include">\r\r
- <src file="mDNSShared/dns_sd.h"/>\r
- </dest>\r\r
- <dest dir="lib">\r\r
- <src file="mDNSWindows/DLL/Release/dnssd.lib"/>\r
- </dest>\r\r
- <dest dir="samples/C">\r\r
- <src file="Clients/dns-sd.c"/>\r
- <src file="Clients/DNS-SD.VisualStudio/Release/dns-sd.exe"/>\r\r
- </dest>\r\r
- <dest dir="samples/Java">\r\r
- <src file="Clients/Java/nmakefile"/>\r
- <src file="Clients/Java/BrowserApp.java"/>\r
- <src file="Clients/Java/SimpleChat.java"/>\r
- <src file="Clients/Java/Swing*.java"/>\r
- <src file="Clients/Java/build/prod/*.jar"/>\r
- </dest>\r\r
- </dest>\r\r
-</buildResults>\r\r
Change History (most recent first):
$Log: DNSCommon.c,v $
-Revision 1.199.2.1 2008/07/25 07:25:08 mcguire
-merge of <rdar://3988320&6041178> to SUSB for <rdar://problem/5662487&6090114>
+Revision 1.252 2009/06/27 00:27:03 cheshire
+<rdar://problem/6959273> mDNSResponder taking up 13% CPU with 400 KBps incoming bonjour requests
+Removed overly-complicate and ineffective multi-packet known-answer snooping code
+(Bracketed it with "#if ENABLE_MULTI_PACKET_QUERY_SNOOPING" for now; will delete actual code later)
+
+Revision 1.251 2009/05/19 23:40:37 cheshire
+<rdar://problem/6903507> Sleep Proxy: Retransmission logic not working reliably on quiet networks
+Added m->NextScheduledSPRetry timer for scheduling Sleep Proxy registration retries
+
+Revision 1.250 2009/05/01 21:28:33 cheshire
+<rdar://problem/6721680> AppleConnectAgent's reachability checks delay sleep by 30 seconds
+No longer suspend network operations after we've acknowledged that the machine is going to sleep,
+because other software may not have yet acknowledged the sleep event, and may be still trying
+to do unicast DNS queries or other Bonjour operations.
+
+Revision 1.249 2009/04/24 00:29:20 cheshire
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+Added support for generating/parsing/displaying NSEC records
+
+Revision 1.248 2009/04/23 22:11:16 cheshire
+Minor cleanup in debugging checks in GetLargeResourceRecord
+
+Revision 1.247 2009/04/21 23:36:25 cheshire
+<rdar://problem/6814427> Remove unused kDNSType_MAC
+
+Revision 1.246 2009/04/21 01:00:19 cheshire
+Fixed typo in previous checkin
+
+Revision 1.245 2009/04/21 00:57:23 cheshire
+<rdar://problem/6810410> Off-by-one error in putDomainNameAsLabels()
+If just writing one-byte root label, make sure we have space for that
+
+Revision 1.244 2009/04/11 00:19:30 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.243 2009/04/01 17:50:10 mcguire
+cleanup mDNSRandom
+
+Revision 1.242 2009/03/26 04:01:55 jessic2
+<rdar://problem/6613786> MessageTracer: Log service types longer than 14 characters and service types with underscores
+
+Revision 1.241 2009/03/18 20:50:08 cheshire
+<rdar://problem/6650064> uDNS: Reverse lookup of own IP address takes way too long, sometimes forever
+
+Revision 1.240 2009/03/18 20:41:04 cheshire
+Added definition of the all-ones mDNSOpaque16 ID
+
+Revision 1.239 2009/03/06 23:51:50 mcguire
+Fix broken build by defining DiscardPort
+
+Revision 1.238 2009/03/04 00:40:13 cheshire
+Updated DNS server error codes to be more consistent with definitions at
+<http://www.iana.org/assignments/dns-parameters>
+
+Revision 1.237 2009/03/03 23:04:43 cheshire
+For clarity, renamed "MAC" field to "HMAC" (Host MAC, as opposed to Interface MAC)
+
+Revision 1.236 2009/03/03 22:51:53 cheshire
+<rdar://problem/6504236> Sleep Proxy: Waking on same network but different interface will cause conflicts
+
+Revision 1.235 2009/02/07 05:55:44 cheshire
+Only pay attention to m->DelaySleep when it's nonzero
+
+Revision 1.234 2009/02/07 02:52:52 cheshire
+<rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+Pay attention to m->DelaySleep when computing next task time
+
+Revision 1.233 2009/01/30 23:50:31 cheshire
+Added LastLabel() routine to get the last label of a domainname
+
+Revision 1.232 2009/01/15 00:22:48 mcguire
+<rdar://problem/6437092> NAT-PMP: mDNSResponder needs to listen on 224.0.0.1:5350/UDP with REUSEPORT
+
+Revision 1.231 2008/12/12 01:24:06 cheshire
+Updated GetNextScheduledEvent() to pay attention to m->SPSProxyListChanged
+
+Revision 1.230 2008/12/10 01:55:54 cheshire
+Renamed "Max" macro to avoid conflict with another "Max" macro on ARMv5
+
+Revision 1.229 2008/11/27 01:28:45 cheshire
+For display purposes, show sleep sequence number as unsigned
+
+Revision 1.228 2008/11/26 20:57:37 cheshire
+For consistency with other similar macros, renamed mdnsIsDigit/mdnsIsLetter/mdnsValidHostChar
+to mDNSIsDigit/mDNSIsLetter/mDNSValidHostChar
+
+Revision 1.227 2008/11/26 20:28:05 cheshire
+Added new SSHPort constant
+
+Revision 1.226 2008/11/16 16:55:51 cheshire
+Updated debugging messages
+
+Revision 1.225 2008/11/14 21:56:31 cheshire
+Moved debugging routine ShowTaskSchedulingError() from daemon.c into DNSCommon.c
+
+Revision 1.224 2008/11/14 02:20:03 cheshire
+Include m->NextScheduledSPS in task scheduling calculations
+
+Revision 1.223 2008/11/14 01:19:03 cheshire
+Initialize TimeRcvd and TimeExpire fields in AuthRecord_struct
+
+Revision 1.222 2008/11/14 00:00:53 cheshire
+After client machine wakes up, Sleep Proxy machine need to remove any records
+it was temporarily holding as proxy for that client
+
+Revision 1.221 2008/11/13 19:06:02 cheshire
+Added code to put, get, and display rdataOPT properly
+
+Revision 1.220 2008/11/06 01:08:11 mcguire
+Fix compiler warning about discarding const
+
+Revision 1.219 2008/11/04 23:06:50 cheshire
+Split RDataBody union definition into RDataBody and RDataBody2, and removed
+SOA from the normal RDataBody union definition, saving 270 bytes per AuthRecord
+
+Revision 1.218 2008/11/04 22:21:44 cheshire
+Changed zone field of AuthRecord_struct from domainname to pointer, saving 252 bytes per AuthRecord
+
+Revision 1.217 2008/11/04 22:13:43 cheshire
+Made RDataBody parameter to GetRRDisplayString_rdb "const"
+
+Revision 1.216 2008/11/04 20:06:19 cheshire
+<rdar://problem/6186231> Change MAX_DOMAIN_NAME to 256
+
+Revision 1.215 2008/10/23 23:54:35 cheshire
+Added missing "const" in declaration
+
+Revision 1.214 2008/10/23 22:25:55 cheshire
+Renamed field "id" to more descriptive "updateid"
+
+Revision 1.213 2008/10/22 01:01:52 cheshire
+Added onesEthAddr constant, used for sending ARP broadcasts
+
+Revision 1.212 2008/10/14 21:52:18 cheshire
+Added support for putting/getting/printing kDNSType_MAC
+
+Revision 1.211 2008/10/09 22:36:08 cheshire
+Now that we have Sleep Proxy Server, can't suppress normal scheduling logic while going to sleep
+
+Revision 1.210 2008/10/08 01:03:52 cheshire
+Change GetFirstActiveInterface() so the NetworkInterfaceInfo it returns is not "const"
+Added mDNS_SetupQuestion() convenience function
+
+Revision 1.209 2008/09/23 04:13:30 cheshire
+<rdar://problem/6238774> Remove "local" from the end of _services._dns-sd._udp PTR records
+Removed old special-case Bonjour Browser hack that is no longer needed
+
+Revision 1.208 2008/09/23 02:33:56 cheshire
+<rdar://problem/4738033> uDNS: Should not compress SRV rdata in uDNS packets
+
+Revision 1.207 2008/09/23 02:30:07 cheshire
+Get rid of PutResourceRecordCappedTTL()
+
+Revision 1.206 2008/09/23 02:26:09 cheshire
+Don't need to export putEmptyResourceRecord (it's only used from DNSCommon.c)
+
+Revision 1.205 2008/09/23 02:21:00 cheshire
+Don't need to force setting of rrclass in PutResourceRecordTTLWithLimit() now that putLLQ() sets it correctly
+
+Revision 1.204 2008/08/29 19:03:05 cheshire
+<rdar://problem/6185645> Off-by-one error in putDomainNameAsLabels()
+
+Revision 1.203 2008/08/13 00:47:53 mcguire
+Handle failures when packet logging
+
+Revision 1.202 2008/08/13 00:32:48 mcguire
+refactor to use SwapDNSHeaderBytes instead of swapping manually
+
+Revision 1.201 2008/07/24 20:23:03 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+
+Revision 1.200 2008/07/18 00:07:50 cheshire
+<rdar://problem/5904999> Log a message for applications that register service types longer than 14 characters
Revision 1.199 2008/03/14 19:58:38 mcguire
<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
mDNSexport const mDNSv4Addr onesIPv4Addr = { { 255, 255, 255, 255 } };
mDNSexport const mDNSv6Addr onesIPv6Addr = { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } };
mDNSexport const mDNSAddr zeroAddr = { mDNSAddrType_None, {{{ 0 }}} };
+mDNSexport const mDNSEthAddr onesEthAddr = { { 255, 255, 255, 255, 255, 255 } };
+
+mDNSexport const OwnerOptData zeroOwner = { 0, 0, { { 0 } }, { { 0 } }, { { 0 } } };
mDNSexport const mDNSInterfaceID mDNSInterface_Any = 0;
mDNSexport const mDNSInterfaceID mDNSInterface_LocalOnly = (mDNSInterfaceID)1;
// Uncomment the appropriate lines below to build a special Multicast DNS responder for testing interoperability
// with Microsoft's LLMNR client code.
+#define DiscardPortAsNumber 9
+#define SSHPortAsNumber 22
+#define UnicastDNSPortAsNumber 53
#define SSDPPortAsNumber 1900
-
-#define UnicastDNSPortAsNumber 53
+#define NSIPCPortAsNumber 5030 // Port used for dnsextd to talk to local nameserver bound to loopback
#define NATPMPAnnouncementPortAsNumber 5350
#define NATPMPPortAsNumber 5351
#define DNSEXTPortAsNumber 5352 // Port used for end-to-end DNS operations like LLQ, Updates with Leases, etc.
#define MulticastDNSPortAsNumber 5353
#define LoopbackIPCPortAsNumber 5354
//#define MulticastDNSPortAsNumber 5355 // LLMNR
-
-#define NSIPCPortAsNumber 5030 // Port used for dnsextd to talk to local nameserver bound to loopback
#define PrivateDNSPortAsNumber 5533
-mDNSexport const mDNSIPPort SSDPPort = { { SSDPPortAsNumber >> 8, SSDPPortAsNumber & 0xFF } };
-
+mDNSexport const mDNSIPPort DiscardPort = { { DiscardPortAsNumber >> 8, DiscardPortAsNumber & 0xFF } };
+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 NSIPCPort = { { NSIPCPortAsNumber >> 8, NSIPCPortAsNumber & 0xFF } };
mDNSexport const mDNSIPPort NATPMPAnnouncementPort = { { NATPMPAnnouncementPortAsNumber >> 8, NATPMPAnnouncementPortAsNumber & 0xFF } };
mDNSexport const mDNSIPPort NATPMPPort = { { NATPMPPortAsNumber >> 8, NATPMPPortAsNumber & 0xFF } };
mDNSexport const mDNSIPPort DNSEXTPort = { { DNSEXTPortAsNumber >> 8, DNSEXTPortAsNumber & 0xFF } };
mDNSexport const mDNSIPPort MulticastDNSPort = { { MulticastDNSPortAsNumber >> 8, MulticastDNSPortAsNumber & 0xFF } };
mDNSexport const mDNSIPPort LoopbackIPCPort = { { LoopbackIPCPortAsNumber >> 8, LoopbackIPCPortAsNumber & 0xFF } };
-
-mDNSexport const mDNSIPPort NSIPCPort = { { NSIPCPortAsNumber >> 8, NSIPCPortAsNumber & 0xFF } };
mDNSexport const mDNSIPPort PrivateDNSPort = { { PrivateDNSPortAsNumber >> 8, PrivateDNSPortAsNumber & 0xFF } };
mDNSexport const mDNSv4Addr AllDNSAdminGroup = { { 239, 255, 255, 251 } };
+mDNSexport const mDNSv4Addr AllSystemsMcast = { { 224, 0, 0, 1 } }; // For NAT-PMP Annoucements
mDNSexport const mDNSAddr AllDNSLinkGroup_v4 = { mDNSAddrType_IPv4, { { { 224, 0, 0, 251 } } } };
//mDNSexport const mDNSAddr AllDNSLinkGroup_v4 = { mDNSAddrType_IPv4, { { { 224, 0, 0, 252 } } } }; // LLMNR
mDNSexport const mDNSAddr AllDNSLinkGroup_v6 = { mDNSAddrType_IPv6, { { { 0xFF,0x02,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFB } } } };
//mDNSexport const mDNSAddr AllDNSLinkGroup_v6 = { mDNSAddrType_IPv6, { { { 0xFF,0x02,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x01,0x00,0x03 } } } }; // LLMNR
mDNSexport const mDNSOpaque16 zeroID = { { 0, 0 } };
+mDNSexport const mDNSOpaque16 onesID = { { 255, 255 } };
mDNSexport const mDNSOpaque16 QueryFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery, 0 } };
mDNSexport const mDNSOpaque16 uQueryFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery | kDNSFlag0_RD, 0 } };
mDNSexport const mDNSOpaque16 ResponseFlags = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery | kDNSFlag0_AA, 0 } };
(addr->b[0] == 192 && addr->b[1] == 168)); // 192.168/16
}
-mDNSexport const NetworkInterfaceInfo *GetFirstActiveInterface(const NetworkInterfaceInfo *intf)
+mDNSexport NetworkInterfaceInfo *GetFirstActiveInterface(NetworkInterfaceInfo *intf)
{
while (intf && !intf->InterfaceActive) intf = intf->next;
return(intf);
{
mDNSu32 slot, used = 0;
CacheGroup *cg;
- CacheRecord *rr;
+ const CacheRecord *rr;
FORALL_CACHERECORDS(slot, cg, rr)
if (rr->resrec.InterfaceID == id) used++;
return(used);
case kDNSType_AAAA: return("AAAA");
case kDNSType_SRV: return("SRV");
case kDNSType_OPT: return("OPT");
+ case kDNSType_NSEC: return("NSEC");
case kDNSType_TSIG: return("TSIG");
case kDNSQType_ANY: return("ANY");
default: {
// Note slight bug: this code uses the rdlength from the ResourceRecord object, to display
// the rdata from the RDataBody object. Sometimes this could be the wrong length -- but as
// long as this routine is only used for debugging messages, it probably isn't a big problem.
-mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *rr, RDataBody *rd, char *buffer)
+mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RDataBody *const rd1, char *const buffer)
{
- #define Max (MaxMsg-1)
+ const RDataBody2 *const rd = (RDataBody2 *)rd1;
+ #define RemSpc (MaxMsg-1-length)
char *ptr = buffer;
- mDNSu32 length = mDNS_snprintf(buffer, Max, "%4d %##s %s ", rr->rdlength, rr->name->c, DNSTypeName(rr->rrtype));
+ mDNSu32 length = mDNS_snprintf(buffer, MaxMsg-1, "%4d %##s %s ", rr->rdlength, rr->name->c, DNSTypeName(rr->rrtype));
if (rr->RecordType == kDNSRecordTypePacketNegative) return(buffer);
- if (!rr->rdlength) { mDNS_snprintf(buffer+length, Max-length, "<< ZERO RDATA LENGTH >>"); return(buffer); }
+ if (!rr->rdlength) { mDNS_snprintf(buffer+length, RemSpc, "<< ZERO RDATA LENGTH >>"); return(buffer); }
switch (rr->rrtype)
{
- case kDNSType_A: mDNS_snprintf(buffer+length, Max-length, "%.4a", &rd->ipv4); break;
+ case kDNSType_A: mDNS_snprintf(buffer+length, RemSpc, "%.4a", &rd->ipv4); break;
case kDNSType_NS: // Same as PTR
case kDNSType_CNAME:// Same as PTR
- case kDNSType_PTR: mDNS_snprintf(buffer+length, Max-length, "%##s", rd->name.c); break;
+ case kDNSType_PTR: mDNS_snprintf(buffer+length, RemSpc, "%##s", rd->name.c); break;
- case kDNSType_SOA: mDNS_snprintf(buffer+length, Max-length, "%##s %##s %d %d %d %d %d",
+ case kDNSType_SOA: mDNS_snprintf(buffer+length, RemSpc, "%##s %##s %d %d %d %d %d",
rd->soa.mname.c, rd->soa.rname.c,
rd->soa.serial, rd->soa.refresh, rd->soa.retry, rd->soa.expire, rd->soa.min);
break;
case kDNSType_HINFO:// Display this the same as TXT (show all constituent strings)
case kDNSType_TXT: {
- mDNSu8 *t = rd->txt.c;
+ const mDNSu8 *t = rd->txt.c;
while (t < rd->txt.c + rr->rdlength)
{
- length += mDNS_snprintf(buffer+length, Max-length, "%s%#s", t > rd->txt.c ? "¦" : "", t);
+ length += mDNS_snprintf(buffer+length, RemSpc, "%s%#s", t > rd->txt.c ? "¦" : "", t);
t += 1 + t[0];
}
} break;
- case kDNSType_AAAA: mDNS_snprintf(buffer+length, Max-length, "%.16a", &rd->ipv6); break;
- case kDNSType_SRV: mDNS_snprintf(buffer+length, Max-length, "%u %u %u %##s",
+ case kDNSType_AAAA: mDNS_snprintf(buffer+length, RemSpc, "%.16a", &rd->ipv6); break;
+ case kDNSType_SRV: mDNS_snprintf(buffer+length, RemSpc, "%u %u %u %##s",
rd->srv.priority, rd->srv.weight, mDNSVal16(rd->srv.port), rd->srv.target.c); break;
- case kDNSType_OPT: length += mDNS_snprintf(buffer+length, Max-length, "%d Len %d ", rd->opt.opt, rd->opt.optlen);
- length += mDNS_snprintf(buffer+length, Max-length, "Max UDP %d ", rr->rrclass);
- if (rd->opt.opt == kDNSOpt_LLQ)
+
+ case kDNSType_OPT: {
+ const rdataOPT *opt;
+ const rdataOPT *const end = (const rdataOPT *)&rd->data[rr->rdlength];
+ length += mDNS_snprintf(buffer+length, RemSpc, "Max %d", rr->rrclass);
+ for (opt = &rd->opt[0]; opt < end; opt++)
{
- length += mDNS_snprintf(buffer+length, Max-length, "Vers %d ", rd->opt.OptData.llq.vers);
- length += mDNS_snprintf(buffer+length, Max-length, "Op %d ", rd->opt.OptData.llq.llqOp);
- length += mDNS_snprintf(buffer+length, Max-length, "Err/Port %d ", rd->opt.OptData.llq.err);
- length += mDNS_snprintf(buffer+length, Max-length, "ID %08X%08X ", rd->opt.OptData.llq.id.l[0], rd->opt.OptData.llq.id.l[1]);
- length += mDNS_snprintf(buffer+length, Max-length, "Lease %d", rd->opt.OptData.llq.llqlease);
+ switch(opt->opt)
+ {
+ case kDNSOpt_LLQ:
+ length += mDNS_snprintf(buffer+length, RemSpc, " Vers %d", opt->u.llq.vers);
+ length += mDNS_snprintf(buffer+length, RemSpc, " Op %d", opt->u.llq.llqOp);
+ length += mDNS_snprintf(buffer+length, RemSpc, " Err/Port %d", opt->u.llq.err);
+ length += mDNS_snprintf(buffer+length, RemSpc, " ID %08X%08X", opt->u.llq.id.l[0], opt->u.llq.id.l[1]);
+ length += mDNS_snprintf(buffer+length, RemSpc, " Lease %d", opt->u.llq.llqlease);
+ break;
+ case kDNSOpt_Lease:
+ length += mDNS_snprintf(buffer+length, RemSpc, " Lease %d", opt->u.updatelease);
+ break;
+ case kDNSOpt_Owner:
+ length += mDNS_snprintf(buffer+length, RemSpc, " Vers %d", opt->u.owner.vers);
+ length += mDNS_snprintf(buffer+length, RemSpc, " Seq %3d", (mDNSu8)opt->u.owner.seq); // Display as unsigned
+ length += mDNS_snprintf(buffer+length, RemSpc, " MAC %.6a", opt->u.owner.HMAC.b);
+ if (opt->optlen >= DNSOpt_OwnerData_ID_Wake_Space-4)
+ {
+ length += mDNS_snprintf(buffer+length, RemSpc, " I-MAC %.6a", opt->u.owner.IMAC.b);
+ if (opt->optlen > DNSOpt_OwnerData_ID_Wake_Space-4)
+ length += mDNS_snprintf(buffer+length, RemSpc, " Password %.6a", opt->u.owner.password.b);
+ }
+ break;
+ default:
+ length += mDNS_snprintf(buffer+length, RemSpc, " Unknown %d", opt->opt);
+ break;
+ }
}
- else if (rd->opt.opt == kDNSOpt_Lease)
- length += mDNS_snprintf(buffer+length, Max-length, "kDNSOpt_Lease Lease %d", rd->opt.OptData.updatelease);
- else
- length += mDNS_snprintf(buffer+length, Max-length, "Unknown opt %d", rd->opt.opt);
+ }
break;
- default: mDNS_snprintf(buffer+length, Max-length, "RDLen %d: %s", rr->rdlength, rd->data);
+
+ case kDNSType_NSEC: {
+ int i;
+ for (i=0; i<255; i++)
+ if (rd->nsec.bitmap[i>>3] & (128 >> (i&7)))
+ length += mDNS_snprintf(buffer+length, RemSpc, "%s ", DNSTypeName(i));
+ }
+ break;
+
+ default: mDNS_snprintf(buffer+length, RemSpc, "RDLen %d: %s", rr->rdlength, rd->data);
// Really should scan buffer to check if text is valid UTF-8 and only replace with dots if not
for (ptr = buffer; *ptr; ptr++) if (*ptr < ' ') *ptr = '.';
break;
return(buffer);
}
-// Long-term we need to make this cross-platform, either by using our own embedded RC4 code
-// to generate the pseudo-random sequence, or by adding another mDNSPlatformXXX() call.
-// The former would be preferable because it makes our code self-contained, so it will run anywhere.
-// The latter is less desirable because it increases the burden on people writing platform support layers
-// to now implement one more function (and an important one at that, that needs to be cryptographically strong).
-// For now, as a temporary fix, if we're building mDNSResponder for OS X we just use arc4random() directly here.
+// See comments in mDNSEmbeddedAPI.h
+#if _PLATFORM_HAS_STRONG_PRNG_
+#define mDNSRandomNumber mDNSPlatformRandomNumber
+#else
+mDNSlocal mDNSu32 mDNSRandomFromSeed(mDNSu32 seed)
+ {
+ return seed * 21 + 1;
+ }
-#if _BUILDING_XCODE_PROJECT_
-#include <stdlib.h>
-#endif
+mDNSlocal mDNSu32 mDNSMixRandomSeed(mDNSu32 seed, mDNSu8 iteration)
+ {
+ return iteration ? mDNSMixRandomSeed(mDNSRandomFromSeed(seed), --iteration) : seed;
+ }
-mDNSexport mDNSu32 mDNSRandom(mDNSu32 max) // Returns pseudo-random result from zero to max inclusive
+mDNSlocal mDNSu32 mDNSRandomNumber()
{
+ static mDNSBool seeded = mDNSfalse;
static mDNSu32 seed = 0;
- mDNSu32 mask = 1;
-
- if (!seed)
+ if (!seeded)
{
- int i;
- seed = mDNSPlatformRandomSeed(); // Pick an initial seed
- for (i=0; i<100; i++) seed = seed * 21 + 1; // And mix it up a bit
+ seed = mDNSMixRandomSeed(mDNSPlatformRandomSeed(), 100);
+ seeded = mDNStrue;
}
- while (mask < max) mask = (mask << 1) | 1;
-
-#if _BUILDING_XCODE_PROJECT_
- do seed = arc4random();
-#else
- do seed = seed * 21 + 1;
-#endif
- while ((seed & mask) > max);
-
- return (seed & mask);
+ return (seed = mDNSRandomFromSeed(seed));
}
-
-mDNSexport mDNSu32 mDNSRandomFromFixedSeed(mDNSu32 seed, mDNSu32 max)
+#endif // ! _PLATFORM_HAS_STRONG_PRNG_
+
+mDNSexport mDNSu32 mDNSRandom(mDNSu32 max) // Returns pseudo-random result from zero to max inclusive
{
+ mDNSu32 ret = 0;
mDNSu32 mask = 1;
+
while (mask < max) mask = (mask << 1) | 1;
- do seed = seed * 21 + 1; while ((seed & mask) > max);
- return (seed & mask);
+
+ do ret = mDNSRandomNumber() & mask;
+ while (ret > max);
+
+ return ret;
}
mDNSexport mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2)
while (*a || *b)
{
if (a + 1 + *a >= max)
- { debugf("Malformed domain name (more than 255 characters)"); return(mDNSfalse); }
+ { debugf("Malformed domain name (more than 256 characters)"); return(mDNSfalse); }
if (!SameDomainLabel(a, b)) return(mDNSfalse);
a += 1 + *a;
b += 1 + *b;
return(mDNSfalse);
}
+mDNSexport const mDNSu8 *LastLabel(const domainname *d)
+ {
+ const mDNSu8 *p = d->c;
+ while (d->c[0])
+ {
+ p = d->c;
+ d = (const domainname*)(d->c + 1 + d->c[0]);
+ }
+ return(p);
+ }
+
// Returns length of a domain name INCLUDING the byte for the final null label
// e.g. for the root label "." it returns one
// For the FQDN "com." it returns 5 (length byte, three data bytes, final zero)
-// Legal results are 1 (just root label) to 255 (MAX_DOMAIN_NAME)
-// If the given domainname is invalid, result is 256 (MAX_DOMAIN_NAME+1)
+// Legal results are 1 (just root label) to 256 (MAX_DOMAIN_NAME)
+// If the given domainname is invalid, result is 257 (MAX_DOMAIN_NAME+1)
mDNSexport mDNSu16 DomainNameLengthLimit(const domainname *const name, const mDNSu8 *limit)
{
const mDNSu8 *src = name->c;
// Any dots in the name are literal dots, not label separators
// If successful, AppendLiteralLabelString returns a pointer to the next unused byte
// in the domainname bufer (i.e. the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
+// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 256 bytes)
// AppendLiteralLabelString returns mDNSNULL.
mDNSexport mDNSu8 *AppendLiteralLabelString(domainname *const name, const char *cstr)
{
// Textual labels, escaped as necessary using the usual DNS '\' notation, separated by dots.
// If successful, AppendDNSNameString returns a pointer to the next unused byte
// in the domainname bufer (i.e. the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
+// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 256 bytes)
// AppendDNSNameString returns mDNSNULL.
mDNSexport mDNSu8 *AppendDNSNameString(domainname *const name, const char *cstring)
{
if (c == '\\') // If escape character, check next character
{
c = (mDNSu8)*cstr++; // Assume we'll just take the next character
- if (mdnsIsDigit(cstr[-1]) && mdnsIsDigit(cstr[0]) && mdnsIsDigit(cstr[1]))
+ if (mDNSIsDigit(cstr[-1]) && mDNSIsDigit(cstr[0]) && mDNSIsDigit(cstr[1]))
{ // If three decimal digits,
int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
int v1 = cstr[ 0] - '0';
// AppendDomainLabel appends a single label to a name.
// If successful, AppendDomainLabel returns a pointer to the next unused byte
// in the domainname bufer (i.e. the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
+// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 256 bytes)
// AppendDomainLabel returns mDNSNULL.
mDNSexport mDNSu8 *AppendDomainLabel(domainname *const name, const domainlabel *const label)
{
// Textual labels, escaped as necessary using the usual DNS '\' notation, separated by dots.
// If successful, MakeDomainNameFromDNSNameString returns a pointer to the next unused byte
// in the domainname bufer (i.e. the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
+// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 256 bytes)
// MakeDomainNameFromDNSNameString returns mDNSNULL.
mDNSexport mDNSu8 *MakeDomainNameFromDNSNameString(domainname *const name, const char *cstr)
{
return(ptr); // and return
}
-// Note: To guarantee that there will be no possible overrun, cstr must be at least MAX_ESCAPED_DOMAIN_NAME (1005 bytes)
+// Note: To guarantee that there will be no possible overrun, cstr must be at least MAX_ESCAPED_DOMAIN_NAME (1009 bytes)
mDNSexport char *ConvertDomainNameToCString_withescape(const domainname *const name, char *ptr, char esc)
{
- const mDNSu8 *src = name->c; // Domain name we're reading
+ const mDNSu8 *src = name->c; // Domain name we're reading
const mDNSu8 *const max = name->c + MAX_DOMAIN_NAME; // Maximum that's valid
if (*src == 0) *ptr++ = '.'; // Special case: For root, just write a dot
{ src += 3; continue; } // Unicode curly apostrophe
if (ptr < lim)
{
- if (mdnsValidHostChar(*src, (ptr > &hostlabel->c[1]), (src < end-1))) *ptr++ = *src;
+ if (mDNSValidHostChar(*src, (ptr > &hostlabel->c[1]), (src < end-1))) *ptr++ = *src;
else if (ptr > &hostlabel->c[1] && ptr[-1] != '-') *ptr++ = '-';
}
src++;
mDNSu8 *dst = fqdn->c;
const mDNSu8 *src;
const char *errormsg;
+#if APPLE_OSX_mDNSResponder
+ mDNSBool loggedUnderscore = mDNSfalse;
+ static char typeBuf[MAX_ESCAPED_DOMAIN_NAME];
+#endif
// In the case where there is no name (and ONLY in that case),
// a single-label subtype is allowed as the first label of a three-part "type"
src = type->c; // Put the service type into the domain name
len = *src;
- if (len < 2 || len >= 0x40 || (len > 15 && !SameDomainName(domain, &localdomain)))
+ if (len < 2 || len > 15)
{
- errormsg = "Application protocol name must be underscore plus 1-14 characters. See <http://www.dns-sd.org/ServiceTypes.html>";
- goto fail;
+ LogMsg("Bad service type in %#s.%##s%##s Application protocol name must be underscore plus 1-14 characters. "
+ "See <http://www.dns-sd.org/ServiceTypes.html>", name->c, type->c, domain->c);
+#if APPLE_OSX_mDNSResponder
+ ConvertDomainNameToCString(type, typeBuf);
+ mDNSASLLog(mDNSNULL, "serviceType.nameTooLong", "noop", typeBuf, "");
+#endif
}
+ if (len < 2 || len >= 0x40 || (len > 15 && !SameDomainName(domain, &localdomain))) return(mDNSNULL);
if (src[1] != '_') { errormsg = "Application protocol name must begin with underscore"; goto fail; }
for (i=2; i<=len; i++)
{
// Letters and digits are allowed anywhere
- if (mdnsIsLetter(src[i]) || mdnsIsDigit(src[i])) continue;
+ if (mDNSIsLetter(src[i]) || mDNSIsDigit(src[i])) continue;
// Hyphens are only allowed as interior characters
// Underscores are not supposed to be allowed at all, but for backwards compatibility with some old products we do allow them,
// with the same rule as hyphens
- if ((src[i] == '-' || src[i] == '_') && i > 2 && i < len) continue;
- errormsg = "Application protocol name must contain only letters, digits, and hyphens"; goto fail;
+ if ((src[i] == '-' || src[i] == '_') && i > 2 && i < len)
+ {
+#if APPLE_OSX_mDNSResponder
+ if (src[i] == '_' && loggedUnderscore == mDNSfalse)
+ {
+ ConvertDomainNameToCString(type, typeBuf);
+ mDNSASLLog(mDNSNULL, "serviceType.nameWithUnderscore", "noop", typeBuf, "");
+ loggedUnderscore = mDNStrue;
+ }
+#endif
+ continue;
+ }
+ errormsg = "Application protocol name must contain only letters, digits, and hyphens";
+#if APPLE_OSX_mDNSResponder
+ {
+ ConvertDomainNameToCString(type, typeBuf);
+ mDNSASLLog(mDNSNULL, "serviceType.nameWithIllegalCharacters", "noop", typeBuf, "");
+ }
+#endif
+ goto fail;
}
for (i=0; i<=len; i++) *dst++ = *src++;
len = *src;
if (!len) { debugf("DeconstructServiceName: FQDN contains only two labels!"); return(mDNSfalse); }
- // Can't do this check right now, until Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
- //if (!ValidTransportProtocol(src))
- // { debugf("DeconstructServiceName: Transport protocol must be _udp or _tcp"); return(mDNSfalse); }
+ if (!ValidTransportProtocol(src))
+ { debugf("DeconstructServiceName: Transport protocol must be _udp or _tcp"); return(mDNSfalse); }
for (i=0; i<=len; i++) *dst++ = *src++;
*dst++ = 0; // Put terminator on the end of service type
{
if (l < 4) return mDNSfalse; // Need at least " (2)"
if (name->c[l--] != ')') return mDNSfalse; // Last char must be ')'
- if (!mdnsIsDigit(name->c[l])) return mDNSfalse; // Preceeded by a digit
+ if (!mDNSIsDigit(name->c[l])) return mDNSfalse; // Preceeded by a digit
l--;
- while (l > 2 && mdnsIsDigit(name->c[l])) l--; // Strip off digits
+ while (l > 2 && mDNSIsDigit(name->c[l])) l--; // Strip off digits
return (name->c[l] == '(' && name->c[l - 1] == ' ');
}
else
{
if (l < 2) return mDNSfalse; // Need at least "-2"
- if (!mdnsIsDigit(name->c[l])) return mDNSfalse; // Last char must be a digit
+ if (!mDNSIsDigit(name->c[l])) return mDNSfalse; // Last char must be a digit
l--;
- while (l > 2 && mdnsIsDigit(name->c[l])) l--; // Strip off digits
+ while (l > 2 && mDNSIsDigit(name->c[l])) l--; // Strip off digits
return (name->c[l] == '-');
}
}
if (RichText && name->c[0] >= 1 && name->c[name->c[0]] == ')') name->c[0]--;
// Get any existing numerical suffix off the name
- while (mdnsIsDigit(name->c[name->c[0]]))
+ while (mDNSIsDigit(name->c[name->c[0]]))
{ val += (name->c[name->c[0]] - '0') * multiplier; multiplier *= 10; name->c[0]--; }
// Chop opening parentheses or dash from suffix
rr->AllowRemoteQuery = mDNSfalse;
rr->ForceMCast = mDNSfalse;
+ rr->WakeUp = zeroOwner;
+ rr->AddressProxy = zeroAddr;
+ rr->TimeRcvd = 0;
+ rr->TimeExpire = 0;
+
// Field Group 3: Transient state for Authoritative Records (set in mDNS_Register_internal)
// Field Group 4: Transient uDNS state for Authoritative Records (set in mDNS_Register_internal)
rr->uselease = 0;
rr->expire = 0;
rr->Private = 0;
- rr->id = zeroID;
- rr->zone.c[0] = 0;
+ rr->updateid = zeroID;
+ rr->zone = rr->resrec.name;
rr->UpdateServer = zeroAddr;
rr->UpdatePort = zeroIPPort;
rr->nta = mDNSNULL;
rr->namestorage.c[0] = 0; // MUST be set by client before calling mDNS_Register()
}
+mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID InterfaceID, const domainname *const name,
+ const mDNSu16 qtype, mDNSQuestionCallback *const callback, void *const context)
+ {
+ q->InterfaceID = InterfaceID;
+ q->Target = zeroAddr;
+ AssignDomainName(&q->qname, name);
+ q->qtype = qtype;
+ q->qclass = kDNSClass_IN;
+ q->LongLived = (qtype == kDNSType_PTR);
+ q->ExpectUnique = (qtype != kDNSType_PTR);
+ q->ForceMCast = mDNSfalse;
+ q->ReturnIntermed = mDNSfalse;
+ q->QuestionCallback = callback;
+ q->QuestionContext = context;
+ }
+
mDNSexport mDNSu32 RDataHashValue(const ResourceRecord *const rr)
{
+ int len = rr->rdlength;
+ const RDataBody2 *const rdb = (RDataBody2 *)rr->rdata->u.data;
switch(rr->rrtype)
{
case kDNSType_NS:
case kDNSType_CNAME:
case kDNSType_PTR:
- case kDNSType_DNAME: return DomainNameHashValue(&rr->rdata->u.name);
+ case kDNSType_DNAME: return DomainNameHashValue(&rdb->name);
- case kDNSType_SOA: return rr->rdata->u.soa.serial +
- rr->rdata->u.soa.refresh +
- rr->rdata->u.soa.retry +
- rr->rdata->u.soa.expire +
- rr->rdata->u.soa.min +
- DomainNameHashValue(&rr->rdata->u.soa.mname) +
- DomainNameHashValue(&rr->rdata->u.soa.rname);
+ case kDNSType_SOA: return rdb->soa.serial +
+ rdb->soa.refresh +
+ rdb->soa.retry +
+ rdb->soa.expire +
+ rdb->soa.min +
+ DomainNameHashValue(&rdb->soa.mname) +
+ DomainNameHashValue(&rdb->soa.rname);
case kDNSType_MX:
case kDNSType_AFSDB:
case kDNSType_RT:
- case kDNSType_KX: return DomainNameHashValue(&rr->rdata->u.mx.exchange);
+ case kDNSType_KX: return DomainNameHashValue(&rdb->mx.exchange);
+
+ case kDNSType_RP: return DomainNameHashValue(&rdb->rp.mbox) + DomainNameHashValue(&rdb->rp.txt);
- case kDNSType_RP: return DomainNameHashValue(&rr->rdata->u.rp.mbox) + DomainNameHashValue(&rr->rdata->u.rp.txt);
+ case kDNSType_PX: return DomainNameHashValue(&rdb->px.map822) + DomainNameHashValue(&rdb->px.mapx400);
- case kDNSType_PX: return DomainNameHashValue(&rr->rdata->u.px.map822) + DomainNameHashValue(&rr->rdata->u.px.mapx400);
+ case kDNSType_SRV: return DomainNameHashValue(&rdb->srv.target);
- case kDNSType_SRV: return DomainNameHashValue(&rr->rdata->u.srv.target);
+ case kDNSType_OPT: return 0; // OPT is a pseudo-RR container structure; makes no sense to compare
- case kDNSType_OPT: // Okay to use blind memory sum because there are no 'holes' in the in-memory representation
+ case kDNSType_NSEC: len = sizeof(rdataNSEC); // Use in-memory length of 32, and fall through default checksum computation below
default:
{
mDNSu32 sum = 0;
int i;
- for (i=0; i+1 < rr->rdlength; i+=2)
+ for (i=0; i+1 < len; i+=2)
{
- sum += (((mDNSu32)(rr->rdata->u.data[i])) << 8) | rr->rdata->u.data[i+1];
+ sum += (((mDNSu32)(rdb->data[i])) << 8) | rdb->data[i+1];
sum = (sum<<3) | (sum>>29);
}
- if (i < rr->rdlength)
+ if (i < len)
{
- sum += ((mDNSu32)(rr->rdata->u.data[i])) << 8;
+ sum += ((mDNSu32)(rdb->data[i])) << 8;
}
return(sum);
}
// r2 is just a bare RDataBody, which MUST be the same rrtype and rdlength as r1
mDNSexport mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2)
{
+ const RDataBody2 *const b1 = (RDataBody2 *)r1->rdata->u.data;
+ const RDataBody2 *const b2 = (RDataBody2 *)r2;
switch(r1->rrtype)
{
case kDNSType_NS:
case kDNSType_CNAME:
case kDNSType_PTR:
- case kDNSType_DNAME:return(SameDomainName(&r1->rdata->u.name, &r2->name));
+ case kDNSType_DNAME:return(SameDomainName(&b1->name, &b2->name));
- case kDNSType_SOA: return(mDNSBool)( r1->rdata->u.soa.serial == r2->soa.serial &&
- r1->rdata->u.soa.refresh == r2->soa.refresh &&
- r1->rdata->u.soa.retry == r2->soa.retry &&
- r1->rdata->u.soa.expire == r2->soa.expire &&
- r1->rdata->u.soa.min == r2->soa.min &&
- SameDomainName(&r1->rdata->u.soa.mname, &r2->soa.mname) &&
- SameDomainName(&r1->rdata->u.soa.rname, &r2->soa.rname));
+ case kDNSType_SOA: return(mDNSBool)( b1->soa.serial == b2->soa.serial &&
+ b1->soa.refresh == b2->soa.refresh &&
+ b1->soa.retry == b2->soa.retry &&
+ b1->soa.expire == b2->soa.expire &&
+ b1->soa.min == b2->soa.min &&
+ SameDomainName(&b1->soa.mname, &b2->soa.mname) &&
+ SameDomainName(&b1->soa.rname, &b2->soa.rname));
case kDNSType_MX:
case kDNSType_AFSDB:
case kDNSType_RT:
- case kDNSType_KX: return(mDNSBool)( r1->rdata->u.mx.preference == r2->mx.preference &&
- SameDomainName(&r1->rdata->u.mx.exchange, &r2->mx.exchange));
+ case kDNSType_KX: return(mDNSBool)( b1->mx.preference == b2->mx.preference &&
+ SameDomainName(&b1->mx.exchange, &b2->mx.exchange));
- case kDNSType_RP: return(mDNSBool)( SameDomainName(&r1->rdata->u.rp.mbox, &r2->rp.mbox) &&
- SameDomainName(&r1->rdata->u.rp.txt, &r2->rp.txt));
+ case kDNSType_RP: return(mDNSBool)( SameDomainName(&b1->rp.mbox, &b2->rp.mbox) &&
+ SameDomainName(&b1->rp.txt, &b2->rp.txt));
- case kDNSType_PX: return(mDNSBool)( r1->rdata->u.px.preference == r2->px.preference &&
- SameDomainName(&r1->rdata->u.px.map822, &r2->px.map822) &&
- SameDomainName(&r1->rdata->u.px.mapx400, &r2->px.mapx400));
+ case kDNSType_PX: return(mDNSBool)( b1->px.preference == b2->px.preference &&
+ SameDomainName(&b1->px.map822, &b2->px.map822) &&
+ SameDomainName(&b1->px.mapx400, &b2->px.mapx400));
- case kDNSType_SRV: return(mDNSBool)( r1->rdata->u.srv.priority == r2->srv.priority &&
- r1->rdata->u.srv.weight == r2->srv.weight &&
- mDNSSameIPPort(r1->rdata->u.srv.port, r2->srv.port) &&
- SameDomainName(&r1->rdata->u.srv.target, &r2->srv.target));
+ case kDNSType_SRV: return(mDNSBool)( b1->srv.priority == b2->srv.priority &&
+ b1->srv.weight == b2->srv.weight &&
+ mDNSSameIPPort(b1->srv.port, b2->srv.port) &&
+ SameDomainName(&b1->srv.target, &b2->srv.target));
- case kDNSType_OPT: // Okay to use blind memory compare because there are no 'holes' in the in-memory representation
+ case kDNSType_OPT: return mDNSfalse; // OPT is a pseudo-RR container structure; makes no sense to compare
- default: return(mDNSPlatformMemSame(r1->rdata->u.data, r2->data, r1->rdlength));
+ case kDNSType_NSEC: return(mDNSPlatformMemSame(b1->data, b2->data, sizeof(rdataNSEC)));
+
+ default: return(mDNSPlatformMemSame(b1->data, b2->data, r1->rdlength));
}
}
if (rr->InterfaceID && !mDNSOpaque16IsZero(q->TargetQID)) return(mDNSfalse);
// RR type CNAME matches any query type. QTYPE ANY matches any RR type. QCLASS ANY matches any RR class.
- if (rr->rrtype != kDNSType_CNAME && rr->rrtype != q->qtype && q->qtype != kDNSQType_ANY ) return(mDNSfalse);
- if ( rr->rrclass != q->qclass && q->qclass != kDNSQClass_ANY) return(mDNSfalse);
+ if (!RRTypeAnswersQuestionType(rr,q->qtype)) return(mDNSfalse);
+ if (rr->rrclass != q->qclass && q->qclass != kDNSQClass_ANY) return(mDNSfalse);
return(mDNStrue);
}
if (rr->InterfaceID && !mDNSOpaque16IsZero(q->TargetQID)) return(mDNSfalse);
// RR type CNAME matches any query type. QTYPE ANY matches any RR type. QCLASS ANY matches any RR class.
- if (rr->rrtype != kDNSType_CNAME && rr->rrtype != q->qtype && q->qtype != kDNSQType_ANY ) return(mDNSfalse);
- if ( rr->rrclass != q->qclass && q->qclass != kDNSQClass_ANY) return(mDNSfalse);
+ if (!RRTypeAnswersQuestionType(rr,q->qtype)) return(mDNSfalse);
+ if (rr->rrclass != q->qclass && q->qclass != kDNSQClass_ANY) return(mDNSfalse);
+
+ return(rr->namehash == q->qnamehash && SameDomainName(rr->name, &q->qname));
+ }
+
+mDNSexport mDNSBool AnyTypeRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
+ {
+ if (rr->InterfaceID &&
+ q ->InterfaceID && q->InterfaceID != mDNSInterface_LocalOnly &&
+ rr->InterfaceID != q->InterfaceID) return(mDNSfalse);
+
+ // If ResourceRecord received via multicast, but question was unicast, then shouldn't use record to answer this question
+ if (rr->InterfaceID && !mDNSOpaque16IsZero(q->TargetQID)) return(mDNSfalse);
+
+ if (rr->rrclass != q->qclass && q->qclass != kDNSQClass_ANY) return(mDNSfalse);
+
return(rr->namehash == q->qnamehash && SameDomainName(rr->name, &q->qname));
}
mDNSexport mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate)
{
- const RDataBody *rd = &rr->rdata->u;
+ const RDataBody2 *const rd = (RDataBody2 *)rr->rdata->u.data;
const domainname *const name = estimate ? rr->name : mDNSNULL;
if (rr->rrclass == kDNSQClass_ANY) return(rr->rdlength); // Used in update packets to mean "Delete An RRset" (RFC 2136)
else switch (rr->rrtype)
case kDNSType_OPT: return(rr->rdlength);
+ case kDNSType_NSEC: {
+ int i;
+ for (i=sizeof(rdataNSEC); i>0; i--) if (rd->nsec.bitmap[i-1]) break;
+ // For our simplified use of NSEC synthetic records:
+ // nextname is always the record's own name,
+ // the block number is always 0,
+ // the count byte is a value in the range 1-32,
+ // followed by the 1-32 data bytes
+ return((estimate ? 1 : DomainNameLength(rr->name)) + 2 + i);
+ }
+
default: debugf("Warning! Don't know how to get length of resource type %d", rr->rrtype);
return(rr->rdlength);
}
}
+// When a local client registers (or updates) a record, we use this routine to do some simple validation checks
+// to help reduce the risk of bogus malformed data on the network
mDNSexport mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd)
{
mDNSu16 len;
len = DomainNameLengthLimit(&rd->u.srv.target, rd->u.data + rdlength);
return(len <= MAX_DOMAIN_NAME && rdlength == 6+len);
+ //case kDNSType_NSEC not checked
+
default: return(mDNStrue); // Allow all other types without checking
}
}
const mDNSu8 * pointer = mDNSNULL;
const mDNSu8 *const searchlimit = ptr;
- if (!ptr) { LogMsg("putDomainNameAsLabels ptr is null"); return(mDNSNULL); }
+ if (!ptr) { LogMsg("putDomainNameAsLabels %##s ptr is null", name->c); return(mDNSNULL); }
- while (*np && ptr < limit-1) // While we've got characters in the name, and space to write them in the message...
+ if (!*np) // If just writing one-byte root label, make sure we have space for that
{
- if (*np > MAX_DOMAIN_LABEL)
- { LogMsg("Malformed domain name %##s (label more than 63 bytes)", name->c); return(mDNSNULL); }
-
- // This check correctly allows for the final trailing root label:
- // e.g.
- // Suppose our domain name is exactly 255 bytes long, including the final trailing root label.
- // Suppose np is now at name->c[248], and we're about to write our last non-null label ("local").
- // We know that max will be at name->c[255]
- // That means that np + 1 + 5 == max - 1, so we (just) pass the "if" test below, write our
- // six bytes, then exit the loop, write the final terminating root label, and the domain
- // name we've written is exactly 255 bytes long, exactly at the correct legal limit.
- // If the name is one byte longer, then we fail the "if" test below, and correctly bail out.
- if (np + 1 + *np >= max)
- { LogMsg("Malformed domain name %##s (more than 255 bytes)", name->c); return(mDNSNULL); }
-
- if (base) pointer = FindCompressionPointer(base, searchlimit, np);
- if (pointer) // Use a compression pointer if we can
- {
- mDNSu16 offset = (mDNSu16)(pointer - base);
- *ptr++ = (mDNSu8)(0xC0 | (offset >> 8));
- *ptr++ = (mDNSu8)( offset & 0xFF);
- return(ptr);
- }
- else // Else copy one label and try again
- {
- int i;
- mDNSu8 len = *np++;
- if (ptr + 1 + len >= limit) return(mDNSNULL);
- *ptr++ = len;
- for (i=0; i<len; i++) *ptr++ = *np++;
- }
+ if (ptr >= limit) return(mDNSNULL);
}
-
- if (ptr < limit) // If we didn't run out of space
+ else // else, loop through writing labels and/or a compression offset
{
- *ptr++ = 0; // Put the final root label
- return(ptr); // and return
+ do {
+ if (*np > MAX_DOMAIN_LABEL)
+ { LogMsg("Malformed domain name %##s (label more than 63 bytes)", name->c); return(mDNSNULL); }
+
+ // This check correctly allows for the final trailing root label:
+ // e.g.
+ // Suppose our domain name is exactly 256 bytes long, including the final trailing root label.
+ // Suppose np is now at name->c[249], and we're about to write our last non-null label ("local").
+ // We know that max will be at name->c[256]
+ // That means that np + 1 + 5 == max - 1, so we (just) pass the "if" test below, write our
+ // six bytes, then exit the loop, write the final terminating root label, and the domain
+ // name we've written is exactly 256 bytes long, exactly at the correct legal limit.
+ // If the name is one byte longer, then we fail the "if" test below, and correctly bail out.
+ if (np + 1 + *np >= max)
+ { LogMsg("Malformed domain name %##s (more than 256 bytes)", name->c); return(mDNSNULL); }
+
+ if (base) pointer = FindCompressionPointer(base, searchlimit, np);
+ if (pointer) // Use a compression pointer if we can
+ {
+ const mDNSu16 offset = (mDNSu16)(pointer - base);
+ if (ptr+2 > limit) return(mDNSNULL); // If we don't have two bytes of space left, give up
+ *ptr++ = (mDNSu8)(0xC0 | (offset >> 8));
+ *ptr++ = (mDNSu8)( offset & 0xFF);
+ return(ptr);
+ }
+ else // Else copy one label and try again
+ {
+ int i;
+ mDNSu8 len = *np++;
+ // If we don't at least have enough space for this label *plus* a terminating zero on the end, give up
+ if (ptr + 1 + len >= limit) return(mDNSNULL);
+ *ptr++ = len;
+ for (i=0; i<len; i++) *ptr++ = *np++;
+ }
+ } while (*np); // While we've got characters remaining in the name, continue
}
- return(mDNSNULL);
+ *ptr++ = 0; // Put the final root label
+ return(ptr);
}
mDNSlocal mDNSu8 *putVal16(mDNSu8 *ptr, mDNSu16 val)
return ptr + sizeof(mDNSu32);
}
-mDNSlocal mDNSu8 *putOptRData(mDNSu8 *ptr, const mDNSu8 *limit, const ResourceRecord *const rr)
- {
- int nput = 0;
- rdataOPT *opt;
-
- while (nput < rr->rdlength)
- {
- // check if space for opt/optlen
- if (ptr + (2 * sizeof(mDNSu16)) > limit) goto space_err;
- opt = (rdataOPT *)(rr->rdata->u.data + nput);
- ptr = putVal16(ptr, opt->opt);
- ptr = putVal16(ptr, opt->optlen);
- nput += 2 * sizeof(mDNSu16);
- if (opt->opt == kDNSOpt_LLQ)
- {
- if (ptr + LLQ_OPTLEN > limit) goto space_err;
- ptr = putVal16(ptr, opt->OptData.llq.vers);
- ptr = putVal16(ptr, opt->OptData.llq.llqOp);
- ptr = putVal16(ptr, opt->OptData.llq.err);
- mDNSPlatformMemCopy(ptr, opt->OptData.llq.id.b, 8); // 8-byte id
- ptr += 8;
- ptr = putVal32(ptr, opt->OptData.llq.llqlease);
- nput += LLQ_OPTLEN;
- }
- else if (opt->opt == kDNSOpt_Lease)
- {
- if (ptr + sizeof(mDNSs32) > limit) goto space_err;
- ptr = putVal32(ptr, opt->OptData.updatelease);
- nput += sizeof(mDNSs32);
- }
- else { LogMsg("putOptRData - unknown option %d", opt->opt); return mDNSNULL; }
- }
-
- return ptr;
-
- space_err:
- LogMsg("ERROR: putOptRData - out of space");
- return mDNSNULL;
- }
-
-mDNSlocal mDNSu16 getVal16(const mDNSu8 **ptr)
- {
- mDNSu16 val = (mDNSu16)(((mDNSu16)(*ptr)[0]) << 8 | (*ptr)[1]);
- *ptr += sizeof(mDNSOpaque16);
- return val;
- }
-
-mDNSlocal const mDNSu8 *getOptRdata(const mDNSu8 *ptr, const mDNSu8 *const limit, LargeCacheRecord *const cr, mDNSu16 pktRDLen)
- {
- int nread = 0;
- ResourceRecord *const rr = &cr->r.resrec;
- rdataOPT *opt = (rdataOPT *)rr->rdata->u.data;
-
- while (nread < pktRDLen && (mDNSu8 *)opt < rr->rdata->u.data + MaximumRDSize - sizeof(rdataOPT))
- {
- // space for opt + optlen
- if (nread + (2 * sizeof(mDNSu16)) > rr->rdata->MaxRDLength) goto space_err;
- opt->opt = getVal16(&ptr);
- opt->optlen = getVal16(&ptr);
- nread += 2 * sizeof(mDNSu16);
- if (opt->opt == kDNSOpt_LLQ)
- {
- if ((unsigned)(limit - ptr) < LLQ_OPTLEN) goto space_err;
- opt->OptData.llq.vers = getVal16(&ptr);
- opt->OptData.llq.llqOp = getVal16(&ptr);
- opt->OptData.llq.err = getVal16(&ptr);
- mDNSPlatformMemCopy(opt->OptData.llq.id.b, ptr, 8);
- ptr += 8;
- opt->OptData.llq.llqlease = (mDNSu32) ((mDNSu32)ptr[0] << 24 | (mDNSu32)ptr[1] << 16 | (mDNSu32)ptr[2] << 8 | ptr[3]);
- if (opt->OptData.llq.llqlease > 0x70000000UL / mDNSPlatformOneSecond)
- opt->OptData.llq.llqlease = 0x70000000UL / mDNSPlatformOneSecond;
- ptr += sizeof(mDNSOpaque32);
- nread += LLQ_OPTLEN;
- }
- else if (opt->opt == kDNSOpt_Lease)
- {
- if ((unsigned)(limit - ptr) < sizeof(mDNSs32)) goto space_err;
-
- opt->OptData.updatelease = (mDNSu32) ((mDNSu32)ptr[0] << 24 | (mDNSu32)ptr[1] << 16 | (mDNSu32)ptr[2] << 8 | ptr[3]);
- if (opt->OptData.updatelease > 0x70000000UL / mDNSPlatformOneSecond)
- opt->OptData.updatelease = 0x70000000UL / mDNSPlatformOneSecond;
- ptr += sizeof(mDNSs32);
- nread += sizeof(mDNSs32);
- }
- else { LogMsg("ERROR: getOptRdata - unknown opt %d", opt->opt); return mDNSNULL; }
- opt++; // increment pointer into rdatabody
- }
-
- rr->rdlength = pktRDLen;
- return ptr;
-
- space_err:
- LogMsg("ERROR: getLLQRdata - out of space");
- return mDNSNULL;
- }
-
// msg points to the message we're building (pass mDNSNULL if we don't want to use compression pointers)
mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const ResourceRecord *const rr)
{
+ const RDataBody2 *const rdb = (RDataBody2 *)rr->rdata->u.data;
switch (rr->rrtype)
{
case kDNSType_A: if (rr->rdlength != 4)
- {
- debugf("putRData: Illegal length %d for kDNSType_A", rr->rdlength);
- return(mDNSNULL);
- }
+ { debugf("putRData: Illegal length %d for kDNSType_A", rr->rdlength); return(mDNSNULL); }
if (ptr + 4 > limit) return(mDNSNULL);
- *ptr++ = rr->rdata->u.ipv4.b[0];
- *ptr++ = rr->rdata->u.ipv4.b[1];
- *ptr++ = rr->rdata->u.ipv4.b[2];
- *ptr++ = rr->rdata->u.ipv4.b[3];
+ *ptr++ = rdb->ipv4.b[0];
+ *ptr++ = rdb->ipv4.b[1];
+ *ptr++ = rdb->ipv4.b[2];
+ *ptr++ = rdb->ipv4.b[3];
return(ptr);
case kDNSType_NS:
case kDNSType_CNAME:
case kDNSType_PTR:
- case kDNSType_DNAME:return(putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.name));
+ case kDNSType_DNAME:return(putDomainNameAsLabels(msg, ptr, limit, &rdb->name));
- case kDNSType_SOA: ptr = putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.soa.mname);
+ case kDNSType_SOA: ptr = putDomainNameAsLabels(msg, ptr, limit, &rdb->soa.mname);
if (!ptr) return(mDNSNULL);
- ptr = putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.soa.rname);
+ ptr = putDomainNameAsLabels(msg, ptr, limit, &rdb->soa.rname);
if (!ptr || ptr + 20 > limit) return(mDNSNULL);
- ptr = putVal32(ptr, rr->rdata->u.soa.serial);
- ptr = putVal32(ptr, rr->rdata->u.soa.refresh);
- ptr = putVal32(ptr, rr->rdata->u.soa.retry);
- ptr = putVal32(ptr, rr->rdata->u.soa.expire);
- ptr = putVal32(ptr, rr->rdata->u.soa.min);
+ ptr = putVal32(ptr, rdb->soa.serial);
+ ptr = putVal32(ptr, rdb->soa.refresh);
+ ptr = putVal32(ptr, rdb->soa.retry);
+ ptr = putVal32(ptr, rdb->soa.expire);
+ ptr = putVal32(ptr, rdb->soa.min);
return(ptr);
case kDNSType_NULL:
case kDNSType_ISDN:
case kDNSType_LOC:
case kDNSType_DHCID:if (ptr + rr->rdlength > limit) return(mDNSNULL);
- mDNSPlatformMemCopy(ptr, rr->rdata->u.data, rr->rdlength);
+ mDNSPlatformMemCopy(ptr, rdb->data, rr->rdlength);
return(ptr + rr->rdlength);
case kDNSType_MX:
case kDNSType_AFSDB:
case kDNSType_RT:
case kDNSType_KX: if (ptr + 3 > limit) return(mDNSNULL);
- ptr = putVal16(ptr, rr->rdata->u.mx.preference);
- return(putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.mx.exchange));
+ ptr = putVal16(ptr, rdb->mx.preference);
+ return(putDomainNameAsLabels(msg, ptr, limit, &rdb->mx.exchange));
- case kDNSType_RP: ptr = putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.rp.mbox);
+ case kDNSType_RP: ptr = putDomainNameAsLabels(msg, ptr, limit, &rdb->rp.mbox);
if (!ptr) return(mDNSNULL);
- ptr = putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.rp.txt);
+ ptr = putDomainNameAsLabels(msg, ptr, limit, &rdb->rp.txt);
return(ptr);
case kDNSType_PX: if (ptr + 5 > limit) return(mDNSNULL);
- ptr = putVal16(ptr, rr->rdata->u.px.preference);
- ptr = putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.px.map822);
+ ptr = putVal16(ptr, rdb->px.preference);
+ ptr = putDomainNameAsLabels(msg, ptr, limit, &rdb->px.map822);
if (!ptr) return(mDNSNULL);
- ptr = putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.px.mapx400);
+ ptr = putDomainNameAsLabels(msg, ptr, limit, &rdb->px.mapx400);
return(ptr);
- case kDNSType_AAAA: if (rr->rdlength != sizeof(rr->rdata->u.ipv6))
+ case kDNSType_AAAA: if (rr->rdlength != sizeof(rdb->ipv6))
+ { debugf("putRData: Illegal length %d for kDNSType_AAAA", rr->rdlength); return(mDNSNULL); }
+ if (ptr + sizeof(rdb->ipv6) > limit) return(mDNSNULL);
+ mDNSPlatformMemCopy(ptr, &rdb->ipv6, sizeof(rdb->ipv6));
+ return(ptr + sizeof(rdb->ipv6));
+
+ case kDNSType_SRV: if (ptr + 7 > limit) return(mDNSNULL);
+ *ptr++ = (mDNSu8)(rdb->srv.priority >> 8);
+ *ptr++ = (mDNSu8)(rdb->srv.priority & 0xFF);
+ *ptr++ = (mDNSu8)(rdb->srv.weight >> 8);
+ *ptr++ = (mDNSu8)(rdb->srv.weight & 0xFF);
+ *ptr++ = rdb->srv.port.b[0];
+ *ptr++ = rdb->srv.port.b[1];
+ return(putDomainNameAsLabels(msg, ptr, limit, &rdb->srv.target));
+
+ case kDNSType_OPT: {
+ int len = 0;
+ const rdataOPT *opt;
+ const rdataOPT *const end = (const rdataOPT *)&rr->rdata->u.data[rr->rdlength];
+ for (opt = &rr->rdata->u.opt[0]; opt < end; opt++) len += DNSOpt_Data_Space(opt);
+ if (ptr + len > limit) { LogMsg("ERROR: putOptRData - out of space"); return mDNSNULL; }
+
+ for (opt = &rr->rdata->u.opt[0]; opt < end; opt++)
{
- debugf("putRData: Illegal length %d for kDNSType_AAAA", rr->rdlength);
- return(mDNSNULL);
+ const int space = DNSOpt_Data_Space(opt);
+ ptr = putVal16(ptr, opt->opt);
+ ptr = putVal16(ptr, space - 4);
+ switch (opt->opt)
+ {
+ case kDNSOpt_LLQ:
+ ptr = putVal16(ptr, opt->u.llq.vers);
+ ptr = putVal16(ptr, opt->u.llq.llqOp);
+ ptr = putVal16(ptr, opt->u.llq.err);
+ mDNSPlatformMemCopy(ptr, opt->u.llq.id.b, 8); // 8-byte id
+ ptr += 8;
+ ptr = putVal32(ptr, opt->u.llq.llqlease);
+ break;
+ case kDNSOpt_Lease:
+ ptr = putVal32(ptr, opt->u.updatelease);
+ break;
+ case kDNSOpt_Owner:
+ *ptr++ = opt->u.owner.vers;
+ *ptr++ = opt->u.owner.seq;
+ mDNSPlatformMemCopy(ptr, opt->u.owner.HMAC.b, 6); // 6-byte Host identifier
+ ptr += 6;
+ if (space >= DNSOpt_OwnerData_ID_Wake_Space)
+ {
+ mDNSPlatformMemCopy(ptr, opt->u.owner.IMAC.b, 6); // 6-byte interface MAC
+ ptr += 6;
+ if (space > DNSOpt_OwnerData_ID_Wake_Space)
+ {
+ mDNSPlatformMemCopy(ptr, opt->u.owner.password.b, space - DNSOpt_OwnerData_ID_Wake_Space);
+ ptr += space - DNSOpt_OwnerData_ID_Wake_Space;
+ }
+ }
+ break;
+ }
}
- if (ptr + sizeof(rr->rdata->u.ipv6) > limit) return(mDNSNULL);
- mDNSPlatformMemCopy(ptr, &rr->rdata->u.ipv6, sizeof(rr->rdata->u.ipv6));
- return(ptr + sizeof(rr->rdata->u.ipv6));
+ return ptr;
+ }
+
+ case kDNSType_NSEC: {
+ // For our simplified use of NSEC synthetic records:
+ // nextname is always the record's own name,
+ // the block number is always 0,
+ // the count byte is a value in the range 1-32,
+ // followed by the 1-32 data bytes
+ int i, j;
+ for (i=sizeof(rdataNSEC); i>0; i--) if (rdb->nsec.bitmap[i-1]) break;
+ ptr = putDomainNameAsLabels(msg, ptr, limit, rr->name);
+ if (!ptr) return(mDNSNULL);
+ if (ptr + 2 + i > limit) return(mDNSNULL);
+ *ptr++ = 0;
+ *ptr++ = i;
+ for (j=0; j<i; j++) *ptr++ = rdb->nsec.bitmap[j];
+ return ptr;
+ }
- case kDNSType_SRV: if (ptr + 7 > limit) return(mDNSNULL);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.priority >> 8);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.priority & 0xFF);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.weight >> 8);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.weight & 0xFF);
- *ptr++ = rr->rdata->u.srv.port.b[0];
- *ptr++ = rr->rdata->u.srv.port.b[1];
- return(putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.srv.target));
-
- case kDNSType_OPT: return putOptRData(ptr, limit, rr);
-
default: debugf("putRData: Warning! Writing unknown resource type %d as raw data", rr->rrtype);
if (ptr + rr->rdlength > limit) return(mDNSNULL);
- mDNSPlatformMemCopy(ptr, rr->rdata->u.data, rr->rdlength);
+ mDNSPlatformMemCopy(ptr, rdb->data, rr->rdlength);
return(ptr + rr->rdlength);
}
}
+#define IsUnicastUpdate(X) (!mDNSOpaque16IsZero((X)->h.id) && ((X)->h.flags.b[0] & kDNSFlag0_OP_Mask) == kDNSFlag0_OP_Update)
+
mDNSexport mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit)
{
- mDNSu16 rrclass = (rr->rrtype == kDNSType_OPT) ? NormalMaxDNSMessageData : rr->rrclass;
mDNSu8 *endofrdata;
mDNSu16 actualLength;
+ // When sending SRV to conventional DNS server (i.e. in DNS update requests) we should not do name compression on the rdata (RFC 2782)
+ const DNSMessage *const rdatacompressionbase = (IsUnicastUpdate(msg) && rr->rrtype == kDNSType_SRV) ? mDNSNULL : msg;
if (rr->RecordType == kDNSRecordTypeUnregistered)
{
if (!ptr || ptr + 10 >= limit) return(mDNSNULL); // If we're out-of-space, return mDNSNULL
ptr[0] = (mDNSu8)(rr->rrtype >> 8);
ptr[1] = (mDNSu8)(rr->rrtype & 0xFF);
- ptr[2] = (mDNSu8)(rrclass >> 8);
- ptr[3] = (mDNSu8)(rrclass & 0xFF);
+ ptr[2] = (mDNSu8)(rr->rrclass >> 8);
+ ptr[3] = (mDNSu8)(rr->rrclass & 0xFF);
ptr[4] = (mDNSu8)((ttl >> 24) & 0xFF);
ptr[5] = (mDNSu8)((ttl >> 16) & 0xFF);
ptr[6] = (mDNSu8)((ttl >> 8) & 0xFF);
ptr[7] = (mDNSu8)( ttl & 0xFF);
- endofrdata = putRData(msg, ptr+10, limit, rr);
+ endofrdata = putRData(rdatacompressionbase, ptr+10, limit, rr);
if (!endofrdata) { verbosedebugf("Ran out of space in PutResourceRecord for %##s (%s)", rr->name->c, DNSTypeName(rr->rrtype)); return(mDNSNULL); }
// Go back and fill in the actual number of data bytes we wrote
return(endofrdata);
}
-mDNSexport mDNSu8 *PutResourceRecordCappedTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32
- maxttl)
- {
- if (maxttl > rr->rroriginalttl) maxttl = rr->rroriginalttl;
- return(PutResourceRecordTTL(msg, ptr, count, rr, maxttl));
- }
-
-mDNSexport mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit,
- mDNSu16 *count, const AuthRecord *rr)
+mDNSlocal mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, mDNSu16 *count, const AuthRecord *rr)
{
ptr = putDomainNameAsLabels(msg, ptr, limit, rr->resrec.name);
if (!ptr || ptr + 10 > limit) return(mDNSNULL); // If we're out-of-space, return mDNSNULL
ptr = putDomainNameAsLabels(msg, ptr, limit, name);
if (!ptr || ptr + 10 >= limit) return mDNSNULL; // If we're out-of-space, return mDNSNULL
- ptr[0] = (mDNSu8)(rrtype >> 8);
- ptr[1] = (mDNSu8)(rrtype & 0xFF);
- ptr[2] = (mDNSu8)(class >> 8);
- ptr[3] = (mDNSu8)(class & 0xFF);
+ ptr[0] = (mDNSu8)(rrtype >> 8);
+ ptr[1] = (mDNSu8)(rrtype & 0xFF);
+ ptr[2] = (mDNSu8)(class >> 8);
+ ptr[3] = (mDNSu8)(class & 0xFF);
ptr[4] = ptr[5] = ptr[6] = ptr[7] = 0; // zero ttl
ptr[8] = ptr[9] = 0; // zero rdlength/rdata
AuthRecord rr;
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
rr.resrec.rrclass = NormalMaxDNSMessageData;
- rr.resrec.rdlength = LEASE_OPT_RDLEN;
- rr.resrec.rdestimate = LEASE_OPT_RDLEN;
- rr.resrec.rdata->u.opt.opt = kDNSOpt_Lease;
- rr.resrec.rdata->u.opt.optlen = sizeof(mDNSs32);
- rr.resrec.rdata->u.opt.OptData.updatelease = lease;
+ rr.resrec.rdlength = sizeof(rdataOPT); // One option in this OPT record
+ rr.resrec.rdestimate = sizeof(rdataOPT);
+ rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
+ rr.resrec.rdata->u.opt[0].u.updatelease = lease;
end = PutResourceRecordTTLJumbo(msg, end, &msg->h.numAdditionals, &rr.resrec, 0);
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
return end;
case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
{ debugf("skipDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
if (total + 1 + len >= MAX_DOMAIN_NAME) // Remember: expect at least one more byte for the root label
- { debugf("skipDomainName: Malformed domain name (more than 255 characters)"); return(mDNSNULL); }
+ { debugf("skipDomainName: Malformed domain name (more than 256 characters)"); return(mDNSNULL); }
ptr += len;
total += 1 + len;
break;
case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
{ debugf("getDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
if (np + 1 + len >= limit) // Remember: expect at least one more byte for the root label
- { debugf("getDomainName: Malformed domain name (more than 255 characters)"); return(mDNSNULL); }
+ { debugf("getDomainName: Malformed domain name (more than 256 characters)"); return(mDNSNULL); }
*np++ = len;
for (i=0; i<len; i++) *np++ = *ptr++;
*np = 0; // Tentatively place the root label here (may be overwritten if we have more labels)
return(ptr + pktrdlength);
}
+mDNSlocal mDNSu16 getVal16(const mDNSu8 **ptr)
+ {
+ mDNSu16 val = (mDNSu16)(((mDNSu16)(*ptr)[0]) << 8 | (*ptr)[1]);
+ *ptr += sizeof(mDNSOpaque16);
+ return val;
+ }
+
mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *ptr,
- const mDNSu8 *end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *largecr)
+ const mDNSu8 *end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *const largecr)
{
- CacheRecord *rr = &largecr->r;
+ CacheRecord *const rr = &largecr->r;
+ RDataBody2 *const rdb = (RDataBody2 *)rr->smallrdatastorage.data;
mDNSu16 pktrdlength;
- if (largecr == &m->rec && largecr->r.resrec.RecordType)
- LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &largecr->r));
+ if (largecr == &m->rec && m->rec.r.resrec.RecordType)
+ {
+ LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
+#if ForceAlerts
+ *(long*)0 = 0;
+#endif
+ }
rr->next = mDNSNULL;
rr->resrec.name = &largecr->namestorage;
rr->CRActiveQuestion = mDNSNULL;
rr->UnansweredQueries = 0;
rr->LastUnansweredTime= 0;
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
rr->MPUnansweredQ = 0;
rr->MPLastUnansweredQT= 0;
rr->MPUnansweredKA = 0;
rr->MPExpectingKA = mDNSfalse;
+#endif
rr->NextInCFList = mDNSNULL;
rr->resrec.InterfaceID = InterfaceID;
if (ptr + pktrdlength > end) { debugf("GetLargeResourceRecord: RDATA exceeds end of packet"); return(mDNSNULL); }
end = ptr + pktrdlength; // Adjust end to indicate the end of the rdata for this resource record
- rr->resrec.rdata = (RData*)&rr->rdatastorage;
+ rr->resrec.rdata = (RData*)&rr->smallrdatastorage;
rr->resrec.rdata->MaxRDLength = MaximumRDSize;
if (!RecordType) LogMsg("GetLargeResourceRecord: No RecordType for %##s", rr->resrec.name->c);
else switch (rr->resrec.rrtype)
{
case kDNSType_A: if (pktrdlength != sizeof(mDNSv4Addr)) return(mDNSNULL);
- rr->resrec.rdata->u.ipv4.b[0] = ptr[0];
- rr->resrec.rdata->u.ipv4.b[1] = ptr[1];
- rr->resrec.rdata->u.ipv4.b[2] = ptr[2];
- rr->resrec.rdata->u.ipv4.b[3] = ptr[3];
+ rdb->ipv4.b[0] = ptr[0];
+ rdb->ipv4.b[1] = ptr[1];
+ rdb->ipv4.b[2] = ptr[2];
+ rdb->ipv4.b[3] = ptr[3];
break;
case kDNSType_NS:
case kDNSType_CNAME:
case kDNSType_PTR:
- case kDNSType_DNAME:ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.name);
+ case kDNSType_DNAME:ptr = getDomainName(msg, ptr, end, &rdb->name);
if (ptr != end) { debugf("GetLargeResourceRecord: Malformed CNAME/PTR RDATA name"); return(mDNSNULL); }
- //debugf("%##s PTR %##s rdlen %d", rr->resrec.name.c, rr->resrec.rdata->u.name.c, pktrdlength);
+ //debugf("%##s PTR %##s rdlen %d", rr->resrec.name.c, rdb->name.c, pktrdlength);
break;
- case kDNSType_SOA: ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.soa.mname);
+ case kDNSType_SOA: ptr = getDomainName(msg, ptr, end, &rdb->soa.mname);
if (!ptr) { debugf("GetLargeResourceRecord: Malformed SOA RDATA mname"); return mDNSNULL; }
- ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.soa.rname);
+ ptr = getDomainName(msg, ptr, end, &rdb->soa.rname);
if (!ptr) { debugf("GetLargeResourceRecord: Malformed SOA RDATA rname"); return mDNSNULL; }
if (ptr + 0x14 != end) { debugf("GetLargeResourceRecord: Malformed SOA RDATA"); return mDNSNULL; }
- rr->resrec.rdata->u.soa.serial = (mDNSs32) ((mDNSs32)ptr[0x00] << 24 | (mDNSs32)ptr[0x01] << 16 | (mDNSs32)ptr[0x02] << 8 | ptr[0x03]);
- rr->resrec.rdata->u.soa.refresh = (mDNSu32) ((mDNSu32)ptr[0x04] << 24 | (mDNSu32)ptr[0x05] << 16 | (mDNSu32)ptr[0x06] << 8 | ptr[0x07]);
- rr->resrec.rdata->u.soa.retry = (mDNSu32) ((mDNSu32)ptr[0x08] << 24 | (mDNSu32)ptr[0x09] << 16 | (mDNSu32)ptr[0x0A] << 8 | ptr[0x0B]);
- rr->resrec.rdata->u.soa.expire = (mDNSu32) ((mDNSu32)ptr[0x0C] << 24 | (mDNSu32)ptr[0x0D] << 16 | (mDNSu32)ptr[0x0E] << 8 | ptr[0x0F]);
- rr->resrec.rdata->u.soa.min = (mDNSu32) ((mDNSu32)ptr[0x10] << 24 | (mDNSu32)ptr[0x11] << 16 | (mDNSu32)ptr[0x12] << 8 | ptr[0x13]);
+ rdb->soa.serial = (mDNSs32) ((mDNSs32)ptr[0x00] << 24 | (mDNSs32)ptr[0x01] << 16 | (mDNSs32)ptr[0x02] << 8 | ptr[0x03]);
+ rdb->soa.refresh = (mDNSu32) ((mDNSu32)ptr[0x04] << 24 | (mDNSu32)ptr[0x05] << 16 | (mDNSu32)ptr[0x06] << 8 | ptr[0x07]);
+ rdb->soa.retry = (mDNSu32) ((mDNSu32)ptr[0x08] << 24 | (mDNSu32)ptr[0x09] << 16 | (mDNSu32)ptr[0x0A] << 8 | ptr[0x0B]);
+ rdb->soa.expire = (mDNSu32) ((mDNSu32)ptr[0x0C] << 24 | (mDNSu32)ptr[0x0D] << 16 | (mDNSu32)ptr[0x0E] << 8 | ptr[0x0F]);
+ rdb->soa.min = (mDNSu32) ((mDNSu32)ptr[0x10] << 24 | (mDNSu32)ptr[0x11] << 16 | (mDNSu32)ptr[0x12] << 8 | ptr[0x13]);
break;
case kDNSType_NULL:
return(mDNSNULL);
}
rr->resrec.rdlength = pktrdlength;
- mDNSPlatformMemCopy(rr->resrec.rdata->u.data, ptr, pktrdlength);
+ mDNSPlatformMemCopy(rdb->data, ptr, pktrdlength);
break;
case kDNSType_MX:
case kDNSType_AFSDB:
case kDNSType_RT:
case kDNSType_KX: if (pktrdlength < 3) return(mDNSNULL); // Preference + domainname
- rr->resrec.rdata->u.mx.preference = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
- ptr = getDomainName(msg, ptr+2, end, &rr->resrec.rdata->u.mx.exchange);
+ rdb->mx.preference = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
+ ptr = getDomainName(msg, ptr+2, end, &rdb->mx.exchange);
if (ptr != end) { debugf("GetLargeResourceRecord: Malformed MX name"); return(mDNSNULL); }
- //debugf("%##s SRV %##s rdlen %d", rr->resrec.name.c, rr->resrec.rdata->u.srv.target.c, pktrdlength);
+ //debugf("%##s SRV %##s rdlen %d", rr->resrec.name.c, rdb->srv.target.c, pktrdlength);
break;
- case kDNSType_RP: ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.rp.mbox); // Domainname + domainname
+ case kDNSType_RP: ptr = getDomainName(msg, ptr, end, &rdb->rp.mbox); // Domainname + domainname
if (!ptr) { debugf("GetLargeResourceRecord: Malformed RP mbox"); return mDNSNULL; }
- ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.rp.txt);
+ ptr = getDomainName(msg, ptr, end, &rdb->rp.txt);
if (ptr != end) { debugf("GetLargeResourceRecord: Malformed RP txt"); return mDNSNULL; }
break;
case kDNSType_PX: if (pktrdlength < 4) return(mDNSNULL); // Preference + domainname + domainname
- rr->resrec.rdata->u.px.preference = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
- ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.px.map822);
+ rdb->px.preference = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
+ ptr = getDomainName(msg, ptr, end, &rdb->px.map822);
if (!ptr) { debugf("GetLargeResourceRecord: Malformed PX map822"); return mDNSNULL; }
- ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.px.mapx400);
+ ptr = getDomainName(msg, ptr, end, &rdb->px.mapx400);
if (ptr != end) { debugf("GetLargeResourceRecord: Malformed PX mapx400"); return mDNSNULL; }
break;
case kDNSType_AAAA: if (pktrdlength != sizeof(mDNSv6Addr)) return(mDNSNULL);
- mDNSPlatformMemCopy(&rr->resrec.rdata->u.ipv6, ptr, sizeof(rr->resrec.rdata->u.ipv6));
+ mDNSPlatformMemCopy(&rdb->ipv6, ptr, sizeof(rdb->ipv6));
break;
case kDNSType_SRV: if (pktrdlength < 7) return(mDNSNULL); // Priority + weight + port + domainname
- rr->resrec.rdata->u.srv.priority = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
- rr->resrec.rdata->u.srv.weight = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]);
- rr->resrec.rdata->u.srv.port.b[0] = ptr[4];
- rr->resrec.rdata->u.srv.port.b[1] = ptr[5];
- ptr = getDomainName(msg, ptr+6, end, &rr->resrec.rdata->u.srv.target);
+ rdb->srv.priority = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
+ rdb->srv.weight = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]);
+ rdb->srv.port.b[0] = ptr[4];
+ rdb->srv.port.b[1] = ptr[5];
+ ptr = getDomainName(msg, ptr+6, end, &rdb->srv.target);
if (ptr != end) { debugf("GetLargeResourceRecord: Malformed SRV RDATA name"); return(mDNSNULL); }
- //debugf("%##s SRV %##s rdlen %d", rr->resrec.name.c, rr->resrec.rdata->u.srv.target.c, pktrdlength);
+ //debugf("%##s SRV %##s rdlen %d", rr->resrec.name.c, rdb->srv.target.c, pktrdlength);
break;
- case kDNSType_OPT: ptr = getOptRdata(ptr, end, largecr, pktrdlength); break;
+ case kDNSType_OPT: {
+ rdataOPT *opt = rr->resrec.rdata->u.opt;
+ rr->resrec.rdlength = 0;
+ while (ptr < end && (mDNSu8 *)(opt+1) < &rr->resrec.rdata->u.data[MaximumRDSize])
+ {
+ if (ptr + 4 > end) { LogMsg("GetLargeResourceRecord: OPT RDATA ptr + 4 > end"); return(mDNSNULL); }
+ opt->opt = getVal16(&ptr);
+ opt->optlen = getVal16(&ptr);
+ if (!ValidDNSOpt(opt)) { LogMsg("GetLargeResourceRecord: opt %d optlen %d wrong", opt->opt, opt->optlen); return(mDNSNULL); }
+ if (ptr + opt->optlen > end) { LogMsg("GetLargeResourceRecord: ptr + opt->optlen > end"); return(mDNSNULL); }
+ switch(opt->opt)
+ {
+ case kDNSOpt_LLQ:
+ opt->u.llq.vers = getVal16(&ptr);
+ opt->u.llq.llqOp = getVal16(&ptr);
+ opt->u.llq.err = getVal16(&ptr);
+ mDNSPlatformMemCopy(opt->u.llq.id.b, ptr, 8);
+ ptr += 8;
+ opt->u.llq.llqlease = (mDNSu32) ((mDNSu32)ptr[0] << 24 | (mDNSu32)ptr[1] << 16 | (mDNSu32)ptr[2] << 8 | ptr[3]);
+ if (opt->u.llq.llqlease > 0x70000000UL / mDNSPlatformOneSecond)
+ opt->u.llq.llqlease = 0x70000000UL / mDNSPlatformOneSecond;
+ ptr += sizeof(mDNSOpaque32);
+ break;
+ case kDNSOpt_Lease:
+ opt->u.updatelease = (mDNSu32) ((mDNSu32)ptr[0] << 24 | (mDNSu32)ptr[1] << 16 | (mDNSu32)ptr[2] << 8 | ptr[3]);
+ if (opt->u.updatelease > 0x70000000UL / mDNSPlatformOneSecond)
+ opt->u.updatelease = 0x70000000UL / mDNSPlatformOneSecond;
+ ptr += sizeof(mDNSs32);
+ break;
+ case kDNSOpt_Owner:
+ opt->u.owner.vers = ptr[0];
+ opt->u.owner.seq = ptr[1];
+ mDNSPlatformMemCopy(opt->u.owner.HMAC.b, ptr+2, 6); // 6-byte MAC address
+ mDNSPlatformMemCopy(opt->u.owner.IMAC.b, ptr+2, 6); // 6-byte MAC address
+ opt->u.owner.password = zeroEthAddr;
+ if (opt->optlen >= DNSOpt_OwnerData_ID_Wake_Space-4)
+ {
+ mDNSPlatformMemCopy(opt->u.owner.IMAC.b, ptr+8, 6); // 6-byte MAC address
+ if (opt->optlen > DNSOpt_OwnerData_ID_Wake_Space-4)
+ mDNSPlatformMemCopy(opt->u.owner.password.b, ptr+14, opt->optlen - (DNSOpt_OwnerData_ID_Wake_Space-4));
+ }
+ ptr += opt->optlen;
+ break;
+ }
+ opt++; // increment pointer into rdatabody
+ }
+ rr->resrec.rdlength = (mDNSu8*)opt - rr->resrec.rdata->u.data;
if (ptr != end) { LogMsg("GetLargeResourceRecord: Malformed OptRdata"); return(mDNSNULL); }
+ break;
+ }
+
+ case kDNSType_NSEC: {
+ unsigned int i, j;
+ domainname d;
+ ptr = getDomainName(msg, ptr, end, &d); // Ignored for our simplified use of NSEC synthetic records
+ if (!ptr) { debugf("GetLargeResourceRecord: Malformed NSEC nextname"); return mDNSNULL; }
+ if (*ptr++ != 0) { debugf("GetLargeResourceRecord: We only handle block zero NSECs"); return mDNSNULL; }
+ i = *ptr++;
+ if (i < 1 || i > sizeof(rdataNSEC)) { debugf("GetLargeResourceRecord: invalid block length %d", i); return mDNSNULL; }
+ mDNSPlatformMemZero(rdb->nsec.bitmap, sizeof(rdb->nsec.bitmap));
+ for (j=0; j<i; j++) rdb->nsec.bitmap[j] = *ptr++;
+ if (ptr != end) { LogMsg("GetLargeResourceRecord: Malformed NSEC"); return(mDNSNULL); }
+ break;
+ }
default: if (pktrdlength > rr->resrec.rdata->MaxRDLength)
{
// We also grab a binary copy of the rdata anyway, since the caller
// might know how to interpret it even if we don't.
rr->resrec.rdlength = pktrdlength;
- mDNSPlatformMemCopy(rr->resrec.rdata->u.data, ptr, pktrdlength);
+ mDNSPlatformMemCopy(rdb->data, ptr, pktrdlength);
break;
}
{
mDNSPlatformMemZero(question, sizeof(*question));
question->InterfaceID = InterfaceID;
+ if (!InterfaceID) question->TargetQID = onesID; // In DNSQuestions we use TargetQID as the indicator of whether it's unicast or multicast
ptr = getDomainName(msg, ptr, end, &question->qname);
if (!ptr) { debugf("Malformed domain name in DNS question section"); return(mDNSNULL); }
if (ptr+4 > end) { debugf("Malformed DNS question section -- no query type and class!"); return(mDNSNULL); }
return (ptr);
}
-mDNSexport const mDNSu8 *LocateLLQOptData(const DNSMessage *const msg, const mDNSu8 *const end)
+mDNSexport const mDNSu8 *LocateOptRR(const DNSMessage *const msg, const mDNSu8 *const end, int minsize)
{
int i;
const mDNSu8 *ptr = LocateAdditionals(msg, end);
// but not necessarily the *last* entry in the Additional Section.
for (i = 0; ptr && i < msg->h.numAdditionals; i++)
{
- if (ptr + 10 + LLQ_OPT_RDLEN <= end && // Make sure we have 10+22 bytes of data
- ptr[0] == 0 && // Name must be root label
- ptr[1] == (kDNSType_OPT >> 8 ) && // rrtype OPT
- ptr[2] == (kDNSType_OPT & 0xFF) &&
- ((mDNSu16)ptr[9] << 8 | (mDNSu16)ptr[10]) >= (mDNSu16)LLQ_OPT_RDLEN)
+ if (ptr + DNSOpt_Header_Space + minsize <= end && // Make sure we have 11+minsize bytes of data
+ ptr[0] == 0 && // Name must be root label
+ ptr[1] == (kDNSType_OPT >> 8 ) && // rrtype OPT
+ ptr[2] == (kDNSType_OPT & 0xFF) &&
+ ((mDNSu16)ptr[9] << 8 | (mDNSu16)ptr[10]) >= (mDNSu16)minsize)
return(ptr);
else
ptr = skipResourceRecord(msg, ptr, end);
}
// On success, GetLLQOptData returns pointer to storage within shared "m->rec";
-// it is callers responsibilty to clear m->rec.r.resrec.RecordType after use
+// it is caller's responsibilty to clear m->rec.r.resrec.RecordType after use
// Note: An OPT RDataBody actually contains one or more variable-length rdataOPT objects packed together
// The code that currently calls this assumes there's only one, instead of iterating through the set
mDNSexport const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end)
{
- const mDNSu8 *ptr = LocateLLQOptData(msg, end);
+ const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LLQData_Space);
if (ptr)
{
ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
- if (ptr) return(&m->rec.r.resrec.rdata->u.opt);
- }
- return(mDNSNULL);
- }
-
-mDNSexport const mDNSu8 *LocateLeaseOptData(const DNSMessage *const msg, const mDNSu8 *const end)
- {
- int i;
- const mDNSu8 *ptr = LocateAdditionals(msg, end);
-
- // Locate the OPT record.
- // According to RFC 2671, "One OPT pseudo-RR can be added to the additional data section of either a request or a response."
- // This implies that there may be *at most* one OPT record per DNS message, in the Additional Section,
- // but not necessarily the *last* entry in the Additional Section.
- for (i = 0; ptr && i < msg->h.numAdditionals; i++)
- {
- if (ptr + 10 + LEASE_OPT_RDLEN <= end && // Make sure we have 10+8 bytes of data
- ptr[0] == 0 && // Name must be root label
- ptr[1] == (kDNSType_OPT >> 8 ) && // rrtype OPT
- ptr[2] == (kDNSType_OPT & 0xFF) &&
- ((mDNSu16)ptr[9] << 8 | (mDNSu16)ptr[10]) >= (mDNSu16)LEASE_OPT_RDLEN)
- return(ptr);
- else
- ptr = skipResourceRecord(msg, ptr, end);
+ if (ptr) return(&m->rec.r.resrec.rdata->u.opt[0]);
}
return(mDNSNULL);
}
mDNSexport mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end)
{
mDNSu32 result = 0;
- const mDNSu8 *ptr = LocateLeaseOptData(msg, end);
+ const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
if (ptr) ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
- if (ptr && m->rec.r.resrec.rdlength >= LEASE_OPT_RDLEN && m->rec.r.resrec.rdata->u.opt.opt == kDNSOpt_Lease)
- result = m->rec.r.resrec.rdata->u.opt.OptData.updatelease;
+ if (ptr && m->rec.r.resrec.rdlength >= DNSOpt_LeaseData_Space && m->rec.r.resrec.rdata->u.opt[0].opt == kDNSOpt_Lease)
+ result = m->rec.r.resrec.rdata->u.opt[0].u.updatelease;
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
return(result);
}
#define DNS_RC_Name(X) ( \
(X) == kDNSFlag1_RC_NoErr ? "NoErr" : \
- (X) == kDNSFlag1_RC_FmtErr ? "FmtErr" : \
- (X) == kDNSFlag1_RC_SrvErr ? "SrvErr" : \
+ (X) == kDNSFlag1_RC_FormErr ? "FormErr" : \
+ (X) == kDNSFlag1_RC_ServFail ? "ServFail" : \
(X) == kDNSFlag1_RC_NXDomain ? "NXDomain" : \
(X) == kDNSFlag1_RC_NotImpl ? "NotImpl" : \
(X) == kDNSFlag1_RC_Refused ? "Refused" : \
(X) == kDNSFlag1_RC_NotZone ? "NotZone" : "??" )
// Note: DumpPacket expects the packet header fields in host byte order, not network byte order
-mDNSexport void DumpPacket(mDNS *const m, mDNSBool sent, char *transport,
+mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *transport,
const mDNSAddr *srcaddr, mDNSIPPort srcport,
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end)
{
const mDNSu8 *ptr = msg->data;
int i;
DNSQuestion q;
- char sbuffer[64], dbuffer[64] = "";
+ char tbuffer[64], sbuffer[64], dbuffer[64] = "";
+ if (!status) tbuffer[mDNS_snprintf(tbuffer, sizeof(tbuffer), sent ? "Sent" : "Received" )] = 0;
+ else tbuffer[mDNS_snprintf(tbuffer, sizeof(tbuffer), "ERROR %d %sing", status, sent ? "Send" : "Receiv")] = 0;
if (sent) sbuffer[mDNS_snprintf(sbuffer, sizeof(sbuffer), "port " )] = 0;
else sbuffer[mDNS_snprintf(sbuffer, sizeof(sbuffer), "%#a:", srcaddr)] = 0;
if (dstaddr || !mDNSIPPortIsZero(dstport))
dbuffer[mDNS_snprintf(dbuffer, sizeof(dbuffer), " to %#a:%d", dstaddr, mDNSVal16(dstport))] = 0;
LogMsg("-- %s %s DNS %s%s (flags %02X%02X) RCODE: %s (%d) %s%s%s%s%s%sID: %d %d bytes from %s%d%s%s --",
- sent ? "Sent" : "Received", transport,
+ tbuffer, transport,
DNS_OP_Name(msg->h.flags.b[0] & kDNSFlag0_OP_Mask),
msg->h.flags.b[0] & kDNSFlag0_QR_Response ? "Response" : "Query",
msg->h.flags.b[0], msg->h.flags.b[1],
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo)
{
mStatus status = mStatus_NoError;
- const mDNSu16 numQuestions = msg->h.numQuestions;
- const mDNSu16 numAnswers = msg->h.numAnswers;
- const mDNSu16 numAuthorities = msg->h.numAuthorities;
const mDNSu16 numAdditionals = msg->h.numAdditionals;
- mDNSu16 tmpNumAdditionals = numAdditionals;
- mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
+ mDNSu8 *newend;
- if (end <= msg->data || end - msg->data > AbsoluteMaxDNSMessageData)
+ // Zero-length message data is okay (e.g. for a DNS Update ack, where all we need is an ID and an error code
+ if (end < msg->data || end - msg->data > AbsoluteMaxDNSMessageData)
{
LogMsg("mDNSSendDNSMessage: invalid message %p %p %d", msg->data, end, end - msg->data);
return mStatus_BadParamErr;
}
- end = putHINFO(m, msg, end, authInfo);
- if (!end) { LogMsg("mDNSSendDNSMessage: putHINFO failed"); status = mStatus_NoMemoryErr; }
- else
- {
- tmpNumAdditionals = msg->h.numAdditionals;
+ newend = putHINFO(m, msg, end, authInfo);
+ if (!newend) LogMsg("mDNSSendDNSMessage: putHINFO failed"); // Not fatal
+ else end = newend;
- // Put all the integer values in IETF byte-order (MSB first, LSB second)
- *ptr++ = (mDNSu8)(numQuestions >> 8);
- *ptr++ = (mDNSu8)(numQuestions & 0xFF);
- *ptr++ = (mDNSu8)(numAnswers >> 8);
- *ptr++ = (mDNSu8)(numAnswers & 0xFF);
- *ptr++ = (mDNSu8)(numAuthorities >> 8);
- *ptr++ = (mDNSu8)(numAuthorities & 0xFF);
- *ptr++ = (mDNSu8)(tmpNumAdditionals >> 8);
- *ptr++ = (mDNSu8)(tmpNumAdditionals & 0xFF);
+ // Put all the integer values in IETF byte-order (MSB first, LSB second)
+ SwapDNSHeaderBytes(msg);
- if (authInfo) DNSDigest_SignMessage(msg, &end, authInfo, 0); // DNSDigest_SignMessage operates on message in network byte order
- if (!end) { LogMsg("mDNSSendDNSMessage: DNSDigest_SignMessage failed"); status = mStatus_NoMemoryErr; }
+ if (authInfo) DNSDigest_SignMessage(msg, &end, authInfo, 0); // DNSDigest_SignMessage operates on message in network byte order
+ if (!end) { LogMsg("mDNSSendDNSMessage: DNSDigest_SignMessage failed"); status = mStatus_NoMemoryErr; }
+ else
+ {
+ // Send the packet on the wire
+ if (!sock)
+ status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, src, dst, dstport);
else
{
- // Send the packet on the wire
- if (!sock)
- status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, src, dst, dstport);
+ mDNSu16 msglen = (mDNSu16)(end - (mDNSu8 *)msg);
+ mDNSu8 lenbuf[2] = { (mDNSu8)(msglen >> 8), (mDNSu8)(msglen & 0xFF) };
+ long nsent = mDNSPlatformWriteTCP(sock, (char*)lenbuf, 2); // Should do scatter/gather here -- this is probably going out as two packets
+ if (nsent != 2) { LogMsg("mDNSSendDNSMessage: write msg length failed %d/%d", nsent, 2); status = mStatus_ConnFailed; }
else
{
- mDNSu16 msglen = (mDNSu16)(end - (mDNSu8 *)msg);
- mDNSu8 lenbuf[2] = { (mDNSu8)(msglen >> 8), (mDNSu8)(msglen & 0xFF) };
- long nsent = mDNSPlatformWriteTCP(sock, (char*)lenbuf, 2); // Should do scatter/gather here -- this is probably going out as two packets
- if (nsent != 2) { LogMsg("mDNSSendDNSMessage: write msg length failed %d/%d", nsent, 2); status = mStatus_ConnFailed; }
- else
- {
- nsent = mDNSPlatformWriteTCP(sock, (char *)msg, msglen);
- if (nsent != msglen) { LogMsg("mDNSSendDNSMessage: write msg body failed %d/%d", nsent, msglen); status = mStatus_ConnFailed; }
- }
+ nsent = mDNSPlatformWriteTCP(sock, (char *)msg, msglen);
+ if (nsent != msglen) { LogMsg("mDNSSendDNSMessage: write msg body failed %d/%d", nsent, msglen); status = mStatus_ConnFailed; }
}
}
}
- // Put all the integer values back the way they were before we return
- msg->h.numQuestions = numQuestions;
- msg->h.numAnswers = numAnswers;
- msg->h.numAuthorities = numAuthorities;
+ // Swap the integer values back the way they were (remember that numAdditionals may have been changed by putHINFO and/or SignMessage)
+ SwapDNSHeaderBytes(msg);
// Dump the packet with the HINFO and TSIG
- if (mDNS_LogLevel >= MDNS_LOG_VERBOSE_DEBUG && !mDNSOpaque16IsZero(msg->h.id))
- {
- ptr = (mDNSu8 *)&msg->h.numAdditionals;
- msg->h.numAdditionals = (mDNSu16)ptr[0] << 8 | (mDNSu16)ptr[1];
- DumpPacket(m, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", mDNSNULL, src ? src->port : MulticastDNSPort, dst, dstport, msg, end);
- }
+ if (mDNS_PacketLoggingEnabled && !mDNSOpaque16IsZero(msg->h.id))
+ DumpPacket(m, status, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", mDNSNULL, src ? src->port : MulticastDNSPort, dst, dstport, msg, end);
- // put the final integer value back the way it was
+ // put the number of additionals back the way it was
msg->h.numAdditionals = numAdditionals;
return(status);
}
if (m->NewLocalOnlyQuestions) return(m->timenow);
if (m->NewLocalRecords && LocalRecordReady(m->NewLocalRecords)) return(m->timenow);
+ if (m->SPSProxyListChanged) return(m->timenow);
#ifndef UNICAST_DISABLED
if (e - m->NextuDNSEvent > 0) e = m->NextuDNSEvent;
if (e - m->NextScheduledNATOp > 0) e = m->NextScheduledNATOp;
#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;
+ if (m->DelaySleep && e - m->DelaySleep > 0) e = m->DelaySleep;
- if (!m->SleepState)
+ if (m->SuppressSending)
{
- if (m->SuppressSending)
- {
- if (e - m->SuppressSending > 0) e = m->SuppressSending;
- }
- else
- {
- if (e - m->NextScheduledQuery > 0) e = m->NextScheduledQuery;
- if (e - m->NextScheduledProbe > 0) e = m->NextScheduledProbe;
- if (e - m->NextScheduledResponse > 0) e = m->NextScheduledResponse;
- }
+ if (e - m->SuppressSending > 0) e = m->SuppressSending;
}
+ else
+ {
+ if (e - m->NextScheduledQuery > 0) e = m->NextScheduledQuery;
+ if (e - m->NextScheduledProbe > 0) e = m->NextScheduledProbe;
+ if (e - m->NextScheduledResponse > 0) e = m->NextScheduledResponse;
+ }
+
return(e);
}
+mDNSexport void ShowTaskSchedulingError(mDNS *const m)
+ {
+ mDNS_Lock(m);
+
+ LogMsg("Task Scheduling Error: Continuously busy for more than a second");
+
+ // Note: To accurately diagnose *why* we're busy, the debugging code here needs to mirror the logic in GetNextScheduledEvent above
+
+ if (m->NewQuestions && (!m->NewQuestions->DelayAnswering || m->timenow - m->NewQuestions->DelayAnswering >= 0))
+ LogMsg("Task Scheduling Error: NewQuestion %##s (%s)",
+ m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));
+
+ if (m->NewLocalOnlyQuestions)
+ LogMsg("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
+ m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));
+
+ if (m->NewLocalRecords && LocalRecordReady(m->NewLocalRecords))
+ LogMsg("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, m->NewLocalRecords));
+
+ if (m->timenow - m->NextScheduledEvent >= 0)
+ LogMsg("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
+ if (m->SuppressSending && m->timenow - m->SuppressSending >= 0)
+ LogMsg("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
+ if (m->timenow - m->NextCacheCheck >= 0)
+ LogMsg("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
+ if (m->timenow - m->NextScheduledQuery >= 0)
+ LogMsg("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
+ if (m->timenow - m->NextScheduledProbe >= 0)
+ LogMsg("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
+ if (m->timenow - m->NextScheduledResponse >= 0)
+ LogMsg("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
+ if (m->timenow - m->NextScheduledNATOp >= 0)
+ 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)
+ 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);
+#ifndef UNICAST_DISABLED
+ if (m->timenow - m->NextuDNSEvent >= 0)
+ LogMsg("Task Scheduling Error: NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
+#endif
+
+ mDNS_Unlock(m);
+ }
+
mDNSexport void mDNS_Unlock_(mDNS *const m)
{
// Decrement mDNS_busy
Change History (most recent first):
$Log: DNSCommon.h,v $
+Revision 1.73 2009/04/24 00:28:05 cheshire
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+Added definitions for RRTypeAnswersQuestionType/RRAssertsNonexistence/AnyTypeRecordAnswersQuestion
+
+Revision 1.72 2009/04/01 21:12:56 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+
+Revision 1.71 2009/04/01 17:50:10 mcguire
+cleanup mDNSRandom
+
+Revision 1.70 2009/03/04 00:40:12 cheshire
+Updated DNS server error codes to be more consistent with definitions at
+<http://www.iana.org/assignments/dns-parameters>
+
+Revision 1.69 2008/11/26 20:57:37 cheshire
+For consistency with other similar macros, renamed mdnsIsDigit/mdnsIsLetter/mdnsValidHostChar
+to mDNSIsDigit/mDNSIsLetter/mDNSValidHostChar
+
+Revision 1.68 2008/11/14 21:56:31 cheshire
+Moved debugging routine ShowTaskSchedulingError() from daemon.c into DNSCommon.c
+
+Revision 1.67 2008/11/13 19:05:09 cheshire
+Added definition of LocateOptRR()
+
+Revision 1.66 2008/10/22 19:56:54 cheshire
+Removed unused SameRData() macro -- it duplicates the functionality of IdenticalSameNameRecord()
+
+Revision 1.65 2008/10/20 15:39:20 cheshire
+Group "#define PutResourceRecord ..." with related definitions
+
+Revision 1.64 2008/10/08 01:03:33 cheshire
+Change GetFirstActiveInterface() so the NetworkInterfaceInfo it returns is not "const"
+
+Revision 1.63 2008/09/23 02:30:07 cheshire
+Get rid of PutResourceRecordCappedTTL()
+
+Revision 1.62 2008/09/23 02:26:09 cheshire
+Don't need to export putEmptyResourceRecord (it's only used from DNSCommon.c)
+
+Revision 1.61 2008/08/13 00:47:53 mcguire
+Handle failures when packet logging
+
Revision 1.60 2008/07/24 20:23:03 cheshire
<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
kDNSFlag1_RC_Mask = 0x0F, // Response code
kDNSFlag1_RC_NoErr = 0x00,
- kDNSFlag1_RC_FmtErr = 0x01,
- kDNSFlag1_RC_SrvErr = 0x02,
+ kDNSFlag1_RC_FormErr = 0x01,
+ kDNSFlag1_RC_ServFail = 0x02,
kDNSFlag1_RC_NXDomain = 0x03,
kDNSFlag1_RC_NotImpl = 0x04,
kDNSFlag1_RC_Refused = 0x05,
#pragma mark - General Utility Functions
#endif
-extern const NetworkInterfaceInfo *GetFirstActiveInterface(const NetworkInterfaceInfo *intf);
+extern NetworkInterfaceInfo *GetFirstActiveInterface(NetworkInterfaceInfo *intf);
extern mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf);
extern mDNSu32 mDNSRandom(mDNSu32 max); // Returns pseudo-random result from zero to max inclusive
-extern mDNSu32 mDNSRandomFromFixedSeed(mDNSu32 seed, mDNSu32 max);
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Domain Name Utility Functions
#endif
-#define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
+#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
#define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
#define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
-#define mdnsIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
+#define mDNSIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
-#define mdnsValidHostChar(X, notfirst, notlast) (mdnsIsLetter(X) || mdnsIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
+#define mDNSValidHostChar(X, notfirst, notlast) (mDNSIsLetter(X) || mDNSIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
extern mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent);
extern int CountLabels(const domainname *d);
(r1)->rdatahash == (r2)->rdatahash && \
SameRDataBody((r1), &(r2)->rdata->u))
+// A given RRType answers a QuestionType if RRType is CNAME, or types match, or QuestionType is ANY,
+// or the RRType is NSEC and positively asserts the nonexistence of the type being requested
+#define RRTypeAnswersQuestionType(R,T) ((R)->rrtype == kDNSType_CNAME || (R)->rrtype == (T) || (T) == kDNSQType_ANY || RRAssertsNonexistence((R),(T)))
+#define RRAssertsNonexistence(R,T) ((R)->rrtype == kDNSType_NSEC && (T) < kDNSQType_ANY && !((R)->rdata->u.nsec.bitmap[(T)>>3] & (128 >> ((T)&7))))
+
extern mDNSu32 RDataHashValue(const ResourceRecord *const rr);
extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2);
-#define SameRData(r1,r2) ((r1)->rrtype == (r2)->rrtype && (r1)->rdlength == (r2)->rdlength && (r1)->rdatahash == (r2)->rdatahash && SameRDataBody((r1), &(r2)->rdata->u))
-extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
extern mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
+extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
+extern mDNSBool AnyTypeRecordAnswersQuestion (const ResourceRecord *const rr, const DNSQuestion *const q);
extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
// If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
// but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
extern mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit);
-#define PutResourceRecordTTL(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
+
+#define PutResourceRecordTTL(msg, ptr, count, rr, ttl) \
+ PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? (msg)->data + NormalMaxDNSMessageData : (msg)->data + AbsoluteMaxDNSMessageData)
-#define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
- (msg)->data + AbsoluteMaxDNSMessageData)
-extern mDNSu8 *PutResourceRecordCappedTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 maxttl);
-extern mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, mDNSu16 *count, const AuthRecord *rr);
+#define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) \
+ PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), (msg)->data + AbsoluteMaxDNSMessageData)
+#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
extern mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass);
extern mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass);
extern mDNSu8 *putDeleteRRSet(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype);
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
-#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end, DomainAuthInfo *authInfo);
extern const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end);
extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end);
extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
-extern const mDNSu8 *LocateLLQOptData(const DNSMessage *const msg, const mDNSu8 *const end);
+extern const mDNSu8 *LocateOptRR(const DNSMessage *const msg, const mDNSu8 *const end, int minsize);
extern const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end);
-extern const mDNSu8 *LocateLeaseOptData(const DNSMessage *const msg, const mDNSu8 *const end);
extern mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end);
-extern void DumpPacket(mDNS *const m, mDNSBool sent, char *transport,
+extern void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *transport,
const mDNSAddr *srcaddr, mDNSIPPort srcport,
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end);
#pragma mark - RR List Management & Task Management
#endif
+extern void ShowTaskSchedulingError(mDNS *const m);
extern void mDNS_Lock_(mDNS *const m);
extern void mDNS_Unlock_(mDNS *const m);
+#if defined(_WIN32)
+ #define __func__ __FUNCTION__
+#endif
+
#define mDNS_Lock(X) do { \
if ((X)->mDNS_busy != (X)->mDNS_reentrancy) LogMsg("%s: mDNS_Lock locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy); \
mDNS_Lock_(X); } while (0)
Change History (most recent first):
$Log: DNSDigest.c,v $
+Revision 1.26 2008/10/10 23:21:51 mcguire
+fixed typo in original MD5 source reference
+
Revision 1.25 2007/12/17 23:48:29 cheshire
DNSDigest_SignMessage doesn't need to return a result -- it already updates the 'end' parameter
* Note: machine archetecure specific conditionals from the original sources are turned off, but are left in the code
* to aid in platform-specific optimizations and debugging.
* Sources originally distributed under the following license headers:
- * CommonDigest.c - APSL
+ * CommonDigest.h - APSL
*
* md32_Common.h
* ====================================================================
Change History (most recent first):
$Log: mDNS.c,v $
-Revision 1.777.4.5 2008/09/30 18:03:01 mcguire
+Revision 1.969.2.1 2009/07/23 23:41:25 cheshire
+<rdar://problem/7086623> Sleep Proxy: Ten-second maintenance wake not long enough to reliably get network connectivity
+
+Revision 1.969 2009/06/30 21:18:19 cheshire
+<rdar://problem/7020041> Plugging and unplugging the power cable shouldn't cause a network change event
+Additional fixes:
+1. Made mDNS_ActivateNetWake_internal and mDNS_DeactivateNetWake_internal more defensive against bad parameters
+2. mDNS_DeactivateNetWake_internal also needs to stop any outstanding Sleep Proxy resolve operations
+
+Revision 1.968 2009/06/29 23:51:09 cheshire
+<rdar://problem/6690034> Can't bind to Active Directory
+
+Revision 1.967 2009/06/27 00:25:27 cheshire
+<rdar://problem/6959273> mDNSResponder taking up 13% CPU with 400 KBps incoming bonjour requests
+Removed overly-complicate and ineffective multi-packet known-answer snooping code
+(Bracketed it with "#if ENABLE_MULTI_PACKET_QUERY_SNOOPING" for now; will delete actual code later)
+
+Revision 1.966 2009/06/26 01:55:55 cheshire
+<rdar://problem/6890712> mDNS: iChat's Buddy photo always appears as the "shadow person" over Bonjour
+Additional refinements -- except for the case of explicit queries for record types we don't have (for names we own),
+add additional NSEC records only when there's space to do that without having to generate an additional packet
+
+Revision 1.965 2009/06/24 22:14:21 cheshire
+<rdar://problem/6911445> Plugging and unplugging the power cable shouldn't cause a network change event
+
+Revision 1.964 2009/06/03 23:07:13 cheshire
+<rdar://problem/6890712> mDNS: iChat's Buddy photo always appears as the "shadow person" over Bonjour
+Large records were not being added in cases where an NSEC record was also required
+
+Revision 1.963 2009/05/28 00:39:19 cheshire
+<rdar://problem/6926465> Sleep is delayed by 10 seconds if BTMM is on
+After receiving confirmation of wide-area record deletion, need to schedule another evaluation of whether we're ready to sleep yet
+
+Revision 1.962 2009/05/19 23:40:37 cheshire
+<rdar://problem/6903507> Sleep Proxy: Retransmission logic not working reliably on quiet networks
+Added m->NextScheduledSPRetry timer for scheduling Sleep Proxy registration retries
+
+Revision 1.961 2009/05/19 23:00:43 cheshire
+Improved comments and debugging messages
+
+Revision 1.960 2009/05/13 17:25:33 mkrochma
+<rdar://problem/6879926> Should not schedule maintenance wake when machine has no advertised services
+Sleep proxy client should only look for services being advertised via Multicast
+
+Revision 1.959 2009/05/12 23:10:31 cheshire
+<rdar://problem/6879926> Should not schedule maintenance wake when machine has no advertised services
+Make new routine mDNSCoreHaveAdvertisedServices so daemon.c can tell whether it needs to schedule a maintenance wake
+
+Revision 1.958 2009/05/12 19:19:20 cheshire
+<rdar://problem/6879925> Sleep Proxy delays sleep by ten seconds when logged in to VPN
+
+Revision 1.957 2009/05/07 23:56:25 cheshire
+<rdar://problem/6601427> Retransmit and retry Sleep Proxy Server requests
+To get negative answers for our AAAA query we need to set the ReturnIntermed flag on the NetWakeResolve question
+
+Revision 1.956 2009/05/07 23:46:27 cheshire
+<rdar://problem/6601427> Retransmit and retry Sleep Proxy Server requests
+
+Revision 1.955 2009/05/07 23:40:54 cheshire
+Minor code rearrangement in preparation for upcoming changes
+
+Revision 1.954 2009/05/01 21:28:34 cheshire
+<rdar://problem/6721680> AppleConnectAgent's reachability checks delay sleep by 30 seconds
+No longer suspend network operations after we've acknowledged that the machine is going to sleep,
+because other software may not have yet acknowledged the sleep event, and may be still trying
+to do unicast DNS queries or other Bonjour operations.
+
+Revision 1.953 2009/05/01 19:17:35 cheshire
+<rdar://problem/6501561> Sleep Proxy: Reduce the frequency of maintenance wakes: ODD, fans, power
+
+Revision 1.952 2009/05/01 19:16:45 mcguire
+<rdar://problem/6846322> Crash: mDNS_vsnprintf + 1844
+
+Revision 1.951 2009/04/28 23:48:19 jessic2
+<rdar://problem/6830541> regservice_callback: instance->request is NULL 0
+
+Revision 1.950 2009/04/25 01:17:10 mcguire
+Fix spurious TCP connect failures uncovered by <rdar://problem/6729406> PPP doesn't automatically reconnect on wake from sleep
+
+Revision 1.949 2009/04/25 01:11:02 mcguire
+Refactor: create separate function: RestartRecordGetZoneData
+
+Revision 1.948 2009/04/24 21:25:16 cheshire
+<rdar://problem/6601002> Special case Net Assistant port so Apple Remote Desktop doesn't wake up every machine on the network
+
+Revision 1.947 2009/04/24 19:41:12 mcguire
+<rdar://problem/6791775> 4 second delay in DNS response
+
+Revision 1.946 2009/04/24 19:28:39 mcguire
+<rdar://problem/6791775> 4 second delay in DNS response
+
+Revision 1.945 2009/04/24 00:30:30 cheshire
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+Added code to generate and process NSEC records
+
+Revision 1.944 2009/04/23 22:06:29 cheshire
+Added CacheRecord and InterfaceID parameters to MakeNegativeCacheRecord, in preparation for:
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+
+Revision 1.943 2009/04/22 01:19:56 jessic2
+<rdar://problem/6814585> Daemon: mDNSResponder is logging garbage for error codes because it's using %ld for int 32
+
+Revision 1.942 2009/04/21 02:13:29 cheshire
+<rdar://problem/5270176> Local hostname changed even though there really isn't a name conflict
+Made code less susceptible to being tricked by stale packets echoed back from the network.
+
+Revision 1.941 2009/04/15 22:22:23 mcguire
+<rdar://problem/6768947> uDNS: Treat RCODE 5 (Refused) responses as failures
+Additional fix: protect against deref of NULL
+
+Revision 1.940 2009/04/15 20:42:51 mcguire
+<rdar://problem/6768947> uDNS: Treat RCODE 5 (Refused) responses as failures
+
+Revision 1.939 2009/04/11 00:19:32 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.938 2009/04/06 23:44:57 cheshire
+<rdar://problem/6757838> mDNSResponder thrashing kernel lock in the UDP close path, hurting SPECweb performance
+
+Revision 1.937 2009/04/04 00:14:49 mcguire
+fix logging in BeginSleepProcessing
+
+Revision 1.936 2009/04/04 00:10:59 mcguire
+don't ignore m->SystemWakeOnLANEnabled when going to sleep
+
+Revision 1.935 2009/04/01 17:50:11 mcguire
+cleanup mDNSRandom
+
+Revision 1.934 2009/03/27 17:17:58 cheshire
+Improved "Ignoring suspect uDNS response" debugging message
+
+Revision 1.933 2009/03/21 02:40:21 cheshire
+<rdar://problem/6704514> uDNS: Need to create negative cache entries for "local" SOA
+
+Revision 1.932 2009/03/20 23:53:03 jessic2
+<rdar://problem/6646228> SIGHUP should restart all in-progress queries
+
+Revision 1.931 2009/03/18 19:08:15 cheshire
+Show old/new sleep sequence numbers in logical order
+
+Revision 1.930 2009/03/17 23:40:45 cheshire
+For now only try the highest-ranked Sleep Proxy; fixed come compiler warnings
+
+Revision 1.929 2009/03/17 21:55:56 cheshire
+Fixed mistake in logic for decided when we're ready to go to sleep
+
+Revision 1.928 2009/03/17 19:48:12 cheshire
+<rdar://problem/6688927> Don't cache negative unicast answers for Multicast DNS names
+
+Revision 1.927 2009/03/17 01:22:56 cheshire
+<rdar://problem/6601427> Sleep Proxy: Retransmit and retry Sleep Proxy Server requests
+Initial support for resolving up to three Sleep Proxies in parallel
+
+Revision 1.926 2009/03/17 01:05:07 mcguire
+<rdar://problem/6657640> Reachability fixes on DNS config change
+
+Revision 1.925 2009/03/13 01:35:36 mcguire
+<rdar://problem/6657640> Reachability fixes on DNS config change
+
+Revision 1.924 2009/03/10 23:45:20 cheshire
+Added comments explaining usage of SetSPSProxyListChanged()
+
+Revision 1.923 2009/03/09 21:53:02 cheshire
+<rdar://problem/6650479> Sleep Proxy: Need to stop proxying when it sees an ARP probe from the client
+
+Revision 1.922 2009/03/09 21:30:17 cheshire
+Improved some LogSPS messages; made RestartProbing() subroutine
+
+Revision 1.921 2009/03/06 22:53:31 cheshire
+Don't bother registering with Sleep Proxy if we have no advertised services
+
+Revision 1.920 2009/03/06 20:08:55 cheshire
+<rdar://problem/6601429> Sleep Proxy: Return error responses to clients
+
+Revision 1.919 2009/03/05 21:54:43 cheshire
+Improved "Sleep Proxy Server started / stopped" message
+
+Revision 1.918 2009/03/04 01:37:14 cheshire
+<rdar://problem/6601428> Limit maximum number of records that a Sleep Proxy Server will accept
+
+Revision 1.917 2009/03/03 23:14:25 cheshire
+Got rid of code duplication by making subroutine "SetupOwnerOpt"
+
+Revision 1.916 2009/03/03 23:04:43 cheshire
+For clarity, renamed "MAC" field to "HMAC" (Host MAC, as opposed to Interface MAC)
+
+Revision 1.915 2009/03/03 22:51:53 cheshire
+<rdar://problem/6504236> Sleep Proxy: Waking on same network but different interface will cause conflicts
+
+Revision 1.914 2009/03/03 00:46:09 cheshire
+Additional debugging information in ResolveSimultaneousProbe
+
+Revision 1.913 2009/02/27 03:08:47 cheshire
+<rdar://problem/6547720> Crash while shutting down when "local" is in the user's DNS searchlist
+
+Revision 1.912 2009/02/27 02:31:28 cheshire
+Improved "Record not found in list" debugging message
+
+Revision 1.911 2009/02/21 01:42:11 cheshire
+Updated log messages
+
+Revision 1.910 2009/02/19 01:50:53 cheshire
+Converted some LogInfo messages to LogSPS
+
+Revision 1.909 2009/02/14 00:04:59 cheshire
+Left-justify interface names
+
+Revision 1.908 2009/02/13 19:40:07 cheshire
+Improved alignment of LogSPS messages
+
+Revision 1.907 2009/02/13 18:16:05 cheshire
+Fixed some compile warnings
+
+Revision 1.906 2009/02/13 06:10:17 cheshire
+Convert LogOperation messages to LogInfo
+
+Revision 1.905 2009/02/12 20:57:24 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.904 2009/02/11 02:37:29 cheshire
+m->p->SystemWakeForNetworkAccessEnabled renamed to m->SystemWakeOnLANEnabled
+Moved code to send goodbye packets from mDNSCoreMachineSleep into BeginSleepProcessing,
+so that it happens correctly even when we delay re-sleep due to a very short wakeup.
+
+Revision 1.903 2009/02/09 23:34:31 cheshire
+Additional logging for debugging unknown packets
+
+Revision 1.902 2009/02/07 05:57:01 cheshire
+Fixed debugging log message
+
+Revision 1.901 2009/02/07 02:57:31 cheshire
+<rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+
+Revision 1.900 2009/02/02 21:29:24 cheshire
+<rdar://problem/4786302> Implement logic to determine when to send dot-local lookups via Unicast
+If Negative response for our special Microsoft Active Directory "local SOA" check has no
+SOA record in the authority section, assume we should cache the negative result for 24 hours
+
+Revision 1.899 2009/01/31 00:37:50 cheshire
+When marking cache records for deletion in response to a uDNS response,
+make sure InterfaceID matches (i.e. it should be NULL for a uDNS cache record)
+
+Revision 1.898 2009/01/30 23:49:20 cheshire
+Exclude mDNSInterface_Unicast from "InterfaceID ... not currently found" test
+
+Revision 1.897 2009/01/30 22:04:49 cheshire
+Workaround to reduce load on root name servers when caching the SOA record for "."
+
+Revision 1.896 2009/01/30 22:00:05 cheshire
+Made mDNS_StartQuery_internal pay attention to mDNSInterface_Unicast
+
+Revision 1.895 2009/01/30 17:46:39 cheshire
+Improved debugging messages for working out why spurious name conflicts are happening
+
+Revision 1.894 2009/01/30 00:22:09 cheshire
+<rdar://problem/6540743> No announcement after probing & no conflict notice
+
+Revision 1.893 2009/01/29 22:27:03 mcguire
+<rdar://problem/6407429> Cleanup: Logs about Unknown DNS packet type 5450
+
+Revision 1.892 2009/01/24 01:38:23 cheshire
+Fixed error in logic for targeted queries
+
+Revision 1.891 2009/01/22 02:14:25 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.890 2009/01/22 00:45:02 cheshire
+Improved SPS debugging log messages; we are eligible to start answering ARP requests
+after we send our first announcement, not after we send our last probe
+
+Revision 1.889 2009/01/21 03:43:56 mcguire
+<rdar://problem/6511765> BTMM: Add support for setting kDNSServiceErr_NATPortMappingDisabled in DynamicStore
+
+Revision 1.888 2009/01/20 00:27:43 mcguire
+<rdar://problem/6305725> when removing a uDNS record, if a dup exists, copy information to it
+
+Revision 1.887 2009/01/17 05:14:37 cheshire
+Convert SendQueries Probe messages to LogSPS messages
+
+Revision 1.886 2009/01/17 03:43:09 cheshire
+Added SPSLogging switch to facilitate Sleep Proxy Server debugging
+
+Revision 1.885 2009/01/16 22:44:18 cheshire
+<rdar://problem/6402123> Sleep Proxy: Begin ARP Announcements sooner
+
+Revision 1.884 2009/01/16 21:43:52 cheshire
+Let InitializeLastAPTime compute the correct interval, instead of having it passed in as a parameter
+
+Revision 1.883 2009/01/16 21:11:18 cheshire
+When purging expired Sleep Proxy records, need to check DuplicateRecords list too
+
+Revision 1.882 2009/01/16 19:54:28 cheshire
+Use symbols "SleepProxyServiceType" and "localdomain" instead of literal strings
+
+Revision 1.881 2009/01/14 01:38:38 mcguire
+<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
+
+Revision 1.880 2009/01/10 01:51:19 cheshire
+q->CurrentAnswers not being incremented/decremented when answering a question with a local AuthRecord
+
+Revision 1.879 2009/01/10 01:43:52 cheshire
+Changed misleading function name 'AnsweredLOQ' to more informative 'AnsweredLocalQ'
+
+Revision 1.878 2009/01/10 01:38:10 cheshire
+Changed misleading function name 'AnswerLocalOnlyQuestionWithResourceRecord' to more informative 'AnswerLocalQuestionWithLocalAuthRecord'
+
+Revision 1.877 2009/01/10 01:36:08 cheshire
+Changed misleading function name 'AnswerLocalOnlyQuestions' to more informative 'AnswerAllLocalQuestionsWithLocalAuthRecord'
+
+Revision 1.876 2009/01/09 22:56:06 cheshire
+Don't touch rr after calling mDNS_Deregister_internal -- the memory may have been free'd
+
+Revision 1.875 2009/01/09 22:54:46 cheshire
+When tranferring record from DuplicateRecords list to ResourceRecords list,
+need to copy across state of 'Answered Local-Only-Questions' flag
+
+Revision 1.874 2009/01/07 23:07:24 cheshire
+<rdar://problem/6479416> SPS Client not canceling outstanding resolve call before sleeping
+
+Revision 1.873 2008/12/17 00:18:59 mkrochma
+Change some LogMsg to LogOperation before submitting
+
+Revision 1.872 2008/12/12 01:30:40 cheshire
+Update platform-layer BPF filters when we add or remove AddressProxy records
+
+Revision 1.871 2008/12/10 02:25:31 cheshire
+Minor fixes to use of LogClientOperations symbol
+
+Revision 1.870 2008/12/10 02:11:41 cheshire
+ARMv5 compiler doesn't like uncommented stuff after #endif
+
+Revision 1.869 2008/12/05 02:35:24 mcguire
+<rdar://problem/6107390> Write to the DynamicStore when a Sleep Proxy server is available on the network
+
+Revision 1.868 2008/12/04 21:08:51 mcguire
+<rdar://problem/6116863> mDNS: Provide mechanism to disable Multicast advertisements
+
+Revision 1.867 2008/11/26 21:19:36 cheshire
+<rdar://problem/6374334> Sleeping Server should choose the best Sleep Proxy by using advertised metrics
+
+Revision 1.866 2008/11/26 20:32:46 cheshire
+<rdar://problem/6374328> Sleep Proxy: Advertise BSP metrics in service name
+Update advertised name when Sleep Proxy "intent" metric changes
+
+Revision 1.865 2008/11/26 19:49:25 cheshire
+Record originally-requested port in sr->NATinfo.IntPort
+
+Revision 1.864 2008/11/26 19:02:37 cheshire
+Don't answer ARP Probes from owner machine as it wakes up and rejoins the network
+
+Revision 1.863 2008/11/26 03:59:03 cheshire
+Wait 30 seconds before starting ARP Announcements
+
+Revision 1.862 2008/11/25 23:43:07 cheshire
+<rdar://problem/5745355> Crashes at ServiceRegistrationGotZoneData + 397
+Made code more defensive to guard against ServiceRegistrationGotZoneData being called with invalid ServiceRecordSet object
+
+Revision 1.861 2008/11/25 22:46:30 cheshire
+For ease of code searching, renamed ZoneData field of ServiceRecordSet_struct from "nta" to "srs_nta"
+
+Revision 1.860 2008/11/25 05:07:15 cheshire
+<rdar://problem/6374328> Advertise Sleep Proxy metrics in service name
+
+Revision 1.859 2008/11/20 02:07:56 cheshire
+<rdar://problem/6387470> Refresh our NAT mappings on wake from sleep
+
+Revision 1.858 2008/11/20 01:38:36 cheshire
+For consistency with other parts of the code, changed code to only check
+that the first 4 bytes of MAC address are zero, not the whole 6 bytes.
+
+Revision 1.857 2008/11/14 22:55:18 cheshire
+Fixed log messages
+
+Revision 1.856 2008/11/14 21:08:28 cheshire
+Only put owner option in query packet if we have a non-zero MAC address to put
+Only process owner options in received query packets if the MAC address in the option is non-zero
+
+Revision 1.855 2008/11/14 02:29:54 cheshire
+If Sleep Proxy client fails to renew proxy records before they expire, remove them from our m->ResourceRecords list
+
+Revision 1.854 2008/11/14 00:00:53 cheshire
+After client machine wakes up, Sleep Proxy machine need to remove any records
+it was temporarily holding as proxy for that client
+
+Revision 1.853 2008/11/13 19:07:30 cheshire
+Added code to put OPT record, containing owner and lease lifetime, into SPS registration packet
+
+Revision 1.852 2008/11/12 23:23:11 cheshire
+Before waking a host, check to see if it has an SRV record advertising
+a service on the port in question, and if not, don't bother waking it.
+
+Revision 1.851 2008/11/12 01:54:15 cheshire
+<rdar://problem/6338021> Add domain back to end of _services._dns-sd._udp PTR records
+It turns out it is beneficial to have the domain on the end, because it allows better name compression
+
+Revision 1.850 2008/11/11 01:56:57 cheshire
+Improved name conflict log messages
+
+Revision 1.849 2008/11/06 23:50:43 cheshire
+Allow plain (non-SYN) ssh data packets to wake sleeping host
+
+Revision 1.848 2008/11/05 02:40:28 mkrochma
+Change mDNS_SetFQDN syslog mesage to debugf
+
+Revision 1.847 2008/11/04 23:06:50 cheshire
+Split RDataBody union definition into RDataBody and RDataBody2, and removed
+SOA from the normal RDataBody union definition, saving 270 bytes per AuthRecord
+
+Revision 1.846 2008/11/04 22:21:44 cheshire
+Changed zone field of AuthRecord_struct from domainname to pointer, saving 252 bytes per AuthRecord
+
+Revision 1.845 2008/11/03 23:52:05 cheshire
+Improved ARP debugging messages to differentiate ARP Announcements from Requests
+
+Revision 1.844 2008/10/31 23:43:51 cheshire
+Fixed compile error in Posix build
+
+Revision 1.843 2008/10/31 22:55:04 cheshire
+Initial support for structured SPS names
+
+Revision 1.842 2008/10/30 00:12:07 cheshire
+Fixed spin when PutSPSRec fails to put a record because it's too big to fit
+
+Revision 1.841 2008/10/29 23:23:38 cheshire
+Refined cache size reporting to go in steps of 1000 when number is above 1000
+
+Revision 1.840 2008/10/29 21:34:10 cheshire
+Removed some old debugging messages
+
+Revision 1.839 2008/10/29 21:31:32 cheshire
+Five seconds not always enough time for machine to go to sleep -- increased to ten seconds
+
+Revision 1.838 2008/10/28 18:30:37 cheshire
+Added debugging message in mDNSCoreReceiveRawPacket
+
+Revision 1.837 2008/10/24 23:58:05 cheshire
+Wake up for Back to My Mac IPSEC packets, except NAT keepalive packets
+
+Revision 1.836 2008/10/24 23:18:18 cheshire
+If we have a Sleep Proxy Server, don't remove service registrations from the DNS server
+
+Revision 1.835 2008/10/24 23:07:59 cheshire
+Wake SPS client if we receive conflicting mDNS respoonse (record with same name as one of our unique records, but different rdata)
+
+Revision 1.834 2008/10/24 23:03:24 cheshire
+Wake SPS client if we receive a conflicting ARP (some other machine claiming to own that IP address)
+
+Revision 1.833 2008/10/24 23:01:26 cheshire
+To reduce spurious wakeups for now, we'll only wake for incoming TCP SYN packets
+
+Revision 1.832 2008/10/24 22:58:24 cheshire
+For now, since we don't get IPv6 ND or data packets, don't advertise AAAA records for our SPS clients
+
+Revision 1.831 2008/10/24 22:50:41 cheshire
+When waking SPS client, include interface name in syslog message
+
+Revision 1.830 2008/10/24 20:50:34 cheshire
+Use "#if USE_SEPARATE_UDNS_SERVICE_LIST" instead of "#if defined(USE_SEPARATE_UDNS_SERVICE_LIST)"
+
+Revision 1.829 2008/10/23 23:55:57 cheshire
+Fixed some missing "const" declarations
+
+Revision 1.828 2008/10/23 22:25:56 cheshire
+Renamed field "id" to more descriptive "updateid"
+
+Revision 1.827 2008/10/23 03:06:25 cheshire
+Fixed "Waking host" log message
+
+Revision 1.826 2008/10/22 23:21:30 cheshire
+Make sure we have enough bytes before reading into the transport-level header
+
+Revision 1.825 2008/10/22 22:31:53 cheshire
+Log SYN/FIN/RST bits from TCP header, and don't wake for FIN/RST
+
+Revision 1.824 2008/10/22 20:00:31 cheshire
+If we ourselves go to sleep, stop advertising sleep proxy service, then re-advertise after we wake up
+
+Revision 1.823 2008/10/22 19:55:35 cheshire
+Miscellaneous fixes; renamed FindFirstAnswerInCache to FindSPSInCache
+
+Revision 1.822 2008/10/22 01:41:39 cheshire
+Set question->ThisQInterval back to -1 after we cancel our NetWakeResolve
+
+Revision 1.821 2008/10/22 01:12:53 cheshire
+Answer ARP Requests for any IP address we're proxying for
+
+Revision 1.820 2008/10/21 01:11:11 cheshire
+Added mDNSCoreReceiveRawPacket for handling raw packets received by platform layer
+
+Revision 1.819 2008/10/20 22:16:27 cheshire
+Updated comments; increased cache shedding threshold from 3000 to 4000
+
+Revision 1.818 2008/10/16 22:01:54 cheshire
+Fix last checkin: Should be "ar->resrec.rdata->u.data", not "ar->resrec.rdata.u.data"
+
+Revision 1.817 2008/10/16 21:40:49 cheshire
+Need to set ar->resrec.rdlength correctly before calling mDNS_Register_internal()
+
+Revision 1.816 2008/10/15 23:12:36 cheshire
+On receiving SPS registration from client, broadcast ARP Announcements claiming ownership of that IP address
+
+Revision 1.815 2008/10/15 20:46:38 cheshire
+When transferring records to SPS, include Lease Option
+
+Revision 1.814 2008/10/15 19:51:27 cheshire
+Change "NOTE:" to "Note:" so that BBEdit 9 stops putting those lines into the funtion popup menu
+
+Revision 1.813 2008/10/15 00:09:23 cheshire
+When acting as Sleep Proxy Server, handle DNS Updates received from SPS clients on the network
+
+Revision 1.812 2008/10/15 00:01:40 cheshire
+When going to sleep, discover and resolve SPS, and if successful, transfer records to it
+
+Revision 1.811 2008/10/14 23:51:57 cheshire
+Created new routine GetRDLengthMem() to compute the in-memory storage requirements for particular rdata
+
+Revision 1.810 2008/10/14 21:37:55 cheshire
+Removed unnecessary m->BeSleepProxyServer variable
+
+Revision 1.809 2008/10/10 23:45:48 cheshire
+For ForceMCast records, SetTargetToHostName should use the dot-local multicast hostname,
+not a wide-area unicast hostname
+
+Revision 1.808 2008/10/09 18:59:19 cheshire
+Added NetWakeResolve code, removed unused m->SendDeregistrations and m->SendImmediateAnswers
+
+Revision 1.807 2008/10/07 15:56:58 cheshire
+Fixed "unused variable" warnings in non-debug builds
+
+Revision 1.806 2008/10/04 00:53:37 cheshire
+On interfaces that support Wake-On-LAN, browse to discover Sleep Proxy Servers
+
+Revision 1.805 2008/10/03 18:17:28 cheshire
+<rdar://problem/6134215> Sleep Proxy: Mac with Internet Sharing should also offer Sleep Proxy service
+Update advertised Sleep Proxy Server name if user changes computer name
+
+Revision 1.804 2008/10/03 01:26:06 mcguire
+<rdar://problem/6266145> mDNS_FinalExit failed to send goodbye for duplicate uDNS records
+Put back Duplicate Record check
+
+Revision 1.803 2008/10/02 23:38:56 mcguire
+<rdar://problem/6266145> mDNS_FinalExit failed to send goodbye for duplicate uDNS records
+
+Revision 1.802 2008/10/02 23:13:48 cheshire
+<rdar://problem/6134215> Sleep Proxy: Mac with Internet Sharing should also offer Sleep Proxy service
+Need to drop lock before calling "mDNSCoreBeSleepProxyServer(m, mDNSfalse);"
+
+Revision 1.801 2008/10/02 22:51:04 cheshire
+<rdar://problem/6134215> Sleep Proxy: Mac with Internet Sharing should also offer Sleep Proxy service
+Added mDNSCoreBeSleepProxyServer() routine to start and stop Sleep Proxy Service
+
+Revision 1.800 2008/10/02 22:13:15 cheshire
+<rdar://problem/6230680> 100ms delay on shutdown
+Additional refinement: Also need to clear m->SuppressSending
+
+Revision 1.799 2008/09/29 20:12:37 cheshire
+Rename 'AnswerLocalQuestions' to more descriptive 'AnswerLocalOnlyQuestions' and 'AnsweredLocalQ' to 'AnsweredLOQ'
+
+Revision 1.798 2008/09/26 19:53:14 cheshire
+Fixed locking error: should not call mDNS_Deregister_internal within "mDNS_DropLock" section
+
+Revision 1.797 2008/09/25 20:40:59 cheshire
+<rdar://problem/6245044> Stop using separate m->ServiceRegistrations list
+In mDNS_SetFQDN, need to update all AutoTarget SRV records, even if m->MulticastHostname hasn't changed
+
+Revision 1.796 2008/09/25 20:17:10 cheshire
+<rdar://problem/6245044> Stop using separate m->ServiceRegistrations list
+Added defensive code to make sure *all* records of a ServiceRecordSet have
+completed deregistering before we pass on the mStatus_MemFree message
+
+Revision 1.795 2008/09/25 00:30:11 cheshire
+<rdar://problem/6245044> Stop using separate m->ServiceRegistrations list
+
+Revision 1.794 2008/09/24 23:48:05 cheshire
+Don't need to pass whole ServiceRecordSet reference to GetServiceTarget;
+it only needs to access the embedded SRV member of the set
+
+Revision 1.793 2008/09/23 04:11:53 cheshire
+<rdar://problem/6238774> Remove "local" from the end of _services._dns-sd._udp PTR records
+
+Revision 1.792 2008/09/23 02:30:07 cheshire
+Get rid of PutResourceRecordCappedTTL()
+
+Revision 1.791 2008/09/20 00:34:21 mcguire
<rdar://problem/6129039> BTMM: Add support for WANPPPConnection
-Revision 1.777.4.4 2008/08/14 20:43:59 cheshire
-<rdar://problem/6143846> Back to My Mac not working with Time Capsule shared volume
+Revision 1.790 2008/09/18 22:46:34 cheshire
+<rdar://problem/6230680> 100ms delay on shutdown
+
+Revision 1.789 2008/09/18 06:15:06 mkrochma
+<rdar://problem/6117156> Cleanup: mDNSResponder logging debugging information to console
+
+Revision 1.788 2008/09/16 21:11:41 cheshire
+<rdar://problem/6223969> mDNS: Duplicate TXT record queries being produced by iPhone Remote
+
+Revision 1.787 2008/09/05 22:53:24 cheshire
+Improve "How is rr->resrec.rroriginalttl <= SecsSinceRcvd" debugging message
+
+Revision 1.786 2008/09/05 22:23:28 cheshire
+Moved initialization of "question->LocalSocket" to more logical place
+
+Revision 1.785 2008/08/14 19:20:55 cheshire
+<rdar://problem/6143846> Negative responses over TCP incorrectly rejected
-Revision 1.777.4.3 2008/07/29 20:46:05 mcguire
-<rdar://problem/6090007> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-merge r1.782 & r1.783 from <rdar://problem/3988320>
+Revision 1.784 2008/08/13 00:47:53 mcguire
+Handle failures when packet logging
-Revision 1.777.4.2 2008/07/29 20:13:52 mcguire
-<rdar://problem/6090024> BTMM: alternate SSDP queries between multicast & unicast
-merged r1.781 for <rdar://problem/5736845>
+Revision 1.783 2008/07/25 07:09:51 mcguire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-Revision 1.777.4.1 2008/07/29 19:17:55 mcguire
-<rdar://problem/6090046> Only trigger reconfirm on hostname if both A and AAAA query fail to elicit a response
-merge r1.779, r.1780 from <rdar://problem/6041178>
+Revision 1.782 2008/07/24 20:23:03 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+
+Revision 1.781 2008/07/18 21:37:35 mcguire
+<rdar://problem/5736845> BTMM: alternate SSDP queries between multicast & unicast
+
+Revision 1.780 2008/07/18 02:24:36 cheshire
+<rdar://problem/6041178> Only trigger reconfirm on hostname if both A and AAAA query fail to elicit a response
+Additional fix: Don't want to do the ReconfirmAntecedents() stuff if q->RequestUnicast is set (that indicates
+we're still on our first or second query after an interface registration or wake from sleep).
+
+Revision 1.779 2008/07/18 01:05:23 cheshire
+<rdar://problem/6041178> Only trigger reconfirm on hostname if both A and AAAA query fail to elicit a response
+
+Revision 1.778 2008/06/26 17:24:11 mkrochma
+<rdar://problem/5450912> BTMM: Stop listening on UDP 5351 for NAT Status Announcements
Revision 1.777 2008/06/19 01:20:48 mcguire
<rdar://problem/4206534> Use all configured DNS servers
Revision 1.690 2007/09/05 21:48:01 cheshire
<rdar://problem/5385864> BTMM: mDNSResponder flushes wide-area Bonjour records after an hour for a zone.
-Now that we're respecting the TTL of uDNS records in the cache, the LLQ maintenance cod needs
+Now that we're respecting the TTL of uDNS records in the cache, the LLQ maintenance code needs
to update the cache lifetimes of all relevant records every time it successfully renews an LLQ,
otherwise those records will expire and vanish from the cache.
For naming consistency, kDNSRecordTypeNegative should be kDNSRecordTypePacketNegative
Revision 1.608 2007/04/20 19:45:31 cheshire
-In LogAllOperations mode, dump out unknown DNS packets in their entirety
+In LogClientOperations mode, dump out unknown DNS packets in their entirety
Revision 1.607 2007/04/19 23:56:25 cheshire
Don't do cache-flush processing for LLQ answers
#pragma warning(disable:4706)
#endif
+// Forward declarations
+mDNSlocal void BeginSleepProcessing(mDNS *const m);
+mDNSlocal void RetrySPSRegistrations(mDNS *const m);
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Program Constants
return(mDNSfalse);
}
+mDNSlocal NetworkInterfaceInfo *FirstInterfaceForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
+ {
+ NetworkInterfaceInfo *intf = m->HostInterfaces;
+ while (intf && intf->InterfaceID != InterfaceID) intf = intf->next;
+ return(intf);
+ }
+
+mDNSlocal char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
+ {
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
+ return(intf ? intf->ifname : "<NULL InterfaceID>");
+ }
+
// For a single given DNSQuestion, deliver an add/remove result for the single given AuthRecord
-// Used by AnswerLocalQuestions() and AnswerNewLocalOnlyQuestion()
-mDNSlocal void AnswerLocalOnlyQuestionWithResourceRecord(mDNS *const m, DNSQuestion *q, AuthRecord *rr, QC_result AddRecord)
+// Used by AnswerAllLocalQuestionsWithLocalAuthRecord() and AnswerNewLocalOnlyQuestion()
+mDNSlocal void AnswerLocalQuestionWithLocalAuthRecord(mDNS *const m, DNSQuestion *q, AuthRecord *rr, QC_result AddRecord)
{
// Indicate that we've given at least one positive answer for this record, so we should be prepared to send a goodbye for it
if (AddRecord) rr->AnsweredLocalQ = mDNStrue;
mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
if (q->QuestionCallback && !q->NoAnswer)
+ {
+ q->CurrentAnswers += AddRecord ? 1 : -1;
q->QuestionCallback(m, q, &rr->resrec, AddRecord);
+ }
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
-// When a new local AuthRecord is created or deleted, AnswerLocalQuestions() runs though our LocalOnlyQuestions delivering answers
-// to each, stopping if it reaches a NewLocalOnlyQuestion -- brand-new questions are handled by AnswerNewLocalOnlyQuestion().
+// When a new local AuthRecord is created or deleted, AnswerAllLocalQuestionsWithLocalAuthRecord() runs though
+// all our local questions (both LocalOnlyQuestions and mDNSInterface_Any questions) delivering answers to each,
+// stopping if it reaches a NewLocalOnlyQuestion -- brand-new questions are handled by AnswerNewLocalOnlyQuestion().
// If the AuthRecord is marked mDNSInterface_LocalOnly, then we also deliver it to any other questions we have using mDNSInterface_Any.
// Used by AnswerForNewLocalRecords() and mDNS_Deregister_internal()
-mDNSlocal void AnswerLocalQuestions(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
+mDNSlocal void AnswerAllLocalQuestionsWithLocalAuthRecord(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
{
if (m->CurrentQuestion)
- LogMsg("AnswerLocalQuestions ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
+ LogMsg("AnswerAllLocalQuestionsWithLocalAuthRecord ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
m->CurrentQuestion = m->LocalOnlyQuestions;
while (m->CurrentQuestion && m->CurrentQuestion != m->NewLocalOnlyQuestions)
DNSQuestion *q = m->CurrentQuestion;
m->CurrentQuestion = q->next;
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
- AnswerLocalOnlyQuestionWithResourceRecord(m, q, rr, AddRecord); // MUST NOT dereference q again
+ AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, AddRecord); // MUST NOT dereference q again
}
// If this AuthRecord is marked LocalOnly, then we want to deliver it to all local 'mDNSInterface_Any' questions
DNSQuestion *q = m->CurrentQuestion;
m->CurrentQuestion = q->next;
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
- AnswerLocalOnlyQuestionWithResourceRecord(m, q, rr, AddRecord); // MUST NOT dereference q again
+ AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, AddRecord); // MUST NOT dereference q again
}
}
// When sending a unique record, all other records matching "SameResourceRecordSignature" must also be sent
// When receiving a unique record, all old cache records matching "SameResourceRecordSignature" are flushed
-mDNSlocal mDNSBool SameResourceRecordSignature(const AuthRecord *const r1, const AuthRecord *const r2)
+// SameResourceRecordNameClassInterface is functionally the same as SameResourceRecordSignature, except rrtype does not have to match
+
+#define SameResourceRecordSignature(A,B) (A)->resrec.rrtype == (B)->resrec.rrtype && SameResourceRecordNameClassInterface((A),(B))
+
+mDNSlocal mDNSBool SameResourceRecordNameClassInterface(const AuthRecord *const r1, const AuthRecord *const r2)
{
if (!r1) { LogMsg("SameResourceRecordSignature ERROR: r1 is NULL"); return(mDNSfalse); }
if (!r2) { LogMsg("SameResourceRecordSignature ERROR: r2 is NULL"); return(mDNSfalse); }
r2->resrec.InterfaceID &&
r1->resrec.InterfaceID != r2->resrec.InterfaceID) return(mDNSfalse);
return(mDNSBool)(
- r1->resrec.rrtype == r2->resrec.rrtype &&
r1->resrec.rrclass == r2->resrec.rrclass &&
r1->resrec.namehash == r2->resrec.namehash &&
SameDomainName(r1->resrec.name, r2->resrec.name));
// complete ownership of *all* types for this name, so *any* record type with the same name is a conflict.
// In addition, when probing we send our questions with the wildcard type kDNSQType_ANY,
// so a response of any type should match, even if it is not actually the type the client plans to use.
+
+// For now, to make it easier to avoid false conflicts, we treat SPS Proxy records like shared records,
+// and require the rrtypes to match for the rdata to be considered potentially conflicting
mDNSlocal mDNSBool PacketRRMatchesSignature(const CacheRecord *const pktrr, const AuthRecord *const authrr)
{
if (!pktrr) { LogMsg("PacketRRMatchesSignature ERROR: pktrr is NULL"); return(mDNSfalse); }
if (pktrr->resrec.InterfaceID &&
authrr->resrec.InterfaceID &&
pktrr->resrec.InterfaceID != authrr->resrec.InterfaceID) return(mDNSfalse);
- if (!(authrr->resrec.RecordType & kDNSRecordTypeUniqueMask) && pktrr->resrec.rrtype != authrr->resrec.rrtype) return(mDNSfalse);
+ if (!(authrr->resrec.RecordType & kDNSRecordTypeUniqueMask) || authrr->WakeUp.HMAC.l[0])
+ if (pktrr->resrec.rrtype != authrr->resrec.rrtype) return(mDNSfalse);
return(mDNSBool)(
pktrr->resrec.rrclass == authrr->resrec.rrclass &&
pktrr->resrec.namehash == authrr->resrec.namehash &&
{
if (rr->resrec.RecordType == kDNSRecordTypeUnique)
{
- //LogMsg("ProbeCount %d Next %ld %s",
- // rr->ProbeCount, (rr->LastAPTime + rr->ThisAPInterval) - m->timenow, ARDisplayString(m, rr));
+ //LogMsg("ProbeCount %d Next %ld %s", rr->ProbeCount, (rr->LastAPTime + rr->ThisAPInterval) - m->timenow, ARDisplayString(m, rr));
if (m->NextScheduledProbe - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
m->NextScheduledProbe = (rr->LastAPTime + rr->ThisAPInterval);
}
}
}
-mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr, mDNSs32 interval)
+mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
{
- rr->ThisAPInterval = interval;
+ // For reverse-mapping Sleep Proxy PTR records, probe interval is one second
+ rr->ThisAPInterval = rr->AddressProxy.type ? mDNSPlatformOneSecond : DefaultAPIntervalForRecordType(rr->resrec.RecordType);
// To allow us to aggregate probes when a group of services are registered together,
// the first probe is delayed 1/4 second. This means the common-case behaviour is:
}
}
- rr->LastAPTime = m->SuppressProbes - interval;
+ rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval;
// Set LastMCTime to now, to inhibit multicast responses
// (no need to send additional multicast responses when we're announcing anyway)
rr->LastMCTime = m->timenow;
// delayed by a few milliseconds, this announcement does not inadvertently go out *before* the probing is complete.
// When the probing is complete and those records begin to announce, these records will also be picked up and accelerated,
// because they will meet the criterion of being at least half-way to their scheduled announcement time.
+ if (rr->resrec.RecordType != kDNSRecordTypeUnique)
+ rr->LastAPTime += DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + rr->ThisAPInterval / 2;
+
// The exception is unique records that have already been verified and are just being updated
// via mDNS_Update() -- for these we want to announce the new value immediately, without delay.
if (rr->resrec.RecordType == kDNSRecordTypeVerified)
- rr->LastAPTime = m->timenow - interval;
- else if (rr->resrec.RecordType != kDNSRecordTypeUnique)
- rr->LastAPTime += DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + interval / 2;
+ rr->LastAPTime = m->timenow - rr->ThisAPInterval;
+
+ // For reverse-mapping Sleep Proxy PTR records we don't want to start probing instantly -- we
+ // wait one second to give the client a chance to go to sleep, and then start our ARP/NDP probing.
+ // After three probes one second apart with no answer, we conclude the client is now sleeping
+ // and we can begin broadcasting our announcements to take over ownership of that IP address.
+ // If we don't wait for the client to go to sleep, then when the client sees our ARP Announcements there's a risk
+ // (depending on the OS and networking stack it's using) that it might interpret it as a conflict and change its IP address.
+ if (rr->AddressProxy.type) rr->LastAPTime = m->timenow;
+
+ // For now, since we don't yet handle IPv6 ND or data packets, we send deletions for our SPS clients' AAAA records
+ if (rr->WakeUp.HMAC.l[0] && rr->resrec.rrtype == kDNSType_AAAA)
+ rr->LastAPTime = m->timenow - rr->ThisAPInterval + mDNSPlatformOneSecond * 10;
SetNextAnnounceProbeTime(m, rr);
}
// Eventually we should unify this with GetServiceTarget() in uDNS.c
mDNSlocal void SetTargetToHostName(mDNS *const m, AuthRecord *const rr)
{
- domainname *target = GetRRDomainNameTarget(&rr->resrec);
+ domainname *const target = GetRRDomainNameTarget(&rr->resrec);
+ const domainname *newname = &m->MulticastHostname;
if (!target) debugf("SetTargetToHostName: Don't know how to set the target of rrtype %d", rr->resrec.rrtype);
- if (target && SameDomainName(target, &m->MulticastHostname))
+ if (!(rr->ForceMCast || rr->resrec.InterfaceID == mDNSInterface_LocalOnly || IsLocalDomain(&rr->namestorage)))
+ {
+ const domainname *const n = GetServiceTarget(m, rr);
+ if (n) newname = n;
+ }
+
+ if (target && SameDomainName(target, newname))
debugf("SetTargetToHostName: Target of %##s is already %##s", rr->resrec.name->c, target->c);
- if (target && !SameDomainName(target, &m->MulticastHostname))
+ if (target && !SameDomainName(target, newname))
{
- AssignDomainName(target, &m->MulticastHostname);
+ AssignDomainName(target, newname);
SetNewRData(&rr->resrec, mDNSNULL, 0); // Update rdlength, rdestimate, rdatahash
// If we're in the middle of probing this record, we need to start again,
rr->AnnounceCount = InitialAnnounceCount;
rr->RequireGoodbye = mDNSfalse;
- InitializeLastAPTime(m, rr, DefaultAPIntervalForRecordType(rr->resrec.RecordType));
+ InitializeLastAPTime(m, rr);
}
}
if (!rr->resrec.RecordType)
{ LogMsg("mDNS_Register_internal: RecordType must be non-zero %s", ARDisplayString(m, rr)); return(mStatus_BadParamErr); }
+ if (m->ShutdownTime)
+ { LogMsg("mDNS_Register_internal: Shutting down, can't register %s", ARDisplayString(m, rr)); return(mStatus_ServiceNotRunning); }
+
+ if (m->DivertMulticastAdvertisements && !AuthRecord_uDNS(rr))
+ {
+ mDNSInterfaceID previousID = rr->resrec.InterfaceID;
+ if (rr->resrec.InterfaceID == mDNSInterface_Any) rr->resrec.InterfaceID = mDNSInterface_LocalOnly;
+ if (rr->resrec.InterfaceID != mDNSInterface_LocalOnly)
+ {
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
+ if (intf && !intf->Advertise) rr->resrec.InterfaceID = mDNSInterface_LocalOnly;
+ }
+ if (rr->resrec.InterfaceID != previousID)
+ LogInfo("mDNS_Register_internal: Diverting record to local-only %s", ARDisplayString(m, rr));
+ }
+
while (*p && *p != rr) p=&(*p)->next;
while (*d && *d != rr) d=&(*d)->next;
if (*d || *p)
// If this resource record is referencing a specific interface, make sure it exists
if (rr->resrec.InterfaceID && rr->resrec.InterfaceID != mDNSInterface_LocalOnly)
{
- NetworkInterfaceInfo *intf;
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->InterfaceID == rr->resrec.InterfaceID) break;
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
if (!intf)
{
debugf("mDNS_Register_internal: Bogus InterfaceID %p in resource record", rr->resrec.InterfaceID);
rr->RequireGoodbye = mDNSfalse;
rr->AnsweredLocalQ = mDNSfalse;
rr->IncludeInProbe = mDNSfalse;
- rr->ImmedAnswer = mDNSNULL;
rr->ImmedUnicast = mDNSfalse;
+ rr->SendNSECNow = mDNSNULL;
+ rr->ImmedAnswer = mDNSNULL;
rr->ImmedAdditional = mDNSNULL;
rr->SendRNow = mDNSNULL;
rr->v4Requester = zerov4Addr;
rr->NextResponse = mDNSNULL;
rr->NR_AnswerTo = mDNSNULL;
rr->NR_AdditionalTo = mDNSNULL;
- if (!rr->AutoTarget) InitializeLastAPTime(m, rr, DefaultAPIntervalForRecordType(rr->resrec.RecordType));
+ if (!rr->AutoTarget) InitializeLastAPTime(m, rr);
// rr->LastAPTime = Set for us in InitializeLastAPTime()
// rr->LastMCTime = Set for us in InitializeLastAPTime()
// rr->LastMCInterface = Set for us in InitializeLastAPTime()
rr->NextUpdateCredit = 0;
rr->UpdateBlocked = 0;
+ // For records we're holding as proxy (except reverse-mapping PTR records) two announcements is sufficient
+ if (rr->WakeUp.HMAC.l[0] && !rr->AddressProxy.type) rr->AnnounceCount = 2;
+
// Field Group 4: Transient uDNS state for Authoritative Records
rr->state = regState_Zero;
rr->uselease = 0;
rr->expire = 0;
rr->Private = 0;
- rr->id = zeroID;
- rr->zone.c[0] = 0;
+ rr->updateid = zeroID;
+ rr->zone = rr->resrec.name;
rr->UpdateServer = zeroAddr;
rr->UpdatePort = zeroIPPort;
rr->nta = mDNSNULL;
rr->QueuedRDLen = 0;
// rr->resrec.interface = already set in mDNS_SetupResourceRecord
-// rr->resrec.name->c = MUST be set by client
+// rr->resrec.name->c = MUST be set by client
// rr->resrec.rrtype = already set in mDNS_SetupResourceRecord
// rr->resrec.rrclass = already set in mDNS_SetupResourceRecord
// rr->resrec.rroriginalttl = already set in mDNS_SetupResourceRecord
for (r = m->ResourceRecords; r; r=r->next)
{
const AuthRecord *s2 = r->RRSet ? r->RRSet : r;
- if (s1 != s2 && SameResourceRecordSignature(r, rr) && !SameRData(&r->resrec, &rr->resrec))
+ if (s1 != s2 && SameResourceRecordSignature(r, rr) && !IdenticalSameNameRecord(&r->resrec, &rr->resrec))
break;
}
if (r) // If we found a conflict, set RecordType = kDNSRecordTypeDeregistering so we'll deliver the callback
rr->UpdateCallback(m, rr, OldRData); // ... and let the client know
}
-// NOTE: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
+// Note: mDNS_Deregister_internal can call a user callback, which may change the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
// Exported so uDNS.c can call this
mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr, mDNS_Dereg_type drt)
dup->ProbeCount = rr->ProbeCount;
dup->AnnounceCount = rr->AnnounceCount;
dup->RequireGoodbye = rr->RequireGoodbye;
+ dup->AnsweredLocalQ = rr->AnsweredLocalQ;
dup->ImmedAnswer = rr->ImmedAnswer;
dup->ImmedUnicast = rr->ImmedUnicast;
dup->ImmedAdditional = rr->ImmedAdditional;
dup->LastAPTime = rr->LastAPTime;
dup->LastMCTime = rr->LastMCTime;
dup->LastMCInterface = rr->LastMCInterface;
+ dup->UpdateServer = rr->UpdateServer;
+ dup->UpdatePort = rr->UpdatePort;
+ dup->Private = rr->Private;
+ dup->state = rr->state;
rr->RequireGoodbye = mDNSfalse;
+ rr->AnsweredLocalQ = mDNSfalse;
}
}
}
{
// No need to log an error message if we already know this is a potentially repeated deregistration
if (drt != mDNS_Dereg_repeat)
- LogMsg("mDNS_Deregister_internal: Record %p %##s (%s) not found in list",
- rr, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ LogMsg("mDNS_Deregister_internal: Record %p not found in list %s", rr, ARDisplayString(m,rr));
return(mStatus_BadReferenceErr);
}
// If this is a shared record and we've announced it at least once,
// we need to retract that announcement before we delete the record
- // If this is a record (including mDNSInterface_LocalOnly records) for which we've given local answers then
- // it's tempting to just do "AnswerLocalQuestions(m, rr, mDNSfalse)" here, but that would not not be safe.
- // The AnswerLocalQuestions routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
+ // If this is a record (including mDNSInterface_LocalOnly records) for which we've given local-only answers then
+ // it's tempting to just do "AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse)" here, but that would not not be safe.
+ // The AnswerAllLocalQuestionsWithLocalAuthRecord routine walks the question list invoking client callbacks, using the "m->CurrentQuestion"
// mechanism to cope with the client callback modifying the question list while that's happening.
// However, mDNS_Deregister could have been called from a client callback (e.g. from the domain enumeration callback FoundDomain)
// which means that the "m->CurrentQuestion" mechanism is already in use to protect that list, so we can't use it twice.
// process and will complete asynchronously. Either way we don't need to do anything more here.
return(mStatus_NoError);
}
-#endif UNICAST_DISABLED
+#endif // UNICAST_DISABLED
if (RecordType == kDNSRecordTypeShared && (rr->RequireGoodbye || rr->AnsweredLocalQ))
{
// is allowed to do anything, including starting/stopping queries, registering/deregistering records, etc.
// In this case the likely client action to the mStatus_MemFree message is to free the memory,
// so any attempt to touch rr after this is likely to lead to a crash.
- mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
if (drt != mDNS_Dereg_conflict)
{
+ mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
if (rr->RecordCallback)
rr->RecordCallback(m, rr, mStatus_MemFree); // MUST NOT touch rr after this
+ mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
else
{
RecordProbeFailure(m, rr);
+ mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
if (rr->RecordCallback)
rr->RecordCallback(m, rr, mStatus_NameConflict); // MUST NOT touch rr after this
+ mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
// Now that we've finished deregistering rr, check our DuplicateRecords list for any that we marked previously.
// Note that with all the client callbacks going on, by the time we get here all the
// records we marked may have been explicitly deregistered by the client anyway.
else { mDNS_Deregister_internal(m, r2, mDNS_Dereg_conflict); r2 = m->DuplicateRecords; }
}
}
- mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
return(mStatus_NoError);
}
// it should go ahead and immediately dispose of this registration
rr->resrec.RecordType = kDNSRecordTypeShared;
rr->RequireGoodbye = mDNSfalse;
- if (rr->AnsweredLocalQ) { AnswerLocalQuestions(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
+ if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal); // Don't touch rr after this
}
-// NOTE: DiscardDeregistrations calls mDNS_Deregister_internal which can call a user callback, which may change
+// Note: DiscardDeregistrations calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSlocal void DiscardDeregistrations(mDNS *const m)
}
}
-mDNSlocal void GrantUpdateCredit(AuthRecord *rr)
+mDNSlocal mStatus GetLabelDecimalValue(const mDNSu8 *const src, mDNSu8 *dst)
{
- if (++rr->UpdateCredits >= kMaxUpdateCredits) rr->NextUpdateCredit = 0;
- else rr->NextUpdateCredit = NonZeroTime(rr->NextUpdateCredit + kUpdateCreditRefreshInterval);
+ int i, val = 0;
+ if (src[0] < 1 || src[0] > 3) return(mStatus_Invalid);
+ for (i=1; i<=src[0]; i++)
+ {
+ if (src[i] < '0' || src[i] > '9') return(mStatus_Invalid);
+ val = val * 10 + src[i] - '0';
+ }
+ if (val > 255) return(mStatus_Invalid);
+ *dst = val;
+ return(mStatus_NoError);
}
-// Note about acceleration of announcements to facilitate automatic coalescing of
-// multiple independent threads of announcements into a single synchronized thread:
-// The announcements in the packet may be at different stages of maturity;
-// One-second interval, two-second interval, four-second interval, and so on.
-// After we've put in all the announcements that are due, we then consider
-// whether there are other nearly-due announcements that are worth accelerating.
-// To be eligible for acceleration, a record MUST NOT be older (further along
-// its timeline) than the most mature record we've already put in the packet.
-// In other words, younger records can have their timelines accelerated to catch up
-// with their elder bretheren; this narrows the age gap and helps them eventually get in sync.
-// Older records cannot have their timelines accelerated; this would just widen
-// the gap between them and their younger bretheren and get them even more out of sync.
+mDNSlocal mStatus GetIPv4FromName(mDNSAddr *const a, const domainname *const name)
+ {
+ int skip = CountLabels(name) - 6;
+ if (skip < 0) { LogMsg("GetIPFromName: Need six labels in IPv4 reverse mapping name %##s", name); return mStatus_Invalid; }
+ if (GetLabelDecimalValue(SkipLeadingLabels(name, skip+3)->c, &a->ip.v4.b[0]) ||
+ GetLabelDecimalValue(SkipLeadingLabels(name, skip+2)->c, &a->ip.v4.b[1]) ||
+ GetLabelDecimalValue(SkipLeadingLabels(name, skip+1)->c, &a->ip.v4.b[2]) ||
+ GetLabelDecimalValue(SkipLeadingLabels(name, skip+0)->c, &a->ip.v4.b[3])) return mStatus_Invalid;
+ a->type = mDNSAddrType_IPv4;
+ return(mStatus_NoError);
+ }
-// NOTE: SendResponses calls mDNS_Deregister_internal which can call a user callback, which may change
-// the record list and/or question list.
-// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
-mDNSlocal void SendResponses(mDNS *const m)
+#define HexVal(X) ( ((X) >= '0' && (X) <= '9') ? ((X) - '0' ) : \
+ ((X) >= 'A' && (X) <= 'F') ? ((X) - 'A' + 10) : \
+ ((X) >= 'a' && (X) <= 'f') ? ((X) - 'a' + 10) : -1)
+
+mDNSlocal mStatus GetIPv6FromName(mDNSAddr *const a, const domainname *const name)
{
- int pktcount = 0;
- AuthRecord *rr, *r2;
- mDNSs32 maxExistingAnnounceInterval = 0;
- const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
+ int i, h, l;
+ const domainname *n;
- m->NextScheduledResponse = m->timenow + 0x78000000;
+ int skip = CountLabels(name) - 34;
+ if (skip < 0) { LogMsg("GetIPFromName: Need 34 labels in IPv6 reverse mapping name %##s", name); return mStatus_Invalid; }
- for (rr = m->ResourceRecords; rr; rr=rr->next)
- if (rr->ImmedUnicast)
+ n = SkipLeadingLabels(name, skip);
+ for (i=0; i<16; i++)
+ {
+ if (n->c[0] != 1) return mStatus_Invalid;
+ l = HexVal(n->c[1]);
+ n = (const domainname *)(n->c + 2);
+
+ if (n->c[0] != 1) return mStatus_Invalid;
+ h = HexVal(n->c[1]);
+ n = (const domainname *)(n->c + 2);
+
+ if (l<0 || h<0) return mStatus_Invalid;
+ a->ip.v6.b[15-i] = (h << 4) | l;
+ }
+
+ a->type = mDNSAddrType_IPv6;
+ return(mStatus_NoError);
+ }
+
+mDNSlocal mDNSs32 ReverseMapDomainType(const domainname *const name)
+ {
+ int skip = CountLabels(name) - 2;
+ if (skip >= 0)
+ {
+ const domainname *suffix = SkipLeadingLabels(name, skip);
+ if (SameDomainName(suffix, (const domainname*)"\x7" "in-addr" "\x4" "arpa")) return mDNSAddrType_IPv4;
+ if (SameDomainName(suffix, (const domainname*)"\x3" "ip6" "\x4" "arpa")) return mDNSAddrType_IPv6;
+ }
+ return(mDNSAddrType_None);
+ }
+
+mDNSlocal void SendARP(mDNS *const m, const mDNSu8 op, const AuthRecord *const rr,
+ const mDNSu8 *const spa, const mDNSu8 *const tha, const mDNSu8 *const tpa, const mDNSu8 *const dst)
+ {
+ int i;
+ mDNSu8 *ptr = m->omsg.data;
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, rr->resrec.InterfaceID);
+ if (!intf) { LogMsg("SendARP: No interface with InterfaceID %p found %s", rr->resrec.InterfaceID, ARDisplayString(m,rr)); return; }
+
+ // 0x00 Destination address
+ for (i=0; i<6; i++) *ptr++ = dst[i];
+
+ // 0x06 Source address (we just use zero -- driver/hardware will fill in real interface address)
+ for (i=0; i<6; i++) *ptr++ = 0x0;
+
+ // 0x0C ARP Ethertype (0x0806)
+ *ptr++ = 0x08; *ptr++ = 0x06;
+
+ // 0x0E ARP header
+ *ptr++ = 0x00; *ptr++ = 0x01; // Hardware address space; Ethernet = 1
+ *ptr++ = 0x08; *ptr++ = 0x00; // Protocol address space; IP = 0x0800
+ *ptr++ = 6; // Hardware address length
+ *ptr++ = 4; // Protocol address length
+ *ptr++ = 0x00; *ptr++ = op; // opcode; Request = 1, Response = 2
+
+ // 0x16 Sender hardware address (our MAC address)
+ for (i=0; i<6; i++) *ptr++ = intf->MAC.b[i];
+
+ // 0x1C Sender protocol address
+ for (i=0; i<4; i++) *ptr++ = spa[i];
+
+ // 0x20 Target hardware address
+ for (i=0; i<6; i++) *ptr++ = tha[i];
+
+ // 0x26 Target protocol address
+ for (i=0; i<4; i++) *ptr++ = tpa[i];
+
+ // 0x2A Total ARP Packet length 42 bytes
+ mDNSPlatformSendRawPacket(m->omsg.data, ptr, rr->resrec.InterfaceID);
+ }
+
+mDNSlocal void SetupOwnerOpt(const mDNS *const m, const NetworkInterfaceInfo *const intf, rdataOPT *const owner)
+ {
+ owner->u.owner.vers = 0;
+ owner->u.owner.seq = m->SleepSeqNum;
+ owner->u.owner.HMAC = m->PrimaryMAC;
+ owner->u.owner.IMAC = intf->MAC;
+ owner->u.owner.password = zeroEthAddr;
+
+ // Don't try to compute the optlen until *after* we've set up the data fields
+ owner->opt = kDNSOpt_Owner;
+ owner->optlen = DNSOpt_Owner_Space(owner) - 4;
+ }
+
+mDNSlocal void GrantUpdateCredit(AuthRecord *rr)
+ {
+ if (++rr->UpdateCredits >= kMaxUpdateCredits) rr->NextUpdateCredit = 0;
+ else rr->NextUpdateCredit = NonZeroTime(rr->NextUpdateCredit + kUpdateCreditRefreshInterval);
+ }
+
+// Note about acceleration of announcements to facilitate automatic coalescing of
+// multiple independent threads of announcements into a single synchronized thread:
+// The announcements in the packet may be at different stages of maturity;
+// One-second interval, two-second interval, four-second interval, and so on.
+// After we've put in all the announcements that are due, we then consider
+// whether there are other nearly-due announcements that are worth accelerating.
+// To be eligible for acceleration, a record MUST NOT be older (further along
+// its timeline) than the most mature record we've already put in the packet.
+// In other words, younger records can have their timelines accelerated to catch up
+// with their elder bretheren; this narrows the age gap and helps them eventually get in sync.
+// Older records cannot have their timelines accelerated; this would just widen
+// the gap between them and their younger bretheren and get them even more out of sync.
+
+// Note: SendResponses calls mDNS_Deregister_internal which can call a user callback, which may change
+// the record list and/or question list.
+// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
+mDNSlocal void SendResponses(mDNS *const m)
+ {
+ int pktcount = 0;
+ AuthRecord *rr, *r2;
+ mDNSs32 maxExistingAnnounceInterval = 0;
+ const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
+
+ m->NextScheduledResponse = m->timenow + 0x78000000;
+
+ if (m->SleepState == SleepState_Transferring) RetrySPSRegistrations(m);
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->ImmedUnicast)
{
mDNSAddr v4 = { mDNSAddrType_IPv4, {{{0}}} };
mDNSAddr v6 = { mDNSAddrType_IPv6, {{{0}}} };
while (rr->NextUpdateCredit && m->timenow - rr->NextUpdateCredit >= 0) GrantUpdateCredit(rr);
if (TimeToAnnounceThisRecord(rr, m->timenow) && ResourceRecordIsValidAnswer(rr))
{
- rr->ImmedAnswer = mDNSInterfaceMark; // Send on all interfaces
- if (maxExistingAnnounceInterval < rr->ThisAPInterval)
- maxExistingAnnounceInterval = rr->ThisAPInterval;
- if (rr->UpdateBlocked) rr->UpdateBlocked = 0;
+ if (rr->AddressProxy.type)
+ {
+ rr->AnnounceCount--;
+ rr->ThisAPInterval *= 2;
+ rr->LastAPTime = m->timenow;
+ if (rr->AddressProxy.type == mDNSAddrType_IPv4)
+ {
+ LogSPS("ARP Announcement %d Capturing traffic for H-MAC %.6a I-MAC %.6a %s", rr->AnnounceCount, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m,rr));
+ SendARP(m, 1, rr, rr->AddressProxy.ip.v4.b, zeroEthAddr.b, rr->AddressProxy.ip.v4.b, onesEthAddr.b);
+ }
+ else if (rr->AddressProxy.type == mDNSAddrType_IPv6)
+ {
+ //LogSPS("NDP Announcement %d %s", rr->AnnounceCount, ARDisplayString(m,rr));
+ //SendARP(m, 1, rr, rr->AddressProxy.ip.v4.b, zeroEthAddr.b, rr->AddressProxy.ip.v4.b, onesEthAddr.b);
+ }
+ }
+ else
+ {
+ rr->ImmedAnswer = mDNSInterfaceMark; // Send on all interfaces
+ if (maxExistingAnnounceInterval < rr->ThisAPInterval)
+ maxExistingAnnounceInterval = rr->ThisAPInterval;
+ if (rr->UpdateBlocked) rr->UpdateBlocked = 0;
+ }
}
}
if ((rr->resrec.InterfaceID && rr->ImmedAnswer) ||
(rr->ThisAPInterval <= maxExistingAnnounceInterval &&
TimeToAnnounceThisRecord(rr, m->timenow + rr->ThisAPInterval/2) &&
+ !rr->AddressProxy.type && // Don't include ARP Annoucements when considering which records to accelerate
ResourceRecordIsValidAnswer(rr)))
rr->ImmedAnswer = mDNSInterfaceMark; // Send on all interfaces
// When sending SRV records (particularly when announcing a new service) automatically add related Address record(s) as additionals
- // NOTE: Currently all address records are interface-specific, so it's safe to set ImmedAdditional to their InterfaceID,
+ // Note: Currently all address records are interface-specific, so it's safe to set ImmedAdditional to their InterfaceID,
// which will be non-null. If by some chance there is an address record that's not interface-specific (should never happen)
// then all that means is that it won't get sent -- which would not be the end of the world.
for (rr = m->ResourceRecords; rr; rr=rr->next)
if (ResourceRecordIsValidAnswer(r2))
if (r2->ImmedAnswer != mDNSInterfaceMark &&
r2->ImmedAnswer != rr->ImmedAnswer && SameResourceRecordSignature(r2, rr))
- r2->ImmedAnswer = rr->ImmedAnswer;
+ r2->ImmedAnswer = !r2->ImmedAnswer ? rr->ImmedAnswer : mDNSInterfaceMark;
}
else if (rr->ImmedAdditional) // If we're sending this as additional, see that its whole RRSet is similarly marked
{
// 1. Deregistering records that need to send their goodbye packet
// 2. Updated records that need to retract their old data
// 3. Answers and announcements we need to send
- // In all cases, if we fail, and we've put at least one answer, we break out of the for loop so we can
- // send this packet and then try again.
- // If we have not put even one answer, then we don't bail out. We pretend we succeeded anyway,
- // because otherwise we'll end up in an infinite loop trying to send a record that will never fit.
for (rr = m->ResourceRecords; rr; rr=rr->next)
+ {
if (rr->SendRNow == intf->InterfaceID)
{
+ newptr = mDNSNULL;
if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
{
newptr = PutResourceRecordTTL(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec, 0);
if (newptr) { responseptr = newptr; numDereg++; }
- else if (m->omsg.h.numAnswers) break;
}
else if (rr->NewRData && !m->SleepState) // If we have new data for this record
{
{
newptr = PutResourceRecordTTL(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec, 0);
if (newptr) { responseptr = newptr; numDereg++; rr->RequireGoodbye = mDNSfalse; }
- else if (m->omsg.h.numAnswers) break;
}
// Now try to see if we can fit the update in the same packet (not fatal if we can't)
SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);
}
else
{
+ mDNSu8 active = (m->SleepState != SleepState_Sleeping || intf->SPSAddr[0].type || intf->SPSAddr[1].type || intf->SPSAddr[2].type);
if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
rr->resrec.rrclass |= kDNSClass_UniqueRRSet; // Temporarily set the cache flush bit so PutResourceRecord will set it
- newptr = PutResourceRecordTTL(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec, m->SleepState ? 0 : rr->resrec.rroriginalttl);
+ newptr = PutResourceRecordTTL(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec, active ? rr->resrec.rroriginalttl : 0);
rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet; // Make sure to clear cache flush bit back to normal state
if (newptr)
{
responseptr = newptr;
- rr->RequireGoodbye = (mDNSu8) (!m->SleepState);
+ rr->RequireGoodbye = active;
if (rr->LastAPTime == m->timenow) numAnnounce++; else numAnswer++;
}
- else if (m->omsg.h.numAnswers) break;
+
+ // The first time through (pktcount==0), if this record is verified unique
+ // (i.e. typically A, AAAA, SRV and TXT), set the flag to add an NSEC too.
+ if (!pktcount && active && rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->SendNSECNow) rr->SendNSECNow = (mDNSInterfaceID)1;
+ }
+
+ if (newptr) // If succeeded in sending, advance to next interface
+ {
+ // If sending on all interfaces, go to next interface; else we're finished now
+ if (rr->ImmedAnswer == mDNSInterfaceMark && rr->resrec.InterfaceID == mDNSInterface_Any)
+ rr->SendRNow = GetNextActiveInterfaceID(intf);
+ else
+ rr->SendRNow = mDNSNULL;
}
- // If sending on all interfaces, go to next interface; else we're finished now
- if (rr->ImmedAnswer == mDNSInterfaceMark && rr->resrec.InterfaceID == mDNSInterface_Any)
- rr->SendRNow = GetNextActiveInterfaceID(intf);
- else
- rr->SendRNow = mDNSNULL;
}
+ }
// Second Pass. Add additional records, if there's space.
newptr = responseptr;
rr->ImmedAdditional = mDNSNULL; // then cancel its ImmedAdditional field
else if (newptr) // Else, try to add it if we can
{
+ // The first time through (pktcount==0), if this record is verified unique
+ // (i.e. typically A, AAAA, SRV and TXT), set the flag to add an NSEC too.
+ if (!pktcount && rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->SendNSECNow) rr->SendNSECNow = (mDNSInterfaceID)1;
+
if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
rr->resrec.rrclass |= kDNSClass_UniqueRRSet; // Temporarily set the cache flush bit so PutResourceRecord will set it
newptr = PutResourceRecord(&m->omsg, newptr, &m->omsg.h.numAdditionals, &rr->resrec);
}
}
}
-
+
+ // Third Pass. Add NSEC records, if there's space.
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->SendNSECNow == (mDNSInterfaceID)1 || rr->SendNSECNow == intf->InterfaceID)
+ {
+ AuthRecord nsec;
+ mDNS_SetupResourceRecord(&nsec, mDNSNULL, mDNSInterface_Any, kDNSType_NSEC, rr->resrec.rroriginalttl, kDNSRecordTypeUnique, mDNSNULL, mDNSNULL);
+ nsec.resrec.rrclass |= kDNSClass_UniqueRRSet;
+ AssignDomainName(&nsec.namestorage, rr->resrec.name);
+ mDNSPlatformMemZero(nsec.rdatastorage.u.nsec.bitmap, sizeof(nsec.rdatastorage.u.nsec.bitmap));
+ for (r2 = m->ResourceRecords; r2; r2=r2->next)
+ if (ResourceRecordIsValidAnswer(r2) && SameResourceRecordNameClassInterface(r2, rr))
+ {
+ if (r2->resrec.rrtype >= kDNSQType_ANY) { LogMsg("Can't create NSEC for record %s", ARDisplayString(m, r2)); break; }
+ else nsec.rdatastorage.u.nsec.bitmap[r2->resrec.rrtype >> 3] |= 128 >> (r2->resrec.rrtype & 7);
+ }
+ newptr = responseptr;
+ if (!r2) // If we successfully built our NSEC record, add it to the packet now
+ {
+ newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAdditionals, &nsec.resrec);
+ if (newptr) responseptr = newptr;
+ }
+
+ // If we successfully put the NSEC record, clear the SendNSECNow flag
+ // If we consider this NSEC optional, then we unconditionally clear the SendNSECNow flag, even if we fail to put this additional record
+ if (newptr || rr->SendNSECNow == (mDNSInterfaceID)1)
+ {
+ rr->SendNSECNow = mDNSNULL;
+ // Run through remainder of list clearing SendNSECNow flag for all other records which would generate the same NSEC
+ for (r2 = rr->next; r2; r2=r2->next)
+ if (SameResourceRecordNameClassInterface(r2, rr))
+ if (r2->SendNSECNow == (mDNSInterfaceID)1 || r2->SendNSECNow == intf->InterfaceID)
+ r2->SendNSECNow = mDNSNULL;
+ }
+ }
+
if (m->omsg.h.numAnswers > 0 || m->omsg.h.numAdditionals)
{
debugf("SendResponses: Sending %d Deregistration%s, %d Announcement%s, %d Answer%s, %d Additional%s on %p",
- numDereg, numDereg == 1 ? "" : "s",
- numAnnounce, numAnnounce == 1 ? "" : "s",
- numAnswer, numAnswer == 1 ? "" : "s",
+ numDereg, numDereg == 1 ? "" : "s",
+ numAnnounce, numAnnounce == 1 ? "" : "s",
+ numAnswer, numAnswer == 1 ? "" : "s",
m->omsg.h.numAdditionals, m->omsg.h.numAdditionals == 1 ? "" : "s", intf->InterfaceID);
if (intf->IPv4Available) mDNSSendDNSMessage(m, &m->omsg, responseptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v4, MulticastDNSPort, mDNSNULL, mDNSNULL);
if (intf->IPv6Available) mDNSSendDNSMessage(m, &m->omsg, responseptr, intf->InterfaceID, mDNSNULL, &AllDNSLinkGroup_v6, MulticastDNSPort, mDNSNULL, mDNSNULL);
debugf(msg, intf, next);
#endif
intf = next;
+ pktcount = 0; // When we move to a new interface, reset packet count back to zero -- NSEC generation logic uses it
}
}
// For all the reconfirmations in a given batch, we want to use the same random value
// so that the reconfirmation questions can be grouped into a single query packet
if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(0x3FFFFFFF);
- interval += mDNSRandomFromFixedSeed(m->RandomReconfirmDelay, interval/3);
+ interval += m->RandomReconfirmDelay % ((interval/3) + 1);
rr->TimeRcvd = m->timenow - (mDNSs32)interval * 3;
rr->resrec.rroriginalttl = (interval * 4 + mDNSPlatformOneSecond - 1) / mDNSPlatformOneSecond;
SetNextCacheCheckTime(m, rr);
domainname *crtarget = GetRRDomainNameTarget(&cr->resrec);
if (crtarget && cr->resrec.rdatahash == namehash && SameDomainName(crtarget, name))
{
- LogOperation("ReconfirmAntecedents: Reconfirming (depth=%d) %s", depth, CRDisplayString(m, cr));
+ LogInfo("ReconfirmAntecedents: Reconfirming (depth=%d) %s", depth, CRDisplayString(m, cr));
mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
if (depth < 5) ReconfirmAntecedents(m, cr->resrec.name, cr->resrec.namehash, depth+1);
}
// we check if we have an address record for the same name. If we do have an IPv4 address for a given
// name but not an IPv6 address, that's okay (it just means the device doesn't do IPv6) so the failure
// to get a AAAA response is not grounds to doubt the PTR/SRV chain that lead us to that name.
-mDNSlocal CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
+mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
{
CacheGroup *const cg = CacheGroupForName(m, HashSlot(name), namehash, name);
- CacheRecord *cr = cg ? cg->members : mDNSNULL;
+ const CacheRecord *cr = cg ? cg->members : mDNSNULL;
while (cr && !RRTypeIsAddressType(cr->resrec.rrtype)) cr=cr->next;
return(cr);
}
+mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *const q, const CacheRecord *const c0, const CacheRecord *const c1)
+ {
+ CacheGroup *const cg = CacheGroupForName(m, HashSlot(&q->qname), q->qnamehash, &q->qname);
+ const CacheRecord *cr, *bestcr = mDNSNULL;
+ mDNSu32 bestmetric = 1000000;
+ for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
+ if (cr->resrec.rrtype == kDNSType_PTR && cr->resrec.rdlength >= 6) // If record is PTR type, with long enough name,
+ if (cr != c0 && cr != c1) // that's not one we've seen before,
+ if (SameNameRecordAnswersQuestion(&cr->resrec, q)) // and answers our browse query,
+ if (!IdenticalSameNameRecord(&cr->resrec, &m->SPSRecords.RR_PTR.resrec)) // and is not our own advertised service...
+ {
+ mDNSu32 metric = SPSMetric(cr->resrec.rdata->u.name.c);
+ if (bestmetric > metric) { bestmetric = metric; bestcr = cr; }
+ }
+ return(bestcr);
+ }
+
+// Finds the three best Sleep Proxies we currently have in our cache
+mDNSexport void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3])
+ {
+ sps[0] = FindSPSInCache1(m, q, mDNSNULL, mDNSNULL);
+ sps[1] = !sps[0] ? mDNSNULL : FindSPSInCache1(m, q, sps[0], mDNSNULL);
+ sps[2] = !sps[1] ? mDNSNULL : FindSPSInCache1(m, q, sps[0], sps[1]);
+ }
+
// Only DupSuppressInfos newer than the specified 'time' are allowed to remain active
mDNSlocal void ExpireDupSuppressInfo(DupSuppressInfo ds[DupSuppressInfoSize], mDNSs32 time)
{
mDNSu32 forecast = (mDNSu32)DomainNameLength(&q->qname) + 4;
const mDNSu32 slot = HashSlot(&q->qname);
const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
- CacheRecord *rr;
+ const CacheRecord *rr;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next) // If we have a resource record in our cache,
if (rr->resrec.rdlength <= SmallRecordLimit && // which is small enough to sensibly fit in the packet
SameNameRecordAnswersQuestion(&rr->resrec, q) && // which answers our question
if (rr->CRActiveQuestion && rr->UnansweredQueries < MaxUnansweredQueries)
if (m->timenow + TicksTTL(rr)/50 - rr->NextRequiredQuery >= 0)
{
- LogOperation("Sending %d%% cache expiration query for %s", 80 + 5 * rr->UnansweredQueries, CRDisplayString(m, rr));
+ debugf("Sending %d%% cache expiration query for %s", 80 + 5 * rr->UnansweredQueries, CRDisplayString(m, rr));
q = rr->CRActiveQuestion;
ExpireDupSuppressInfoOnInterface(q->DupSuppress, m->timenow - TicksTTL(rr)/20, rr->resrec.InterfaceID);
// For uDNS queries (TargetQID non-zero) we adjust LastQTime,
{
mDNSu8 *qptr = m->omsg.data;
const mDNSu8 *const limit = m->omsg.data + sizeof(m->omsg.data);
- InitializeDNSMessage(&m->omsg.h, q->TargetQID, QueryFlags);
- qptr = putQuestion(&m->omsg, qptr, limit, &q->qname, q->qtype, q->qclass);
- mDNSSendDNSMessage(m, &m->omsg, qptr, mDNSInterface_Any, q->LocalSocket, &q->Target, q->TargetPort, mDNSNULL, mDNSNULL);
- q->ThisQInterval *= QuestionIntervalStep;
+
+ // If we fail to get a new on-demand socket (should only happen cases of the most extreme resource exhaustion), we'll try again next time
+ if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ if (q->LocalSocket)
+ {
+ InitializeDNSMessage(&m->omsg.h, q->TargetQID, QueryFlags);
+ qptr = putQuestion(&m->omsg, qptr, limit, &q->qname, q->qtype, q->qclass);
+ mDNSSendDNSMessage(m, &m->omsg, qptr, mDNSInterface_Any, q->LocalSocket, &q->Target, q->TargetPort, mDNSNULL, mDNSNULL);
+ q->ThisQInterval *= QuestionIntervalStep;
+ }
if (q->ThisQInterval > MaxQuestionInterval)
q->ThisQInterval = MaxQuestionInterval;
q->LastQTime = m->timenow;
}
else if (mDNSOpaque16IsZero(q->TargetQID) && !q->Target.type && TimeToSendThisQuestion(q, m->timenow))
{
- //LogOperation("Time to send %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - (q->LastQTime + q->ThisQInterval));
+ //LogInfo("Time to send %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - (q->LastQTime + q->ThisQInterval));
q->SendQNow = mDNSInterfaceMark; // Mark this question for sending on all interfaces
if (maxExistingQuestionInterval < q->ThisQInterval)
maxExistingQuestionInterval = q->ThisQInterval;
// treat this as logically a repeat of the last transmission, without advancing the interval
if (m->timenow - (q->LastQTime + q->ThisQInterval/2) >= 0)
{
- //LogOperation("Accelerating %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - (q->LastQTime + q->ThisQInterval));
+ //LogInfo("Accelerating %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), m->timenow - (q->LastQTime + q->ThisQInterval));
q->SendQNow = mDNSInterfaceMark; // Mark this question for sending on all interfaces
debugf("SendQueries: %##s (%s) next interval %d seconds RequestUnicast = %d",
q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval / InitialQuestionInterval, q->RequestUnicast);
// 2. else, if it has reached its probe time, mark it for sending and then update m->NextScheduledProbe correctly
else if (rr->ProbeCount)
{
+ if (rr->AddressProxy.type == mDNSAddrType_IPv4)
+ {
+ LogSPS("SendQueries ARP Probe %d %s %s", rr->ProbeCount, InterfaceNameForID(m, rr->resrec.InterfaceID), ARDisplayString(m,rr));
+ SendARP(m, 1, rr, zerov4Addr.b, zeroEthAddr.b, rr->AddressProxy.ip.v4.b, rr->WakeUp.IMAC.b);
+ }
+ else if (rr->AddressProxy.type == mDNSAddrType_IPv6)
+ {
+ //LogSPS("SendQueries NDP Probe %d %s", rr->ProbeCount, ARDisplayString(m,rr));
+ //SendARP(m, 1, rr, rr->AddressProxy.ip.v4.b, zeroEthAddr.b, rr->AddressProxy.ip.v4.b, onesEthAddr.b);
+ }
// Mark for sending. (If no active interfaces, then don't even try.)
- rr->SendRNow = !intf ? mDNSNULL : (rr->resrec.InterfaceID) ? rr->resrec.InterfaceID : intf->InterfaceID;
+ rr->SendRNow = (!intf || rr->WakeUp.HMAC.l[0]) ? mDNSNULL : rr->resrec.InterfaceID ? rr->resrec.InterfaceID : intf->InterfaceID;
rr->LastAPTime = m->timenow;
+ // When we have a late conflict that resets a record to probing state we use a special marker value greater
+ // than DefaultProbeCountForTypeUnique. Here we detect that state and reset rr->ProbeCount back to the right value.
+ if (rr->ProbeCount > DefaultProbeCountForTypeUnique)
+ rr->ProbeCount = DefaultProbeCountForTypeUnique;
rr->ProbeCount--;
SetNextAnnounceProbeTime(m, rr);
if (rr->ProbeCount == 0)
// go through our interface list sending the appropriate queries on each interface
while (intf)
{
+ const int os = !intf->MAC.l[0] ? 0 : DNSOpt_Header_Space + mDNSSameEthAddress(&m->PrimaryMAC, &intf->MAC) ? DNSOpt_OwnerData_ID_Space : DNSOpt_OwnerData_ID_Wake_Space;
+ int OwnerRecordSpace = 0;
AuthRecord *rr;
mDNSu8 *queryptr = m->omsg.data;
+ mDNSu8 *limit = m->omsg.data + AbsoluteMaxDNSMessageData;
InitializeDNSMessage(&m->omsg.h, zeroID, QueryFlags);
if (KnownAnswerList) verbosedebugf("SendQueries: KnownAnswerList set... Will continue from previous packet");
if (!KnownAnswerList)
debugf("SendQueries: %s question for %##s (%s) at %d forecast total %d",
SuppressOnThisInterface(q->DupSuppress, intf) ? "Suppressing" : "Putting ",
q->qname.c, DNSTypeName(q->qtype), queryptr - m->omsg.data, queryptr + answerforecast - m->omsg.data);
+
// If we're suppressing this question, or we successfully put it, update its SendQNow state
if (SuppressOnThisInterface(q->DupSuppress, intf) ||
BuildQuestion(m, &m->omsg, &queryptr, q, &kalistptr, &answerforecast))
- q->SendQNow = (q->InterfaceID || !q->SendOnAll) ? mDNSNULL : GetNextActiveInterfaceID(intf);
+ q->SendQNow = (q->InterfaceID || !q->SendOnAll) ? mDNSNULL : GetNextActiveInterfaceID(intf);
+
+ // Once we've put at least one question, cut back our limit to the normal single-packet size
+ if (m->omsg.h.numQuestions) limit = m->omsg.data + NormalMaxDNSMessageData;
}
}
{
mDNSBool ucast = (rr->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353;
mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
- const mDNSu8 *const limit = m->omsg.data + ((m->omsg.h.numQuestions) ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData);
mDNSu8 *newptr = putQuestion(&m->omsg, queryptr, limit, rr->resrec.name, kDNSQType_ANY, (mDNSu16)(rr->resrec.rrclass | ucbit));
// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
mDNSu32 forecast = answerforecast + 12 + rr->resrec.rdestimate;
- if (newptr && newptr + forecast < limit)
+ if (newptr && newptr + forecast + os < limit)
{
- queryptr = newptr;
- answerforecast = forecast;
+ queryptr = newptr;
+ limit = m->omsg.data + NormalMaxDNSMessageData;
+ answerforecast = forecast;
+ OwnerRecordSpace = os;
rr->SendRNow = (rr->resrec.InterfaceID) ? mDNSNULL : GetNextActiveInterfaceID(intf);
rr->IncludeInProbe = mDNStrue;
verbosedebugf("SendQueries: Put Question %##s (%s) probecount %d",
}
else
{
- verbosedebugf("SendQueries: Retracting Question %##s (%s)",
- rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ verbosedebugf("SendQueries: Retracting Question %##s (%s)", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
m->omsg.h.numQuestions--;
}
}
- }
+ }
+
+ if (m->omsg.h.numQuestions) limit = m->omsg.data + NormalMaxDNSMessageData - OwnerRecordSpace;
// Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
while (KnownAnswerList)
{
CacheRecord *ka = KnownAnswerList;
mDNSu32 SecsSinceRcvd = ((mDNSu32)(m->timenow - ka->TimeRcvd)) / mDNSPlatformOneSecond;
- mDNSu8 *newptr = PutResourceRecordTTL(&m->omsg, queryptr, &m->omsg.h.numAnswers, &ka->resrec, ka->resrec.rroriginalttl - SecsSinceRcvd);
+ mDNSu8 *newptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAnswers, &ka->resrec, ka->resrec.rroriginalttl - SecsSinceRcvd, limit);
if (newptr)
{
verbosedebugf("SendQueries: Put %##s (%s) at %d - %d",
ka->resrec.name->c, DNSTypeName(ka->resrec.rrtype), queryptr - m->omsg.data, newptr - m->omsg.data);
queryptr = newptr;
+ limit = m->omsg.data + NormalMaxDNSMessageData - OwnerRecordSpace;
KnownAnswerList = ka->NextInKAList;
ka->NextInKAList = mDNSNULL;
}
mDNSu8 *newptr = PutResourceRecord(&m->omsg, queryptr, &m->omsg.h.numAuthorities, &rr->resrec);
rr->IncludeInProbe = mDNSfalse;
if (newptr) queryptr = newptr;
- else LogMsg("SendQueries: How did we fail to have space for the Update record %##s (%s)?",
- rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ else LogMsg("SendQueries: How did we fail to have space for the Update record %s", ARDisplayString(m,rr));
}
-
+
+ if (OwnerRecordSpace)
+ {
+ AuthRecord opt;
+ mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
+ opt.resrec.rrclass = NormalMaxDNSMessageData;
+ opt.resrec.rdlength = sizeof(rdataOPT); // One option in this OPT record
+ opt.resrec.rdestimate = sizeof(rdataOPT);
+ SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
+ LogSPS("SendQueries putting %s", ARDisplayString(m, &opt));
+ queryptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAdditionals,
+ &opt.resrec, opt.resrec.rroriginalttl, m->omsg.data + AbsoluteMaxDNSMessageData);
+ if (!queryptr)
+ LogMsg("SendQueries: How did we fail to have space for the OPT record (%d/%d/%d/%d) %s",
+ m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
+ }
+
if (queryptr > m->omsg.data)
{
if ((m->omsg.h.flags.b[0] & kDNSFlag0_TC) && m->omsg.h.numQuestions > 1)
}
}
+mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password)
+ {
+ int i, j;
+ mDNSu8 *ptr = m->omsg.data;
+
+ if (!InterfaceID) { LogMsg("SendWakeup: No InterfaceID specified"); return; }
+
+ // 0x00 Destination address
+ for (i=0; i<6; i++) *ptr++ = EthAddr->b[i];
+
+ // 0x06 Source address (we just use zero -- BPF will fill in real interface address)
+ for (i=0; i<6; i++) *ptr++ = 0x0;
+
+ // 0x0C Ethertype (0x0842)
+ *ptr++ = 0x08;
+ *ptr++ = 0x42;
+
+ // 0x0E Wakeup sync sequence
+ for (i=0; i<6; i++) *ptr++ = 0xFF;
+
+ // 0x14 Wakeup data
+ for (j=0; j<16; j++) for (i=0; i<6; i++) *ptr++ = EthAddr->b[i];
+
+ // 0x74 Password
+ for (i=0; i<6; i++) *ptr++ = password->b[i];
+
+ mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
+
+ // For Ethernet switches that don't flood-foward packets with unknown unicast destination MAC addresses,
+ // broadcast is the only reliable way to get a wakeup packet to the intended target machine.
+ // For 802.11 WPA networks, where a sleeping target machine may have missed a broadcast/multicast
+ // key rotation, unicast is the only way to get a wakeup packet to the intended target machine.
+ // So, we send one of each, unicast first, then broadcast second.
+ for (i=0; i<6; i++) m->omsg.data[i] = 0xFF;
+ mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
+ }
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - RR List Management & Task Management
#endif
-// NOTE: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
+// Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
// Any code walking either list must use the m->CurrentQuestion (and possibly m->CurrentRecord) mechanism to protect against this.
// In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
// which will be auto-advanced (possibly to NULL) if the client callback cancels the question.
if (rr->DelayDelivery) return; // We'll come back later when CacheRecordDeferredAdd() calls us
// Only deliver negative answers if client has explicitly requested them
- if (rr->resrec.RecordType == kDNSRecordTypePacketNegative && (!AddRecord || !q->ReturnIntermed)) return;
+ if (rr->resrec.RecordType == kDNSRecordTypePacketNegative || (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype)))
+ if (!AddRecord || !q->ReturnIntermed) return;
// For CNAME results to non-CNAME questions, only inform the client if they explicitly requested that
if (q->QuestionCallback && !q->NoAnswer && (!followcname || q->ReturnIntermed))
{
mDNS_DropLockBeforeCallback(); // Allow client (and us) to legally make mDNS API calls
- q->QuestionCallback(m, q, &rr->resrec, AddRecord);
+ if (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype))
+ {
+ CacheRecord neg;
+ MakeNegativeCacheRecord(m, &neg, &q->qname, q->qnamehash, q->qtype, q->qclass, 1, rr->resrec.InterfaceID);
+ q->QuestionCallback(m, q, &neg.resrec, AddRecord);
+ }
+ else
+ q->QuestionCallback(m, q, &rr->resrec, AddRecord);
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
- // NOTE: Proceed with caution here because client callback function is allowed to do anything,
+ // Note: Proceed with caution here because client callback function is allowed to do anything,
// including starting/stopping queries, registering/deregistering records, etc.
if (followcname && m->CurrentQuestion == q && q->CNAMEReferrals < 10)
{
const mDNSu32 c = q->CNAMEReferrals + 1;
// Right now we just stop and re-use the existing query. If we really wanted to be 100% perfect,
- // and track CNAMEs coming and going, we should really create a subbordinate query here,
+ // and track CNAMEs coming and going, we should really create a subordinate query here,
// 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.
- LogOperation("AnswerCurrentQuestionWithResourceRecord: following CNAME referral for %s", CRDisplayString(m, rr));
+ LogInfo("AnswerCurrentQuestionWithResourceRecord: following CNAME referral for %s", CRDisplayString(m, rr));
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
const mDNSs32 start = m->timenow - 0x10000000;
mDNSs32 delay = start;
CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
- CacheRecord *rr;
+ const CacheRecord *rr;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (threshhold - RRExpireTime(rr) >= 0) // If we have records about to expire within a second
if (delay - RRExpireTime(rr) < 0) // then delay until after they've been deleted
// the end of the question list, and m->NewQuestions will be set to indicate the first new question.
// rr is a new CacheRecord just received into our cache
// (kDNSRecordTypePacketAns/PacketAnsUnique/PacketAdd/PacketAddUnique).
-// NOTE: CacheRecordAdd calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
+// Note: CacheRecordAdd calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
// which may change the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
// but we don't have any place to cache it. We'll deliver question 'add' events now, but we won't have any
// way to deliver 'remove' events in future, nor will we be able to include this in known-answer lists,
// so we immediately bump ThisQInterval up to MaxQuestionInterval to avoid pounding the network.
-// NOTE: NoCacheAnswer calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
+// Note: NoCacheAnswer calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
// which may change the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSlocal void NoCacheAnswer(mDNS *const m, CacheRecord *rr)
// the end of the question list, and m->NewQuestions will be set to indicate the first new question.
// rr is an existing cache CacheRecord that just expired and is being deleted
// (kDNSRecordTypePacketAns/PacketAnsUnique/PacketAdd/PacketAddUnique).
-// NOTE: CacheRecordRmv calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
+// Note: CacheRecordRmv calls AnswerCurrentQuestionWithResourceRecord which can call a user callback,
// which may change the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
{
if (q->CurrentAnswers == 0)
{
- LogOperation("CacheRecordRmv: Last answer for %##s (%s) expired from cache; will reconfirm antecedents",
+ LogInfo("CacheRecordRmv: Last answer for %##s (%s) expired from cache; will reconfirm antecedents",
q->qname.c, DNSTypeName(q->qtype));
ReconfirmAntecedents(m, &q->qname, q->qnamehash, 0);
}
mDNSlocal void ReleaseCacheRecord(mDNS *const m, CacheRecord *r)
{
//LogMsg("ReleaseCacheRecord: Releasing %s", CRDisplayString(m, r));
- if (r->resrec.rdata && r->resrec.rdata != (RData*)&r->rdatastorage) mDNSPlatformMemFree(r->resrec.rdata);
+ if (r->resrec.rdata && r->resrec.rdata != (RData*)&r->smallrdatastorage) mDNSPlatformMemFree(r->resrec.rdata);
r->resrec.rdata = mDNSNULL;
ReleaseCacheEntity(m, (CacheEntity *)r);
}
if (q->NoAnswer == NoAnswer_Fail)
{
LogMsg("AnswerNewQuestion: NoAnswer_Fail %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
- MakeNegativeCacheRecord(m, &q->qname, q->qnamehash, q->qtype, q->qclass, 60);
+ MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, mDNSInterface_Any);
q->NoAnswer = NoAnswer_Normal; // Temporarily turn off answer suppression
AnswerCurrentQuestionWithResourceRecord(m, &m->rec.r, QC_addnocache);
q->NoAnswer = NoAnswer_Fail; // Restore NoAnswer state
if (rr->resrec.InterfaceID == mDNSInterface_LocalOnly)
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
{
- AnswerLocalOnlyQuestionWithResourceRecord(m, q, rr, mDNStrue);
+ AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, mDNStrue);
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
}
mDNSu32 SecsSinceRcvd = ((mDNSu32)(m->timenow - rr->TimeRcvd)) / mDNSPlatformOneSecond;
if (rr->resrec.rroriginalttl <= SecsSinceRcvd)
{
- LogMsg("AnswerNewQuestion: How is rr->resrec.rroriginalttl %lu <= SecsSinceRcvd %lu for %##s (%s) %d %d",
- rr->resrec.rroriginalttl, SecsSinceRcvd, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), m->timenow, rr->TimeRcvd);
+ LogMsg("AnswerNewQuestion: How is rr->resrec.rroriginalttl %lu <= SecsSinceRcvd %lu for %s %d %d",
+ rr->resrec.rroriginalttl, SecsSinceRcvd, CRDisplayString(m, rr), m->timenow, rr->TimeRcvd);
continue; // Go to next one in loop
}
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
else if (RRTypeIsAddressType(rr->resrec.rrtype) && RRTypeIsAddressType(q->qtype))
- if (rr->resrec.namehash == q->qnamehash && SameDomainName(rr->resrec.name, &q->qname))
- ShouldQueryImmediately = mDNSfalse;
+ ShouldQueryImmediately = mDNSfalse;
}
if (m->CurrentQuestion != q) debugf("AnswerNewQuestion: question deleted while giving cache answers");
}
// When a NewLocalOnlyQuestion is created, AnswerNewLocalOnlyQuestion runs though our ResourceRecords delivering any
-// appropriate answers, stopping if it reaches a NewLocalRecord -- these will be handled by AnswerLocalQuestions
+// appropriate answers, stopping if it reaches a NewLocalRecord -- these will be handled by AnswerAllLocalQuestionsWithLocalAuthRecord
mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
{
DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
m->CurrentRecord = rr->next;
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
{
- AnswerLocalOnlyQuestionWithResourceRecord(m, q, rr, mDNStrue);
+ AnswerLocalQuestionWithLocalAuthRecord(m, q, rr, mDNStrue);
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
}
// To guard against this, if our cache grows above 512kB (approx 3168 records at 164 bytes each),
// and we're actively using less than 1/32 of that cache, then we purge all the unused records
// and recycle them, instead of allocating more memory.
- if (m->rrcache_size > 3000 && m->rrcache_size / 32 > m->rrcache_active)
- LogOperation("Possible denial-of-service attack in progress: m->rrcache_size %lu; m->rrcache_active %lu",
+ if (m->rrcache_size > 5000 && m->rrcache_size / 32 > m->rrcache_active)
+ LogInfo("Possible denial-of-service attack in progress: m->rrcache_size %lu; m->rrcache_active %lu",
m->rrcache_size, m->rrcache_active);
else
{
// Enumerating the entire cache is moderately expensive, so when we do it, we reclaim all the records we can in one pass.
if (!m->rrcache_free)
{
- #if LogAllOperations || MDNS_DEBUGMSGS
mDNSu32 oldtotalused = m->rrcache_totalused;
- #endif
mDNSu32 slot;
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
{
else ReleaseCacheGroup(m, cp);
}
}
- LogOperation("GetCacheEntity recycled %d records to reduce cache from %d to %d",
+ LogInfo("GetCacheEntity recycled %d records to reduce cache from %d to %d",
oldtotalused - m->rrcache_totalused, oldtotalused, m->rrcache_totalused);
}
m->rrcache_free = e->next;
if (++m->rrcache_totalused >= m->rrcache_report)
{
- LogOperation("RR Cache now using %ld objects", m->rrcache_totalused);
- if (m->rrcache_report < 100) m->rrcache_report += 10;
- else m->rrcache_report += 100;
+ LogInfo("RR Cache now using %ld objects", m->rrcache_totalused);
+ if (m->rrcache_report < 100) m->rrcache_report += 10;
+ else if (m->rrcache_report < 1000) m->rrcache_report += 100;
+ else m->rrcache_report += 1000;
}
mDNSPlatformMemZero(e, sizeof(*e));
}
CacheRecord *r = (CacheRecord *)GetCacheEntity(m, cg);
if (r)
{
- r->resrec.rdata = (RData*)&r->rdatastorage; // By default, assume we're usually going to be using local storage
+ r->resrec.rdata = (RData*)&r->smallrdatastorage; // By default, assume we're usually going to be using local storage
if (RDLength > InlineCacheRDSize) // If RDLength is too big, allocate extra storage
{
r->resrec.rdata = (RData*)mDNSPlatformMemAllocate(sizeofRDataHeader + RDLength);
mDNSexport void mDNS_PurgeCacheResourceRecord(mDNS *const m, CacheRecord *rr)
{
+ if (m->mDNS_busy != m->mDNS_reentrancy+1)
+ LogMsg("mDNS_PurgeCacheResourceRecord: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
// Make sure we mark this record as thoroughly expired -- we don't ever want to give
// a positive answer using an expired record (e.g. from an interface that has gone away).
// We don't want to clear CRActiveQuestion here, because that would leave the record subject to
return(time);
}
+// To avoid pointless CPU thrash, we use SetSPSProxyListChanged(X) to record the last interface that
+// had its Sleep Proxy client list change, and defer to actual BPF reconfiguration to mDNS_Execute().
+// (GetNextScheduledEvent() returns "now" when m->SPSProxyListChanged is set)
+#define SetSPSProxyListChanged(X) do { \
+ if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
+ m->SPSProxyListChanged = (X); } while(0)
+
+// Called from mDNS_Execute() to expire stale proxy records
+mDNSlocal void CheckProxyRecords(mDNS *const m, AuthRecord *list)
+ {
+ m->CurrentRecord = list;
+ while (m->CurrentRecord)
+ {
+ AuthRecord *rr = m->CurrentRecord;
+ if (rr->WakeUp.HMAC.l[0])
+ {
+ if (m->timenow - rr->TimeExpire < 0) // If proxy record not expired yet, update m->NextScheduledSPS
+ {
+ if (m->NextScheduledSPS - rr->TimeExpire > 0)
+ m->NextScheduledSPS = rr->TimeExpire;
+ }
+ else // else proxy record expired, so remove it
+ {
+ LogSPS("mDNS_Execute: Removing %d H-MAC %.6a I-MAC %.6a %d %s",
+ m->ProxyRecords, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, rr->WakeUp.seq, ARDisplayString(m, rr));
+ SetSPSProxyListChanged(rr->resrec.InterfaceID);
+ mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
+ // Don't touch rr after this -- memory may have been free'd
+ }
+ }
+ // Mustn't advance m->CurrentRecord until *after* mDNS_Deregister_internal,
+ // because the list may have been changed in that call.
+ if (m->CurrentRecord == rr) // If m->CurrentRecord was not advanced for us, do it now
+ m->CurrentRecord = rr->next;
+ }
+ }
+
mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
{
mDNS_Lock(m); // Must grab lock before trying to read m->timenow
}
}
+ if (m->timenow - m->NextScheduledSPS >= 0)
+ {
+ m->NextScheduledSPS = m->timenow + 0x3FFFFFFF;
+ CheckProxyRecords(m, m->DuplicateRecords); // Clear m->DuplicateRecords first, then m->ResourceRecords
+ CheckProxyRecords(m, m->ResourceRecords);
+ }
+
+ SetSPSProxyListChanged(mDNSNULL); // Perform any deferred BPF reconfiguration now
+
+ if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
+ {
+ m->DelaySleep = 0;
+ if (m->SleepState == SleepState_Transferring)
+ {
+ LogSPS("Re-sleep delay passed; now checking for Sleep Proxy Servers");
+ BeginSleepProcessing(m);
+ }
+ }
+
// 4. See if we can answer any of our new local questions from the cache
for (i=0; m->NewQuestions && i<1000; i++)
{
{
AuthRecord *rr = m->NewLocalRecords;
m->NewLocalRecords = m->NewLocalRecords->next;
- AnswerLocalQuestions(m, rr, mDNStrue);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
}
if (i >= 1000) LogMsg("mDNS_Execute: AnswerForNewLocalRecords exceeded loop limit");
// 5. See what packets we need to send
- if (m->mDNSPlatformStatus != mStatus_NoError || m->SleepState) DiscardDeregistrations(m);
- else if (m->SuppressSending == 0 || m->timenow - m->SuppressSending >= 0)
+ if (m->mDNSPlatformStatus != mStatus_NoError || (m->SleepState == SleepState_Sleeping))
+ DiscardDeregistrations(m);
+ if (m->mDNSPlatformStatus == mStatus_NoError && (m->SuppressSending == 0 || m->timenow - m->SuppressSending >= 0))
{
// If the platform code is ready, and we're not suppressing packet generation right now
// then send our responses, probes, and questions.
if (!question->DuplicateOf)
{
- LogOperation("ActivateUnicastQuery: %##s %s%s%s",
+ debugf("ActivateUnicastQuery: %##s %s%s%s",
question->qname.c, DNSTypeName(question->qtype), question->AuthInfo ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
if (question->LongLived)
}
}
-// Call mDNSCoreMachineSleep(m, mDNStrue) when the machine is about to go to sleep.
-// Call mDNSCoreMachineSleep(m, mDNSfalse) when the machine is has just woken up.
-// Normally, the platform support layer below mDNSCore should call this, not the client layer above.
-// Note that sleep/wake calls do not have to be paired one-for-one; it is acceptable to call
-// mDNSCoreMachineSleep(m, mDNSfalse) any time there is reason to believe that the machine may have just
-// found itself in a new network environment. For example, if the Ethernet hardware indicates that the
-// cable has just been connected, the platform support layer should call mDNSCoreMachineSleep(m, mDNSfalse)
-// to make mDNSCore re-issue its outstanding queries, probe for record uniqueness, etc.
-// While it is safe to call mDNSCoreMachineSleep(m, mDNSfalse) at any time, it does cause extra network
-// traffic, so it should only be called when there is legitimate reason to believe the machine
-// may have become attached to a new network.
-mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleepstate)
+mDNSexport void mDNSCoreRestartQueries(mDNS *const m)
{
- AuthRecord *rr;
-
- mDNS_Lock(m);
-
- m->SleepState = sleepstate;
- LogOperation("%s at %ld", sleepstate ? "Sleeping" : "Waking", m->timenow);
+ DNSQuestion *q;
- if (sleepstate)
- {
#ifndef UNICAST_DISABLED
- SuspendLLQs(m);
- SleepServiceRegistrations(m);
- SleepRecordRegistrations(m);
-#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);
- }
- else
+ // Retrigger all our uDNS questions
+ if (m->CurrentQuestion)
+ LogMsg("mDNSCoreRestartQueries: ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
+ m->CurrentQuestion = m->Questions;
+ while (m->CurrentQuestion)
{
- DNSQuestion *q;
- mDNSu32 slot;
- CacheGroup *cg;
- CacheRecord *cr;
+ q = m->CurrentQuestion;
+ m->CurrentQuestion = m->CurrentQuestion->next;
+ if (!mDNSOpaque16IsZero(q->TargetQID)) ActivateUnicastQuery(m, q, mDNStrue);
+ }
+#endif
-#ifndef UNICAST_DISABLED
- // On wake, retrigger all our uDNS questions
- if (m->CurrentQuestion)
- LogMsg("RestartQueries: ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
- m->CurrentQuestion = m->Questions;
- while (m->CurrentQuestion)
+ // Retrigger all our mDNS questions
+ for (q = m->Questions; q; q=q->next) // Scan our list of questions
+ if (mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q))
{
- q = m->CurrentQuestion;
- m->CurrentQuestion = m->CurrentQuestion->next;
- if (!mDNSOpaque16IsZero(q->TargetQID)) ActivateUnicastQuery(m, q, mDNStrue);
+ q->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
+ q->RequestUnicast = 2; // Set to 2 because is decremented once *before* we check it
+ q->LastQTime = m->timenow - q->ThisQInterval;
+ q->RecentAnswerPkts = 0;
+ ExpireDupSuppressInfo(q->DupSuppress, m->timenow);
+ m->NextScheduledQuery = m->timenow;
}
- // and reactivtate service registrations
- m->NextSRVUpdate = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
- LogOperation("WakeServiceRegistrations %d %d", m->timenow, m->NextSRVUpdate);
+ }
+
+// ***************************************************************************
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Power Management (Sleep/Wake)
#endif
- // 1. Retrigger all our mDNS questions
- for (q = m->Questions; q; q=q->next) // Scan our list of questions
- if (mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q))
- {
- q->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
- q->RequestUnicast = 2; // Set to 2 because is decremented once *before* we check it
- q->LastQTime = m->timenow - q->ThisQInterval;
- q->RecentAnswerPkts = 0;
- ExpireDupSuppressInfo(q->DupSuppress, m->timenow);
- m->NextScheduledQuery = m->timenow;
- }
- // 2. Re-validate our cache records
- m->NextCacheCheck = m->timenow;
- FORALL_CACHERECORDS(slot, cg, cr)
- mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForWake);
+mDNSlocal void SendSPSRegistration(mDNS *const m, NetworkInterfaceInfo *intf, const mDNSOpaque16 id)
+ {
+ const int ownerspace = mDNSSameEthAddress(&m->PrimaryMAC, &intf->MAC) ? DNSOpt_OwnerData_ID_Space : DNSOpt_OwnerData_ID_Wake_Space;
+ const int optspace = DNSOpt_Header_Space + DNSOpt_LeaseData_Space + ownerspace;
+ const int sps = intf->NextSPSAttempt / 3;
+ AuthRecord *rr;
- // 3. Retrigger probing and announcing for all our authoritative records
+ if (!intf->SPSAddr[sps].type)
+ {
+ intf->NextSPSAttemptTime = m->timenow + mDNSPlatformOneSecond;
+ if (m->NextScheduledSPRetry - intf->NextSPSAttemptTime > 0)
+ m->NextScheduledSPRetry = intf->NextSPSAttemptTime;
+ LogSPS("SendSPSRegistration: %s SPS %d (%d) %##s not yet resolved", intf->ifname, intf->NextSPSAttempt, sps, intf->NetWakeResolve[sps].qname.c);
+ goto exit;
+ }
+
+ // Mark our mDNS records (not unicast records) for transfer to SPS
+ if (mDNSOpaque16IsZero(id))
for (rr = m->ResourceRecords; rr; rr=rr->next)
- if (AuthRecord_uDNS(rr))
+ if (rr->resrec.RecordType > kDNSRecordTypeDeregistering)
+ if (rr->resrec.InterfaceID == intf->InterfaceID || (!rr->resrec.InterfaceID && (rr->ForceMCast || IsLocalDomain(rr->resrec.name))))
+ rr->SendRNow = mDNSInterfaceMark; // mark it now
+
+ while (1)
+ {
+ mDNSu8 *p = m->omsg.data;
+ // To comply with RFC 2782, PutResourceRecord suppresses name compression for SRV records in unicast updates.
+ // For now we follow that same logic for SPS registrations too.
+ // If we decide to compress SRV records in SPS registrations in the future, we can achieve that by creating our
+ // initial DNSMessage with h.flags set to zero, and then update it to UpdateReqFlags right before sending the packet.
+ InitializeDNSMessage(&m->omsg.h, mDNSOpaque16IsZero(id) ? mDNS_NewMessageID(m) : id, UpdateReqFlags);
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->SendRNow || (!mDNSOpaque16IsZero(id) && !AuthRecord_uDNS(rr) && mDNSSameOpaque16(rr->updateid, id) && m->timenow - (rr->LastAPTime + rr->ThisAPInterval) >= 0))
{
- ActivateUnicastRegistration(m, rr);
+ mDNSu8 *newptr;
+ const mDNSu8 *const limit = m->omsg.data + (m->omsg.h.mDNS_numUpdates ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData) - optspace;
+ if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
+ rr->resrec.rrclass |= kDNSClass_UniqueRRSet; // Temporarily set the 'unique' bit so PutResourceRecord will set it
+ newptr = PutResourceRecordTTLWithLimit(&m->omsg, p, &m->omsg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl, limit);
+ rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet; // Make sure to clear 'unique' bit back to normal state
+ if (!newptr)
+ LogSPS("SendSPSRegistration put %s FAILED %d/%d %s", intf->ifname, p - m->omsg.data, limit - m->omsg.data, ARDisplayString(m, rr));
+ else
+ {
+ LogSPS("SendSPSRegistration put %s %s", intf->ifname, ARDisplayString(m, rr));
+ rr->SendRNow = mDNSNULL;
+ rr->ThisAPInterval = mDNSPlatformOneSecond;
+ rr->LastAPTime = m->timenow;
+ rr->updateid = m->omsg.h.id;
+ if (m->NextScheduledResponse - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
+ m->NextScheduledResponse = (rr->LastAPTime + rr->ThisAPInterval);
+ p = newptr;
+ }
}
+
+ if (!m->omsg.h.mDNS_numUpdates) break;
+ else
+ {
+ AuthRecord opt;
+ mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
+ opt.resrec.rrclass = NormalMaxDNSMessageData;
+ opt.resrec.rdlength = sizeof(rdataOPT) * 2; // Two options in this OPT record
+ opt.resrec.rdestimate = sizeof(rdataOPT) * 2;
+ opt.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
+ opt.resrec.rdata->u.opt[0].optlen = DNSOpt_LeaseData_Space - 4;
+ opt.resrec.rdata->u.opt[0].u.updatelease = DEFAULT_UPDATE_LEASE;
+ SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[1]);
+ LogSPS("SendSPSRegistration put %s %s", intf->ifname, ARDisplayString(m, &opt));
+ p = PutResourceRecordTTLWithLimit(&m->omsg, p, &m->omsg.h.numAdditionals, &opt.resrec, opt.resrec.rroriginalttl, m->omsg.data + AbsoluteMaxDNSMessageData);
+ if (!p)
+ LogMsg("SendSPSRegistration: Failed to put OPT record (%d updates) %s", m->omsg.h.mDNS_numUpdates, ARDisplayString(m, &opt));
else
{
- if (rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->DependentOn) rr->resrec.RecordType = kDNSRecordTypeUnique;
- rr->ProbeCount = DefaultProbeCountForRecordType(rr->resrec.RecordType);
- rr->AnnounceCount = InitialAnnounceCount;
- InitializeLastAPTime(m, rr, DefaultAPIntervalForRecordType(rr->resrec.RecordType));
+ mStatus err;
+ LogSPS("SendSPSRegistration: Sending Update %s %d (%d) id %5d with %d records %d bytes to %#a:%d", intf->ifname, intf->NextSPSAttempt, sps,
+ mDNSVal16(m->omsg.h.id), m->omsg.h.mDNS_numUpdates, p - m->omsg.data, &intf->SPSAddr[sps], mDNSVal16(intf->SPSPort[sps]));
+ // if (intf->NextSPSAttempt < 5) m->omsg.h.flags = zeroID; // For simulating packet loss
+ err = mDNSSendDNSMessage(m, &m->omsg, p, intf->InterfaceID, mDNSNULL, &intf->SPSAddr[sps], intf->SPSPort[sps], mDNSNULL, mDNSNULL);
+ if (err) LogSPS("SendSPSRegistration: mDNSSendDNSMessage err %d", err);
+ if (err && intf->SPSAddr[sps].type == mDNSAddrType_IPv6 && intf->NetWakeResolve[sps].ThisQInterval == -1)
+ {
+ LogSPS("SendSPSRegistration %d %##s failed to send to IPv6 address; will try IPv4 instead", sps, intf->NetWakeResolve[sps].qname.c);
+ intf->NetWakeResolve[sps].qtype = kDNSType_A;
+ mDNS_StartQuery_internal(m, &intf->NetWakeResolve[sps]);
+ return;
+ }
}
+ }
}
- mDNS_Unlock(m);
+ intf->NextSPSAttemptTime = m->timenow + mDNSPlatformOneSecond * 10; // If successful, update NextSPSAttemptTime
+
+exit:
+ if (mDNSOpaque16IsZero(id) && intf->NextSPSAttempt < 8) intf->NextSPSAttempt++;
}
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - Packet Reception Functions
-#endif
+// RetrySPSRegistrations is called from SendResponses, with the lock held
+mDNSlocal void RetrySPSRegistrations(mDNS *const m)
+ {
+ AuthRecord *rr;
+ NetworkInterfaceInfo *intf;
-#define MustSendRecord(RR) ((RR)->NR_AnswerTo || (RR)->NR_AdditionalTo)
+ // First make sure none of our interfaces' NextSPSAttemptTimes are inadvertently set to m->timenow + mDNSPlatformOneSecond * 10
+ for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
+ if (intf->NextSPSAttempt && intf->NextSPSAttemptTime == m->timenow + mDNSPlatformOneSecond * 10)
+ intf->NextSPSAttemptTime++;
-mDNSlocal mDNSu8 *GenerateUnicastResponse(const DNSMessage *const query, const mDNSu8 *const end,
- const mDNSInterfaceID InterfaceID, mDNSBool LegacyQuery, DNSMessage *const response, AuthRecord *ResponseRecords)
- {
+ // Retry any record registrations that are due
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (!AuthRecord_uDNS(rr) && !mDNSOpaque16IsZero(rr->updateid) && m->timenow - (rr->LastAPTime + rr->ThisAPInterval) >= 0)
+ for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
+ if (!rr->resrec.InterfaceID || rr->resrec.InterfaceID == intf->InterfaceID)
+ {
+ LogSPS("RetrySPSRegistrations: %s", ARDisplayString(m, rr));
+ SendSPSRegistration(m, intf, rr->updateid);
+ }
+
+ // For interfaces where we did an SPS registration attempt, increment intf->NextSPSAttempt
+ for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
+ if (intf->NextSPSAttempt && intf->NextSPSAttemptTime == m->timenow + mDNSPlatformOneSecond * 10 && intf->NextSPSAttempt < 8)
+ intf->NextSPSAttempt++;
+ }
+
+mDNSlocal void NetWakeResolve(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
+ {
+ NetworkInterfaceInfo *intf = (NetworkInterfaceInfo *)question->QuestionContext;
+ int sps = question - intf->NetWakeResolve;
+ (void)m; // Unused
+ LogSPS("NetWakeResolve: SPS: %d Add: %d %s", sps, AddRecord, RRDisplayString(m, answer));
+
+ if (!AddRecord) return; // Don't care about REMOVE events
+ if (answer->rrtype != question->qtype) return; // Don't care about CNAMEs
+
+ mDNS_StopQuery(m, question);
+ question->ThisQInterval = -1;
+
+ if (answer->rrtype == kDNSType_SRV)
+ {
+ intf->SPSPort[sps] = answer->rdata->u.srv.port;
+ AssignDomainName(&question->qname, &answer->rdata->u.srv.target);
+ question->qtype = kDNSType_AAAA;
+ mDNS_StartQuery(m, question);
+ }
+ else if (answer->rrtype == kDNSType_AAAA && answer->rdlength == sizeof(mDNSv6Addr) && mDNSv6AddressIsLinkLocal(&answer->rdata->u.ipv6))
+ {
+ intf->SPSAddr[sps].type = mDNSAddrType_IPv6;
+ intf->SPSAddr[sps].ip.v6 = answer->rdata->u.ipv6;
+ mDNS_Lock(m);
+ if (sps == intf->NextSPSAttempt/3) SendSPSRegistration(m, intf, zeroID); // If we're ready for this result, use it now
+ mDNS_Unlock(m);
+ }
+ else if (answer->rrtype == kDNSType_AAAA && answer->rdlength == 0) // If negative answer for IPv6, look for IPv4 addresses instead
+ {
+ LogSPS("NetWakeResolve: SPS %d %##s has no IPv6 address, will try IPv4 instead", sps, question->qname.c);
+ question->qtype = kDNSType_A;
+ mDNS_StartQuery(m, question);
+ }
+ else if (answer->rrtype == kDNSType_A && answer->rdlength == sizeof(mDNSv4Addr))
+ {
+ intf->SPSAddr[sps].type = mDNSAddrType_IPv4;
+ intf->SPSAddr[sps].ip.v4 = answer->rdata->u.ipv4;
+ mDNS_Lock(m);
+ if (sps == intf->NextSPSAttempt/3) SendSPSRegistration(m, intf, zeroID); // If we're ready for this result, use it now
+ mDNS_Unlock(m);
+ }
+ }
+
+mDNSexport mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m)
+ {
+ AuthRecord *rr;
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.rrtype == kDNSType_SRV && !AuthRecord_uDNS(rr) && !mDNSSameIPPort(rr->resrec.rdata->u.srv.port, DiscardPort))
+ return mDNStrue;
+ return mDNSfalse;
+ }
+
+// BeginSleepProcessing is called, with the lock held, from either mDNS_Execute or mDNSCoreMachineSleep
+mDNSlocal void BeginSleepProcessing(mDNS *const m)
+ {
+ const CacheRecord *sps[3] = { mDNSNULL };
+
+ m->NextScheduledSPRetry = m->timenow;
+
+ if (!m->SystemWakeOnLANEnabled) LogSPS("BeginSleepProcessing: m->SystemWakeOnLANEnabled is false");
+ else if (!mDNSCoreHaveAdvertisedMulticastServices(m)) LogSPS("BeginSleepProcessing: No advertised services");
+ else // If we have at least one advertised service
+ {
+ NetworkInterfaceInfo *intf;
+ for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
+ {
+ if (!intf->NetWake) LogSPS("BeginSleepProcessing: %-6s not capable of magic packet wakeup", intf->ifname);
+ else
+ {
+ FindSPSInCache(m, &intf->NetWakeBrowse, sps);
+ if (!sps[0]) LogSPS("BeginSleepProcessing: %-6s %#a No Sleep Proxy Server found %d", intf->ifname, &intf->ip, intf->NetWakeBrowse.ThisQInterval);
+ else
+ {
+ int i;
+ 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
+ for (i=0; i<3; i++)
+ {
+#if ForceAlerts
+ if (intf->SPSAddr[i].type)
+ { LogMsg("BeginSleepProcessing: %s %d intf->SPSAddr[i].type %d", intf->ifname, i, intf->SPSAddr[i].type); *(long*)0 = 0; }
+ if (intf->NetWakeResolve[i].ThisQInterval >= 0)
+ { LogMsg("BeginSleepProcessing: %s %d intf->NetWakeResolve[i].ThisQInterval %d", intf->ifname, i, intf->NetWakeResolve[i].ThisQInterval); *(long*)0 = 0; }
+#endif
+ intf->SPSAddr[i].type = mDNSAddrType_None;
+ if (intf->NetWakeResolve[i].ThisQInterval >= 0) mDNS_StopQuery(m, &intf->NetWakeResolve[i]);
+ intf->NetWakeResolve[i].ThisQInterval = -1;
+ if (sps[i])
+ {
+ LogSPS("BeginSleepProcessing: %-6s Found Sleep Proxy Server %d TTL %d %s", intf->ifname, i, sps[i]->resrec.rroriginalttl, CRDisplayString(m, sps[i]));
+ mDNS_SetupQuestion(&intf->NetWakeResolve[i], intf->InterfaceID, &sps[i]->resrec.rdata->u.name, kDNSType_SRV, NetWakeResolve, intf);
+ intf->NetWakeResolve[i].ReturnIntermed = mDNStrue;
+ mDNS_StartQuery_internal(m, &intf->NetWakeResolve[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!sps[0]) // 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);
+ }
+ }
+
+// Call mDNSCoreMachineSleep(m, mDNStrue) when the machine is about to go to sleep.
+// Call mDNSCoreMachineSleep(m, mDNSfalse) when the machine is has just woken up.
+// Normally, the platform support layer below mDNSCore should call this, not the client layer above.
+mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
+ {
+ AuthRecord *rr;
+
+ mDNS_Lock(m);
+
+ LogSPS("%s (old state %d) at %ld", sleep ? "Sleeping" : "Waking", m->SleepState, m->timenow);
+
+ if (sleep && !m->SleepState) // Going to sleep
+ {
+ // If we're going to sleep, need to stop advertising that we're a Sleep Proxy Server
+ if (m->SPSSocket)
+ {
+ mDNSu8 oldstate = m->SPSState;
+ mDNS_DropLockBeforeCallback(); // mDNS_DeregisterService expects to be called without the lock held, so we emulate that here
+ m->SPSState = 2;
+ if (oldstate == 1) mDNS_DeregisterService(m, &m->SPSRecords);
+ mDNS_ReclaimLockAfterCallback();
+ }
+
+ m->SleepState = SleepState_Transferring;
+ if (m->SystemWakeOnLANEnabled && m->DelaySleep)
+ {
+ // If we just woke up moments ago, allow ten seconds for networking to stabilize before going back to sleep
+ LogSPS("mDNSCoreMachineSleep: Re-sleeping immediately after waking; will delay for %d ticks", m->DelaySleep - m->timenow);
+ m->SleepLimit = m->DelaySleep + mDNSPlatformOneSecond * 10;
+ }
+ else
+ {
+ m->DelaySleep = 0;
+ m->SleepLimit = m->timenow + mDNSPlatformOneSecond * 10;
+ BeginSleepProcessing(m);
+ }
+
+#ifndef UNICAST_DISABLED
+ SuspendLLQs(m);
+#endif
+ LogSPS("mDNSCoreMachineSleep: m->SleepState %d (%s) seq %d", m->SleepState,
+ m->SleepState == SleepState_Transferring ? "Transferring" :
+ m->SleepState == SleepState_Sleeping ? "Sleeping" : "?", m->SleepSeqNum);
+ }
+ else if (!sleep) // Waking up
+ {
+ mDNSu32 slot;
+ CacheGroup *cg;
+ CacheRecord *cr;
+ NetworkInterfaceInfo *intf;
+
+ // If we were previously sleeping, but now we're not, increment m->SleepSeqNum to indicate that we're entering a new period of wakefulness
+ if (m->SleepState != SleepState_Awake)
+ {
+ m->SleepState = SleepState_Awake;
+ m->SleepSeqNum++;
+ // If the machine wakes and then immediately tries to sleep again (e.g. a maintenance wake)
+ // then we enforce a minimum delay of 16 seconds before we begin sleep processing.
+ // This is to allow time for the Ethernet link to come up, DHCP to get an address, mDNS to issue queries, etc.,
+ // before we make our determination of whether there's a Sleep Proxy out there we should register with.
+ m->DelaySleep = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 16);
+ }
+
+ if (m->SPSState == 3)
+ {
+ mDNS_DropLockBeforeCallback(); // mDNS_DeregisterService expects to be called without the lock held, so we emulate that here
+ m->SPSState = 0;
+ mDNSCoreBeSleepProxyServer(m, m->SPSType, m->SPSPortability, m->SPSMarginalPower, m->SPSTotalPower);
+ mDNS_ReclaimLockAfterCallback();
+ }
+
+ // In case we gave up waiting and went to sleep before we got an ack from the Sleep Proxy,
+ // on wake we go through our record list and clear updateid back to zero
+ for (rr = m->ResourceRecords; rr; rr=rr->next) rr->updateid = zeroID;
+
+ // ... and the same for NextSPSAttempt
+ for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) intf->NextSPSAttempt = -1;
+
+ // Restart unicast and multicast queries
+ mDNSCoreRestartQueries(m);
+
+ // and reactivtate service registrations
+ m->NextSRVUpdate = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
+ LogInfo("WakeServiceRegistrations %d %d", m->timenow, m->NextSRVUpdate);
+
+ // 2. Re-validate our cache records
+ m->NextCacheCheck = m->timenow;
+ FORALL_CACHERECORDS(slot, cg, cr)
+ mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForWake);
+
+ // 3. Retrigger probing and announcing for all our authoritative records
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (AuthRecord_uDNS(rr))
+ {
+ ActivateUnicastRegistration(m, rr);
+ }
+ else
+ {
+ if (rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->DependentOn) rr->resrec.RecordType = kDNSRecordTypeUnique;
+ rr->ProbeCount = DefaultProbeCountForRecordType(rr->resrec.RecordType);
+ rr->AnnounceCount = InitialAnnounceCount;
+ InitializeLastAPTime(m, rr);
+ }
+
+ // 4. Refresh NAT mappings
+ // We don't want to have to assume that all hardware can necessarily keep accurate
+ // track of passage of time while asleep, so on wake we refresh our NAT mappings
+ m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
+ m->retryGetAddr = m->timenow;
+ RecreateNATMappings(m);
+ }
+
+ mDNS_Unlock(m);
+ }
+
+mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m)
+ {
+ DNSQuestion *q;
+ AuthRecord *rr;
+ ServiceRecordSet *srs;
+ NetworkInterfaceInfo *intf;
+
+ mDNS_Lock(m);
+
+ if (m->NextScheduledSPRetry - m->timenow > 0) goto notready;
+
+ m->NextScheduledSPRetry = m->timenow + 0x40000000UL;
+
+ if (m->DelaySleep) goto notready;
+
+ // 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)
+ {
+ LogSPS("ReadyForSleep retrying SPS %s %d", intf->ifname, intf->NextSPSAttempt);
+ SendSPSRegistration(m, intf, zeroID);
+ }
+ else
+ if (m->NextScheduledSPRetry - intf->NextSPSAttemptTime > 0)
+ m->NextScheduledSPRetry = intf->NextSPSAttemptTime;
+ }
+
+ // 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)
+ {
+ LogSPS("ReadyForSleep waiting for LLQ %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ 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)
+ if (srs->state == regState_NoTarget && srs->tcp) goto notready;
+
+ mDNS_Unlock(m);
+ return mDNStrue;
+
+notready:
+ mDNS_Unlock(m);
+ return mDNSfalse;
+ }
+
+mDNSexport mDNSs32 mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now)
+ {
+ AuthRecord *ar;
+
+ // Even when we have no wake-on-LAN-capable interfaces, or we failed to find a sleep proxy, or we have other
+ // failure scenarios, we still want to wake up in at most 120 minutes, to see if the network environment has changed.
+ // E.g. we might wake up and find no wireless network because the base station got rebooted just at that moment,
+ // and if that happens we don't want to just give up and go back to sleep and never try again.
+ mDNSs32 e = now + (120 * 60 * mDNSPlatformOneSecond); // Sleep for at most 120 minutes
+
+ NATTraversalInfo *nat;
+ for (nat = m->NATTraversals; nat; nat=nat->next)
+ if (nat->Protocol && nat->ExpiryTime && nat->ExpiryTime - now > mDNSPlatformOneSecond*4)
+ {
+ mDNSs32 t = nat->ExpiryTime - (nat->ExpiryTime - now) / 10; // Wake up when 90% of the way to the expiry time
+ if (e - t > 0) e = t;
+ LogSPS("ComputeWakeTime: %p %s Int %5d Ext %5d Err %d Retry %5d Interval %5d Expire %5d Wake %5d",
+ nat, nat->Protocol == NATOp_MapTCP ? "TCP" : "UDP",
+ mDNSVal16(nat->IntPort), mDNSVal16(nat->ExternalPort), nat->Result,
+ nat->retryPortMap ? (nat->retryPortMap - now) / mDNSPlatformOneSecond : 0,
+ nat->retryInterval / mDNSPlatformOneSecond,
+ nat->ExpiryTime ? (nat->ExpiryTime - now) / mDNSPlatformOneSecond : 0,
+ (t - now) / mDNSPlatformOneSecond);
+ }
+
+ // This loop checks both the time we need to renew wide-area registrations,
+ // and the time we need to renew Sleep Proxy registrations
+ for (ar = m->ResourceRecords; ar; ar = ar->next)
+ if (ar->expire && ar->expire - now > mDNSPlatformOneSecond*4)
+ {
+ mDNSs32 t = ar->expire - (ar->expire - now) / 10; // Wake up when 90% of the way to the expiry time
+ if (e - t > 0) e = t;
+ LogSPS("ComputeWakeTime: %p Int %7d Next %7d Expire %7d Wake %7d %s",
+ ar, ar->ThisAPInterval / mDNSPlatformOneSecond,
+ (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
+ ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
+ (t - now) / mDNSPlatformOneSecond, ARDisplayString(m, ar));
+ }
+
+ return(e - now);
+ }
+
+// ***************************************************************************
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Packet Reception Functions
+#endif
+
+#define MustSendRecord(RR) ((RR)->NR_AnswerTo || (RR)->NR_AdditionalTo)
+
+mDNSlocal mDNSu8 *GenerateUnicastResponse(const DNSMessage *const query, const mDNSu8 *const end,
+ const mDNSInterfaceID InterfaceID, mDNSBool LegacyQuery, DNSMessage *const response, AuthRecord *ResponseRecords)
+ {
mDNSu8 *responseptr = response->data;
const mDNSu8 *const limit = response->data + sizeof(response->data);
const mDNSu8 *ptr = query->data;
for (rr=ResponseRecords; rr; rr=rr->NextResponse)
if (rr->NR_AnswerTo)
{
- mDNSu8 *p = PutResourceRecordCappedTTL(response, responseptr, &response->h.numAnswers, &rr->resrec, maxttl);
+ mDNSu8 *p = PutResourceRecordTTL(response, responseptr, &response->h.numAnswers, &rr->resrec,
+ maxttl < rr->resrec.rroriginalttl ? maxttl : rr->resrec.rroriginalttl);
if (p) responseptr = p;
else { debugf("GenerateUnicastResponse: Ran out of space for answers!"); response->h.flags.b[0] |= kDNSFlag0_TC; }
}
for (rr=ResponseRecords; rr; rr=rr->NextResponse)
if (rr->NR_AdditionalTo && !rr->NR_AnswerTo)
{
- mDNSu8 *p = PutResourceRecordCappedTTL(response, responseptr, &response->h.numAdditionals, &rr->resrec, maxttl);
+ mDNSu8 *p = PutResourceRecordTTL(response, responseptr, &response->h.numAdditionals, &rr->resrec,
+ maxttl < rr->resrec.rroriginalttl ? maxttl : rr->resrec.rroriginalttl);
if (p) responseptr = p;
else debugf("GenerateUnicastResponse: No more space for additionals");
}
// Returns 0 if there is no conflict
// Returns +1 if there was a conflict and we won
// Returns -1 if there was a conflict and we lost and have to rename
-mDNSlocal int CompareRData(AuthRecord *our, CacheRecord *pkt)
+mDNSlocal int CompareRData(const AuthRecord *const our, const CacheRecord *const pkt)
{
mDNSu8 ourdata[256], *ourptr = ourdata, *ourend;
mDNSu8 pktdata[256], *pktptr = pktdata, *pktend;
// are members of the same RRSet, then this is not a conflict.
mDNSlocal mDNSBool PacketRRConflict(const mDNS *const m, const AuthRecord *const our, const CacheRecord *const pktrr)
{
- const AuthRecord *ourset = our->RRSet ? our->RRSet : our;
-
// If not supposed to be unique, not a conflict
if (!(our->resrec.RecordType & kDNSRecordTypeUniqueMask)) return(mDNSfalse);
// If a dependent record, not a conflict
if (our->DependentOn || MatchDependentOn(m, pktrr, our)) return(mDNSfalse);
+ else
+ {
+ // If the pktrr matches a member of ourset, not a conflict
+ const AuthRecord *ourset = our->RRSet ? our->RRSet : our;
+ const AuthRecord *pktset = FindRRSet(m, pktrr);
+ if (pktset == ourset) return(mDNSfalse);
- // If the pktrr matches a member of ourset, not a conflict
- if (FindRRSet(m, pktrr) == ourset) return(mDNSfalse);
+ // For records we're proxying, where we don't know the full
+ // relationship between the records, having any matching record
+ // in our AuthRecords list is sufficient evidence of non-conflict
+ if (our->WakeUp.HMAC.l[0] && pktset) return(mDNSfalse);
+ }
// Okay, this is a conflict
return(mDNStrue);
}
-// NOTE: ResolveSimultaneousProbe calls mDNS_Deregister_internal which can call a user callback, which may change
+// Note: ResolveSimultaneousProbe calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSlocal void ResolveSimultaneousProbe(mDNS *const m, const DNSMessage *const query, const mDNSu8 *const end,
int result = (int)our->resrec.rrclass - (int)m->rec.r.resrec.rrclass;
if (!result) result = (int)our->resrec.rrtype - (int)m->rec.r.resrec.rrtype;
if (!result) result = CompareRData(our, &m->rec.r);
- if (result > 0)
- LogOperation("ResolveSimultaneousProbe: %##s (%s): We won", our->resrec.name->c, DNSTypeName(our->resrec.rrtype));
- else if (result < 0)
+ if (result)
{
- LogOperation("ResolveSimultaneousProbe: %##s (%s): We lost", our->resrec.name->c, DNSTypeName(our->resrec.rrtype));
- mDNS_Deregister_internal(m, our, mDNS_Dereg_conflict);
+ const char *const msg = (result < 0) ? "lost:" : (result > 0) ? "won: " : "tie: ";
+ LogMsg("ResolveSimultaneousProbe: Pkt Record: %08lX %s", m->rec.r.resrec.rdatahash, CRDisplayString(m, &m->rec.r));
+ LogMsg("ResolveSimultaneousProbe: Our Record %d %s %08lX %s", our->ProbeCount, msg, our->resrec.rdatahash, ARDisplayString(m, our));
+ }
+ // If we lost the tie-break for simultaneous probes, we don't immediately give up, because we might be seeing stale packets on the network.
+ // Instead we pause for one second, to give the other host (if real) a change to establish its name, and then try probing again.
+ // If there really is another live host out there with the same name, it will answer our probes and we'll then rename.
+ if (result < 0)
+ {
+ m->SuppressProbes = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
+ our->ProbeCount = DefaultProbeCountForTypeUnique;
+ our->AnnounceCount = InitialAnnounceCount;
+ InitializeLastAPTime(m, our);
goto exit;
}
}
+#if 0
+ else
+ {
+ LogMsg("ResolveSimultaneousProbe: Pkt Record: %08lX %s", m->rec.r.resrec.rdatahash, CRDisplayString(m, &m->rec.r));
+ LogMsg("ResolveSimultaneousProbe: Our Record ign: %08lX %s", our->resrec.rdatahash, ARDisplayString(m, our));
+ }
+#endif
}
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
}
if (!FoundUpdate)
- LogOperation("ResolveSimultaneousProbe: %##s (%s): No Update Record found", our->resrec.name->c, DNSTypeName(our->resrec.rrtype));
+ LogInfo("ResolveSimultaneousProbe: %##s (%s): No Update Record found", our->resrec.name->c, DNSTypeName(our->resrec.rrtype));
exit:
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
}
return(rr);
}
+// Called from ProcessQuery when we get an mDNS packet with an owner record in it
+mDNSlocal void ClearProxyRecords(mDNS *const m, const OwnerOptData *const owner, AuthRecord *const thelist)
+ {
+ m->CurrentRecord = thelist;
+ while (m->CurrentRecord)
+ {
+ AuthRecord *const rr = m->CurrentRecord;
+ if (m->rec.r.resrec.InterfaceID == rr->resrec.InterfaceID && mDNSSameEthAddress(&owner->HMAC, &rr->WakeUp.HMAC))
+ if (owner->seq != rr->WakeUp.seq || m->timenow - rr->TimeRcvd > mDNSPlatformOneSecond * 60)
+ {
+ LogSPS("ClearProxyRecords: Removing %3d H-MAC %.6a I-MAC %.6a %d %d %s",
+ m->ProxyRecords, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, rr->WakeUp.seq, owner->seq, ARDisplayString(m, rr));
+ mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
+ SetSPSProxyListChanged(m->rec.r.resrec.InterfaceID);
+ }
+ // Mustn't advance m->CurrentRecord until *after* mDNS_Deregister_internal,
+ // because the list may have been changed in that call.
+ if (m->CurrentRecord == rr) // If m->CurrentRecord was not advanced for us, do it now
+ m->CurrentRecord = rr->next;
+ }
+ }
+
// ProcessQuery examines a received query to see if we have any answers to give
mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, const mDNSu8 *const end,
const mDNSAddr *srcaddr, const mDNSInterfaceID InterfaceID, mDNSBool LegacyQuery, mDNSBool QueryWasMulticast,
DNSQuestion **dqp = &DupQuestions;
mDNSs32 delayresponse = 0;
mDNSBool SendLegacyResponse = mDNSfalse;
- const mDNSu8 *ptr = query->data;
+ const mDNSu8 *ptr;
mDNSu8 *responseptr = mDNSNULL;
AuthRecord *rr;
int i;
// ***
- // *** 1. Parse Question Section and mark potential answers
+ // *** 1. Look in Additional Section for an OPT record
+ // ***
+ ptr = LocateOptRR(query, end, DNSOpt_OwnerData_ID_Space);
+ if (ptr)
+ {
+ ptr = GetLargeResourceRecord(m, query, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &m->rec);
+ if (m->rec.r.resrec.rrtype == kDNSType_OPT)
+ {
+ const rdataOPT *opt;
+ const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
+ // Find owner sub-option(s). We verify that the MAC is non-zero, otherwise we could inadvertently
+ // delete all our own AuthRecords (which are identified by having zero MAC tags on them).
+ for (opt = &m->rec.r.resrec.rdata->u.opt[0]; opt < e; opt++)
+ if (opt->opt == kDNSOpt_Owner && opt->u.owner.vers == 0 && opt->u.owner.HMAC.l[0])
+ {
+ ClearProxyRecords(m, &opt->u.owner, m->DuplicateRecords);
+ ClearProxyRecords(m, &opt->u.owner, m->ResourceRecords);
+ }
+ }
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+
+ // ***
+ // *** 2. Parse Question Section and mark potential answers
// ***
+ ptr = query->data;
for (i=0; i<query->h.numQuestions; i++) // For each question...
{
mDNSBool QuestionNeedsMulticastResponse;
int NumAnswersForThisQuestion = 0;
+ AuthRecord *NSECAnswer = mDNSNULL;
DNSQuestion pktq, *q;
ptr = getQuestion(query, ptr, end, InterfaceID, &pktq); // get the question...
if (!ptr) goto exit;
{
rr = m->CurrentRecord;
m->CurrentRecord = rr->next;
- if (ResourceRecordAnswersQuestion(&rr->resrec, &pktq) && (QueryWasMulticast || QueryWasLocalUnicast || rr->AllowRemoteQuery))
+ if (AnyTypeRecordAnswersQuestion(&rr->resrec, &pktq) && (QueryWasMulticast || QueryWasLocalUnicast || rr->AllowRemoteQuery))
{
- if (rr->resrec.RecordType == kDNSRecordTypeUnique)
- ResolveSimultaneousProbe(m, query, end, &pktq, rr);
- else if (ResourceRecordIsValidAnswer(rr))
+ if (RRTypeAnswersQuestionType(&rr->resrec, pktq.qtype))
{
- NumAnswersForThisQuestion++;
- // Notes:
- // NR_AnswerTo pointing into query packet means "answer via immediate legacy unicast" (may *also* choose to multicast)
- // NR_AnswerTo == (mDNSu8*)~1 means "answer via delayed unicast" (to modern querier; may promote to multicast instead)
- // NR_AnswerTo == (mDNSu8*)~0 means "definitely answer via multicast" (can't downgrade to unicast later)
- // If we're not multicasting this record because the kDNSQClass_UnicastResponse bit was set,
- // but the multicast querier is not on a matching subnet (e.g. because of overalyed subnets on one link)
- // then we'll multicast it anyway (if we unicast, the receiver will ignore it because it has an apparently non-local source)
- if (QuestionNeedsMulticastResponse || (!FromLocalSubnet && QueryWasMulticast && !LegacyQuery))
+ if (rr->resrec.RecordType == kDNSRecordTypeUnique)
+ ResolveSimultaneousProbe(m, query, end, &pktq, rr);
+ else if (ResourceRecordIsValidAnswer(rr))
{
- // We only mark this question for sending if it is at least one second since the last time we multicast it
- // on this interface. If it is more than a second, or LastMCInterface is different, then we may multicast it.
- // This is to guard against the case where someone blasts us with queries as fast as they can.
- if (m->timenow - (rr->LastMCTime + mDNSPlatformOneSecond) >= 0 ||
- (rr->LastMCInterface != mDNSInterfaceMark && rr->LastMCInterface != InterfaceID))
- rr->NR_AnswerTo = (mDNSu8*)~0;
+ NumAnswersForThisQuestion++;
+ // Note: We should check here if this is a probe-type query, and if so, generate an immediate
+ // unicast answer back to the source, because timeliness in answering probes is important.
+
+ // Notes:
+ // NR_AnswerTo pointing into query packet means "answer via immediate legacy unicast" (may *also* choose to multicast)
+ // NR_AnswerTo == (mDNSu8*)~1 means "answer via delayed unicast" (to modern querier; may promote to multicast instead)
+ // NR_AnswerTo == (mDNSu8*)~0 means "definitely answer via multicast" (can't downgrade to unicast later)
+ // If we're not multicasting this record because the kDNSQClass_UnicastResponse bit was set,
+ // but the multicast querier is not on a matching subnet (e.g. because of overlaid subnets on one link)
+ // then we'll multicast it anyway (if we unicast, the receiver will ignore it because it has an apparently non-local source)
+ if (QuestionNeedsMulticastResponse || (!FromLocalSubnet && QueryWasMulticast && !LegacyQuery))
+ {
+ // We only mark this question for sending if it is at least one second since the last time we multicast it
+ // on this interface. If it is more than a second, or LastMCInterface is different, then we may multicast it.
+ // This is to guard against the case where someone blasts us with queries as fast as they can.
+ if (m->timenow - (rr->LastMCTime + mDNSPlatformOneSecond) >= 0 ||
+ (rr->LastMCInterface != mDNSInterfaceMark && rr->LastMCInterface != InterfaceID))
+ rr->NR_AnswerTo = (mDNSu8*)~0;
+ }
+ else if (!rr->NR_AnswerTo) rr->NR_AnswerTo = LegacyQuery ? ptr : (mDNSu8*)~1;
}
- else if (!rr->NR_AnswerTo) rr->NR_AnswerTo = LegacyQuery ? ptr : (mDNSu8*)~1;
+ }
+ else if (rr->resrec.RecordType == kDNSRecordTypeVerified)
+ {
+ // If we don't have any answers for this question, but we do own another record with the same name,
+ // then mark it to generate an NSEC record on this interface
+ if (!NSECAnswer) NSECAnswer = rr;
}
}
}
+ if (NumAnswersForThisQuestion == 0 && NSECAnswer)
+ {
+ NumAnswersForThisQuestion++;
+ NSECAnswer->SendNSECNow = InterfaceID;
+ m->NextScheduledResponse = m->timenow;
+ }
+
// If we couldn't answer this question, someone else might be able to,
// so use random delay on response to reduce collisions
if (NumAnswersForThisQuestion == 0) delayresponse = mDNSPlatformOneSecond; // Divided by 50 = 20ms
- // We only do the following accelerated cache expiration processing and duplicate question suppression processing
- // for multicast queries with multicast responses.
- // For any query generating a unicast response we don't do this because we can't assume we will see the response
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
if (QuestionNeedsMulticastResponse)
+#else
+ // We only do the following accelerated cache expiration and duplicate question suppression processing
+ // for non-truncated multicast queries with multicast responses.
+ // For any query generating a unicast response we don't do this because we can't assume we will see the response.
+ // For truncated queries we don't do this because a response we're expecting might be suppressed by a subsequent
+ // known-answer packet, and when there's packet loss we can't safely assume we'll receive *all* known-answer packets.
+ if (QuestionNeedsMulticastResponse && !(query->h.flags.b[0] & kDNSFlag0_TC))
+#endif
{
const mDNSu32 slot = HashSlot(&pktq.qname);
CacheGroup *cg = CacheGroupForName(m, slot, pktq.qnamehash, &pktq.qname);
// Make a list indicating which of our own cache records we expect to see updated as a result of this query
// Note: Records larger than 1K are not habitually multicast, so don't expect those to be updated
- for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
- if (SameNameRecordAnswersQuestion(&cr->resrec, &pktq) && cr->resrec.rdlength <= SmallRecordLimit)
- if (!cr->NextInKAList && eap != &cr->NextInKAList)
- {
- *eap = cr;
- eap = &cr->NextInKAList;
- if (cr->MPUnansweredQ == 0 || m->timenow - cr->MPLastUnansweredQT >= mDNSPlatformOneSecond)
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ if (!(query->h.flags.b[0] & kDNSFlag0_TC))
+#endif
+ for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
+ if (SameNameRecordAnswersQuestion(&cr->resrec, &pktq) && cr->resrec.rdlength <= SmallRecordLimit)
+ if (!cr->NextInKAList && eap != &cr->NextInKAList)
{
- // Although MPUnansweredQ is only really used for multi-packet query processing,
- // we increment it for both single-packet and multi-packet queries, so that it stays in sync
- // with the MPUnansweredKA value, which by necessity is incremented for both query types.
- cr->MPUnansweredQ++;
- cr->MPLastUnansweredQT = m->timenow;
- cr->MPExpectingKA = mDNStrue;
+ *eap = cr;
+ eap = &cr->NextInKAList;
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ if (cr->MPUnansweredQ == 0 || m->timenow - cr->MPLastUnansweredQT >= mDNSPlatformOneSecond)
+ {
+ // Although MPUnansweredQ is only really used for multi-packet query processing,
+ // we increment it for both single-packet and multi-packet queries, so that it stays in sync
+ // with the MPUnansweredKA value, which by necessity is incremented for both query types.
+ cr->MPUnansweredQ++;
+ cr->MPLastUnansweredQT = m->timenow;
+ cr->MPExpectingKA = mDNStrue;
+ }
+#endif
}
- }
// Check if this question is the same as any of mine.
// We only do this for non-truncated queries. Right now it would be too complicated to try
// to keep track of duplicate suppression state between multiple packets, especially when we
// can't guarantee to receive all of the Known Answer packets that go with a particular query.
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
if (!(query->h.flags.b[0] & kDNSFlag0_TC))
+#endif
for (q = m->Questions; q; q=q->next)
if (!q->Target.type && ActiveQuestion(q) && m->timenow - q->LastQTxTime > mDNSPlatformOneSecond / 4)
if (!q->InterfaceID || q->InterfaceID == InterfaceID)
}
// ***
- // *** 2. Now we can safely build the list of marked answers
+ // *** 3. Now we can safely build the list of marked answers
// ***
for (rr = m->ResourceRecords; rr; rr=rr->next) // Now build our list of potential answers
if (rr->NR_AnswerTo) // If we marked the record...
AddRecordToResponseList(&nrp, rr, mDNSNULL); // ... add it to the list
// ***
- // *** 3. Add additional records
+ // *** 4. Add additional records
// ***
AddAdditionalsToResponseList(m, ResponseRecords, &nrp, InterfaceID);
// ***
- // *** 4. Parse Answer Section and cancel any records disallowed by Known-Answer list
+ // *** 5. Parse Answer Section and cancel any records disallowed by Known-Answer list
// ***
for (i=0; i<query->h.numAnswers; i++) // For each record in the query's answer section...
{
}
}
+ ourcacherr = FindIdenticalRecordInCache(m, &m->rec.r.resrec);
+
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
// See if this Known-Answer suppresses any answers we were expecting for our cache records. We do this always,
// even if the TC bit is not set (the TC bit will *not* be set in the *last* packet of a multi-packet KA list).
- ourcacherr = FindIdenticalRecordInCache(m, &m->rec.r.resrec);
if (ourcacherr && ourcacherr->MPExpectingKA && m->timenow - ourcacherr->MPLastUnansweredQT < mDNSPlatformOneSecond)
{
ourcacherr->MPUnansweredKA++;
ourcacherr->MPExpectingKA = mDNSfalse;
}
+#endif
- // Having built our ExpectedAnswers list from the questions in this packet, we can definitively
- // remove from our ExpectedAnswers list any records that are suppressed in the very same packet.
- // For answers that are suppressed in subsequent KA list packets, we rely on the MPQ/MPKA counting to track them.
+ // Having built our ExpectedAnswers list from the questions in this packet, we then remove
+ // any records that are suppressed by the Known Answer list in this packet.
eap = &ExpectedAnswers;
while (*eap)
{
}
// ***
- // *** 5. Cancel any additionals that were added because of now-deleted records
+ // *** 6. Cancel any additionals that were added because of now-deleted records
// ***
for (rr=ResponseRecords; rr; rr=rr->NextResponse)
if (rr->NR_AdditionalTo && !MustSendRecord(rr->NR_AdditionalTo))
{ rr->NR_AnswerTo = mDNSNULL; rr->NR_AdditionalTo = mDNSNULL; }
// ***
- // *** 6. Mark the send flags on the records we plan to send
+ // *** 7. Mark the send flags on the records we plan to send
// ***
for (rr=ResponseRecords; rr; rr=rr->NextResponse)
{
}
// ***
- // *** 7. If we think other machines are likely to answer these questions, set our packet suppression timer
+ // *** 8. If we think other machines are likely to answer these questions, set our packet suppression timer
// ***
if (delayresponse && (!m->SuppressSending || (m->SuppressSending - m->timenow) < (delayresponse + 49) / 50))
{
}
// ***
- // *** 8. If query is from a legacy client, or from a new client requesting a unicast reply, then generate a unicast response too
+ // *** 9. If query is from a legacy client, or from a new client requesting a unicast reply, then generate a unicast response too
// ***
if (SendLegacyResponse)
responseptr = GenerateUnicastResponse(query, end, InterfaceID, LegacyQuery, response, ResponseRecords);
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
// ***
- // *** 9. Finally, clear our link chains ready for use next time
+ // *** 10. Finally, clear our link chains ready for use next time
// ***
while (ResponseRecords)
{
{
cr->UnansweredQueries++;
cr->LastUnansweredTime = m->timenow;
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
if (cr->UnansweredQueries > 1)
debugf("ProcessQuery: (!TC) UAQ %lu MPQ %lu MPKA %lu %s",
cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
+#endif
SetNextCacheCheckTime(m, cr);
}
// then mark it to expire in five seconds if we don't get a response by then.
if (cr->UnansweredQueries >= MaxUnansweredQueries)
{
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
// Only show debugging message if this record was not about to expire anyway
if (RRExpireTime(cr) - m->timenow > 4 * mDNSPlatformOneSecond)
debugf("ProcessQuery: (Max) UAQ %lu MPQ %lu MPKA %lu mDNS_Reconfirm() for %s",
cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
+#endif
mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
}
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
// Make a guess, based on the multi-packet query / known answer counts, whether we think we
// should have seen an answer for this. (We multiply MPQ by 4 and MPKA by 5, to allow for
// possible packet loss of up to 20% of the additional KA packets.)
remain = kDefaultReconfirmTimeForNoAnswer;
mDNS_Reconfirm_internal(m, cr, remain);
}
+#endif
}
while (DupQuestions)
mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
};
-mDNSlocal const DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question)
+mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question)
{
DNSQuestion *q;
for (q = m->Questions; q; q=q->next)
- if (mDNSSameIPPort(q->LocalSocket ? q->LocalSocket->port : MulticastDNSPort, port) &&
- mDNSSameOpaque16(q->TargetQID, id) &&
- q->qtype == question->qtype &&
- q->qclass == question->qclass &&
- q->qnamehash == question->qnamehash &&
+ if (q->LocalSocket &&
+ mDNSSameIPPort (q->LocalSocket->port, port) &&
+ mDNSSameOpaque16(q->TargetQID, id) &&
+ q->qtype == question->qtype &&
+ q->qclass == question->qclass &&
+ q->qnamehash == question->qnamehash &&
SameDomainName(&q->qname, &question->qname))
return(q);
return(mDNSNULL);
(void)id;
(void)srcaddr;
for (q = m->Questions; q; q=q->next)
- if (ResourceRecordAnswersQuestion(&rr->resrec, q))
+ if (!q->DuplicateOf && ResourceRecordAnswersQuestion(&rr->resrec, q))
{
if (!mDNSOpaque16IsZero(q->TargetQID))
{
debugf("ExpectingUnicastResponseForRecord msg->h.id %d q->TargetQID %d for %s", mDNSVal16(id), mDNSVal16(q->TargetQID), CRDisplayString(m, rr));
if (mDNSSameOpaque16(q->TargetQID, id))
{
- if (mDNSSameIPPort(q->LocalSocket ? q->LocalSocket->port : MulticastDNSPort, port)) return(mDNStrue);
+ if (q->LocalSocket && mDNSSameIPPort(q->LocalSocket->port, port)) return(mDNStrue);
// if (mDNSSameAddress(srcaddr, &q->Target)) return(mDNStrue);
// if (q->LongLived && mDNSSameAddress(srcaddr, &q->servAddr)) return(mDNStrue); Shouldn't need this now that we have LLQType checking
// if (TrustedSource(m, srcaddr)) return(mDNStrue);
- LogOperation("WARNING: Ignoring suspect uDNS response for %##s (%s) [q->Target %#a] from %#a: %s",
- q->qname.c, DNSTypeName(q->qtype), &q->Target, srcaddr, CRDisplayString(m, rr));
+ LogInfo("WARNING: Ignoring suspect uDNS response for %##s (%s) [q->Target %#a:%d] from %#a:%d %s",
+ q->qname.c, DNSTypeName(q->qtype), &q->Target, mDNSVal16(q->LocalSocket ? q->LocalSocket->port : zeroIPPort), srcaddr, mDNSVal16(port), CRDisplayString(m, rr));
return(mDNSfalse);
}
}
return(mDNSfalse);
}
-mDNSexport CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg)
+// Certain data types need more space for in-memory storage than their in-packet rdlength would imply
+// Currently this applies only to rdata types containing more than one domainname,
+// or types where the domainname is not the last item in the structure.
+// In addition, NSEC currently requires less space for in-memory storage than its in-packet representation.
+mDNSlocal mDNSu16 GetRDLengthMem(const ResourceRecord *const rr)
{
- CacheRecord *rr = mDNSNULL;
-
- // Certain data types need more space for in-memory storage than their in-packet rdlength would imply
- // Currently this applies only to rdata types containing more than one domainname,
- // or types where the domainname is not the last item in the structure
- mDNSu16 RDLength;
- switch (m->rec.r.resrec.rrtype)
+ switch (rr->rrtype)
{
- case kDNSType_SOA: RDLength = sizeof(rdataSOA); break;
- case kDNSType_RP: RDLength = sizeof(rdataRP); break;
- case kDNSType_PX: RDLength = sizeof(rdataPX); break;
- default: RDLength = m->rec.r.resrec.rdlength; break;
+ case kDNSType_SOA: return sizeof(rdataSOA);
+ case kDNSType_RP: return sizeof(rdataRP);
+ case kDNSType_PX: return sizeof(rdataPX);
+ case kDNSType_NSEC:return sizeof(rdataNSEC);
+ default: return rr->rdlength;
}
+ }
+
+mDNSexport CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg)
+ {
+ CacheRecord *rr = mDNSNULL;
+ mDNSu16 RDLength = GetRDLengthMem(&m->rec.r.resrec);
if (!m->rec.r.resrec.InterfaceID) debugf("CreateNewCacheEntry %s", CRDisplayString(m, &m->rec.r));
//if (RDLength > InlineCacheRDSize)
- // LogOperation("Rdata len %4d > InlineCacheRDSize %d %s", RDLength, InlineCacheRDSize, CRDisplayString(m, &m->rec.r));
+ // LogInfo("Rdata len %4d > InlineCacheRDSize %d %s", RDLength, InlineCacheRDSize, CRDisplayString(m, &m->rec.r));
if (!cg) cg = GetCacheGroup(m, slot, &m->rec.r.resrec); // If we don't have a CacheGroup for this name, make one now
if (cg) rr = GetCacheRecord(m, cg, RDLength); // Make a cache record, being careful not to recycle cg
rr->resrec.name = cg->name; // And set rr->resrec.name to point into our CacheGroup header
// If this is an oversized record with external storage allocated, copy rdata to external storage
- if (rr->resrec.rdata == (RData*)&rr->rdatastorage && RDLength > InlineCacheRDSize)
+ if (rr->resrec.rdata == (RData*)&rr->smallrdatastorage && RDLength > InlineCacheRDSize)
LogMsg("rr->resrec.rdata == &rr->rdatastorage but length > InlineCacheRDSize %##s", m->rec.r.resrec.name->c);
- else if (rr->resrec.rdata != (RData*)&rr->rdatastorage && RDLength <= InlineCacheRDSize)
+ else if (rr->resrec.rdata != (RData*)&rr->smallrdatastorage && RDLength <= InlineCacheRDSize)
LogMsg("rr->resrec.rdata != &rr->rdatastorage but length <= InlineCacheRDSize %##s", m->rec.r.resrec.name->c);
if (RDLength > InlineCacheRDSize)
mDNSPlatformMemCopy(rr->resrec.rdata, m->rec.r.resrec.rdata, sizeofRDataHeader + RDLength);
else
rr->DelayDelivery = CheckForSoonToExpireRecords(m, rr->resrec.name, rr->resrec.namehash, slot);
- CacheRecordAdd(m, rr); // CacheRecordAdd calls SetNextCacheCheckTime(m, rr); for us
+ CacheRecordAdd(m, rr); // CacheRecordAdd calls SetNextCacheCheckTime(m, rr); for us
}
return(rr);
}
rr->TimeRcvd = m->timenow;
rr->resrec.rroriginalttl = ttl;
rr->UnansweredQueries = 0;
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
rr->MPUnansweredQ = 0;
rr->MPUnansweredKA = 0;
rr->MPExpectingKA = mDNSfalse;
+#endif
SetNextCacheCheckTime(m, rr);
}
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (rr->CRActiveQuestion == q)
{
- //LogOperation("GrantCacheExtensions: new lease %d / %s", lease, CRDisplayString(m, rr));
+ //LogInfo("GrantCacheExtensions: new lease %d / %s", lease, CRDisplayString(m, rr));
RefreshCacheRecord(m, rr, lease);
}
}
return ttl;
}
-// NOTE: mDNSCoreReceiveResponse calls mDNS_Deregister_internal which can call a user callback, which may change
+// Note: mDNSCoreReceiveResponse calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
+// InterfaceID non-NULL tells us the interface this multicast response was received on
+// InterfaceID NULL tells us this was a unicast response
+// dstaddr NULL tells us we received this over an outgoing TCP connection we made
mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
const DNSMessage *const response, const mDNSu8 *end,
const mDNSAddr *srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, mDNSIPPort dstport,
int firstauthority = response->h.numAnswers;
int firstadditional = firstauthority + response->h.numAuthorities;
int totalrecords = firstadditional + response->h.numAdditionals;
- const mDNSu8 *ptr = response->data;
-
- // Currently used only for display in debugging message
- (void)srcport;
- (void)dstport;
+ const mDNSu8 *ptr = response->data;
debugf("Received Response from %#-15a addressed to %#-15a on %p with "
"%2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s LLQType %d",
response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
response->h.numAdditionals, response->h.numAdditionals == 1 ? "" : "s", LLQType);
+ // According to RFC 2181 <http://www.ietf.org/rfc/rfc2181.txt>
+ // When a DNS client receives a reply with TC
+ // set, it should ignore that response, and query again, using a
+ // mechanism, such as a TCP connection, that will permit larger replies.
+ // It feels wrong to be throwing away data after the network went to all the trouble of delivering it to us, but
+ // delivering some records of the RRSet first and then the remainder a couple of milliseconds later was causing
+ // failures in our Microsoft Active Directory client, which expects to get the entire set of answers at once.
+ // <rdar://problem/6690034> Can't bind to Active Directory
+ // In addition, if the client immediately canceled its query after getting the initial partial response, then we'll
+ // abort our TCP connection, and not complete the operation, and end up with an incomplete RRSet in our cache.
+ // Next time there's a query for this RRSet we'll see answers in our cache, and assume we have the whole RRSet already,
+ // and not even do the TCP query.
+ // Accordingly, if we get a uDNS reply with kDNSFlag0_TC set, we bail out and wait for the TCP response containing the entire RRSet.
+ if (!InterfaceID && (response->h.flags.b[0] & kDNSFlag0_TC)) return;
+
if (LLQType == uDNS_LLQ_Ignore) return;
// 1. We ignore questions (if any) in mDNS response packets
// in this response packet are immediately deemed to be invalid.
else
{
+ mDNSu8 rcode = (mDNSu8)(response->h.flags.b[1] & kDNSFlag1_RC_Mask);
+ mDNSBool failure = !(rcode == kDNSFlag1_RC_NoErr || rcode == kDNSFlag1_RC_NXDomain || rcode == kDNSFlag1_RC_NotAuth);
+ mDNSBool returnEarly = mDNSfalse;
// We could possibly combine this with the similar loop at the end of this function --
// instead of tagging cache records here and then rescuing them if we find them in the answer section,
// we could instead use the "m->PktNum" mechanism to tag each cache record with the packet number in
// packet number, then we deduce they are old and delete them
for (i = 0; i < response->h.numQuestions && ptr && ptr < end; i++)
{
- DNSQuestion q;
+ DNSQuestion q, *qptr = mDNSNULL;
ptr = getQuestion(response, ptr, end, InterfaceID, &q);
- if (ptr && (!dstaddr || ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q)))
+ if (ptr && (!dstaddr || (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q))))
{
- CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&q.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
- for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
- if (SameNameRecordAnswersQuestion(&rr->resrec, &q))
+ if (!failure)
+ {
+ CacheRecord *rr;
+ const mDNSu32 slot = HashSlot(&q.qname);
+ CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
+ for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
+ if (q.InterfaceID == rr->resrec.InterfaceID && SameNameRecordAnswersQuestion(&rr->resrec, &q))
+ {
+ debugf("uDNS marking %p %##s (%s) %p %s", q.InterfaceID, q.qname.c, DNSTypeName(q.qtype),
+ rr->resrec.InterfaceID, CRDisplayString(m, rr));
+ // Don't want to disturb rroriginalttl here, because code below might need it for the exponential backoff doubling algorithm
+ rr->TimeRcvd = m->timenow - TicksTTL(rr) - 1;
+ rr->UnansweredQueries = MaxUnansweredQueries;
+ }
+ }
+ else
+ {
+ if (qptr)
{
- //LogMsg("uDNS marking %s", CRDisplayString(m, rr));
- // Don't want to disturb rroriginalttl here, because code below might need it for the exponential backoff doubling algorithm
- rr->TimeRcvd = m->timenow - TicksTTL(rr) - 1;
- rr->UnansweredQueries = MaxUnansweredQueries;
+ LogInfo("Server %p responded with code %d to query %##s (%s)", qptr->qDNSServer, rcode, q.qname.c, DNSTypeName(q.qtype));
+ PushDNSServerToEnd(m, qptr);
}
+ returnEarly = mDNStrue;
+ }
}
}
+ if (returnEarly)
+ {
+ LogInfo("Ignoring %2d Answer%s %2d Authorit%s %2d Additional%s",
+ response->h.numAnswers, response->h.numAnswers == 1 ? ", " : "s,",
+ response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
+ response->h.numAdditionals, response->h.numAdditionals == 1 ? "" : "s");
+ // not goto exit because we won't have any CacheFlushRecords and we do not want to
+ // generate negative cache entries (we want to query the next server)
+ return;
+ }
}
for (i = 0; i < totalrecords && ptr && ptr < end; i++)
if (!AcceptableResponse) AcceptableResponse = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r);
// 1. Check that this packet resource record does not conflict with any of ours
- if (mDNSOpaque16IsZero(response->h.id))
+ if (mDNSOpaque16IsZero(response->h.id) && m->rec.r.resrec.rrtype != kDNSType_NSEC)
{
if (m->CurrentRecord)
LogMsg("mDNSCoreReceiveResponse ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
// For other unicast responses, this code accepts them only for responses with an
// (apparently) local source address that pertain to a record of our own that's in probing state
if (!AcceptableResponse && !(ResponseSrcLocal && rr->resrec.RecordType == kDNSRecordTypeUnique)) continue;
+
if (PacketRRMatchesSignature(&m->rec.r, rr)) // If interface, name, type (if shared record) and class match...
{
// ... check to see if type and rdata are identical
- if (m->rec.r.resrec.rrtype == rr->resrec.rrtype && SameRData(&m->rec.r.resrec, &rr->resrec))
+ if (IdenticalSameNameRecord(&m->rec.r.resrec, &rr->resrec))
{
// If the RR in the packet is identical to ours, just check they're not trying to lower the TTL on us
if (m->rec.r.resrec.rroriginalttl >= rr->resrec.rroriginalttl/2 || m->SleepState)
// else, the packet RR has different type or different rdata -- check to see if this is a conflict
else if (m->rec.r.resrec.rroriginalttl > 0 && PacketRRConflict(m, rr, &m->rec.r))
{
- debugf("mDNSCoreReceiveResponse: Our Record: %08lX %s", rr-> resrec.rdatahash, ARDisplayString(m, rr));
- debugf("mDNSCoreReceiveResponse: Pkt Record: %08lX %s", m->rec.r.resrec.rdatahash, CRDisplayString(m, &m->rec.r));
+ LogInfo("mDNSCoreReceiveResponse: Pkt Record: %08lX %s", m->rec.r.resrec.rdatahash, CRDisplayString(m, &m->rec.r));
+ LogInfo("mDNSCoreReceiveResponse: Our Record: %08lX %s", rr-> resrec.rdatahash, ARDisplayString(m, rr));
// If this record is marked DependentOn another record for conflict detection purposes,
// then *that* record has to be bumped back to probing state to resolve the conflict
- while (rr->DependentOn) rr = rr->DependentOn;
+ if (rr->DependentOn)
+ {
+ while (rr->DependentOn) rr = rr->DependentOn;
+ LogInfo("mDNSCoreReceiveResponse: Dep Record: %08lX %s", rr-> resrec.rdatahash, ARDisplayString(m, rr));
+ }
// If we've just whacked this record's ProbeCount, don't need to do it again
- if (rr->ProbeCount <= DefaultProbeCountForTypeUnique)
+ if (rr->ProbeCount > DefaultProbeCountForTypeUnique)
+ LogInfo("mDNSCoreReceiveResponse: Already reset to Probing: %s", ARDisplayString(m, rr));
+ else if (rr->ProbeCount == DefaultProbeCountForTypeUnique)
+ LogMsg("mDNSCoreReceiveResponse: Ignoring response received before we even began probing: %s", ARDisplayString(m, rr));
+ else
{
+ LogMsg("mDNSCoreReceiveResponse: Received from %#a:%d %s", srcaddr, mDNSVal16(srcport), CRDisplayString(m, &m->rec.r));
// If we'd previously verified this record, put it back to probing state and try again
if (rr->resrec.RecordType == kDNSRecordTypeVerified)
{
- debugf("mDNSCoreReceiveResponse: Reseting to Probing: %##s (%s)", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ LogMsg("mDNSCoreReceiveResponse: Reseting to Probing: %s", ARDisplayString(m, rr));
rr->resrec.RecordType = kDNSRecordTypeUnique;
+ // We set ProbeCount to one more than the usual value so we know we've already touched this record.
+ // This is because our single probe for "example-name.local" could yield a response with (say) two A records and
+ // three AAAA records in it, and we don't want to call RecordProbeFailure() five times and count that as five conflicts.
+ // This special value is recognised and reset to DefaultProbeCountForTypeUnique in SendQueries().
rr->ProbeCount = DefaultProbeCountForTypeUnique + 1;
- InitializeLastAPTime(m, rr, DefaultAPIntervalForRecordType(kDNSRecordTypeUnique));
+ rr->AnnounceCount = InitialAnnounceCount;
+ InitializeLastAPTime(m, rr);
RecordProbeFailure(m, rr); // Repeated late conflicts also cause us to back off to the slower probing rate
}
// If we're probing for this record, we just failed
else if (rr->resrec.RecordType == kDNSRecordTypeUnique)
{
- debugf("mDNSCoreReceiveResponse: Will rename %##s (%s)", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ LogMsg("mDNSCoreReceiveResponse: ProbeCount %d; will rename %s", rr->ProbeCount, ARDisplayString(m, rr));
mDNS_Deregister_internal(m, rr, mDNS_Dereg_conflict);
}
- // We assumed this record must be unique, but we were wrong.
- // (e.g. There are two mDNSResponders on the same machine giving
- // different answers for the reverse mapping record.)
- // This is simply a misconfiguration, and we don't try to recover from it.
+ // We assumed this record must be unique, but we were wrong. (e.g. There are two mDNSResponders on the same machine giving
+ // different answers for the reverse mapping record.) This is simply a misconfiguration, and we don't try to recover from it.
else if (rr->resrec.RecordType == kDNSRecordTypeKnownUnique)
{
- debugf("mDNSCoreReceiveResponse: Unexpected conflict on %##s (%s) -- discarding our record",
- rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ LogMsg("mDNSCoreReceiveResponse: Unexpected conflict discarding %s", ARDisplayString(m, rr));
mDNS_Deregister_internal(m, rr, mDNS_Dereg_conflict);
}
else
- debugf("mDNSCoreReceiveResponse: Unexpected record type %X %##s (%s)",
- rr->resrec.RecordType, rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
+ LogMsg("mDNSCoreReceiveResponse: Unexpected record type %X %s", rr->resrec.RecordType, ARDisplayString(m, rr));
}
}
// Else, matching signature, different type or rdata, but not a considered a conflict.
if (!AcceptableResponse)
{
- CacheRecord *cr;
+ const CacheRecord *cr;
for (cr = CacheFlushRecords; cr != (CacheRecord*)1; cr = cr->NextInCFList)
{
domainname *target = GetRRDomainNameTarget(&cr->resrec);
const mDNSu32 slot = HashSlot(m->rec.r.resrec.name);
CacheGroup *cg = CacheGroupForRecord(m, slot, &m->rec.r.resrec);
CacheRecord *rr;
+
// 2a. Check if this packet resource record is already in our cache
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
{
{
if (!(r2->resrec.rroriginalttl == 240 && r1->resrec.rroriginalttl == 60 && r2->resrec.rrtype == kDNSType_TXT) &&
mDNSOpaque16IsZero(response->h.id))
- LogOperation("Correcting TTL from %4d to %4d for %s",
+ LogInfo("Correcting TTL from %4d to %4d for %s",
r2->resrec.rroriginalttl, r1->resrec.rroriginalttl, CRDisplayString(m, r2));
r2->resrec.rroriginalttl = r1->resrec.rroriginalttl;
}
ptr = getQuestion(response, ptr, end, InterfaceID, &q);
if (ptr && (!dstaddr || ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q)))
{
- CacheRecord *rr, *neg = mDNSNULL;
- mDNSu32 slot = HashSlot(&q.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
- for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
- if (SameNameRecordAnswersQuestion(&rr->resrec, &q))
- {
- // 1. If we got a fresh answer to this query, then don't need to generate a negative entry
- if (rr->TimeRcvd + TicksTTL(rr) - m->timenow > 0) break;
- // 2. If we already had a negative entry, keep track of it so we can resurrect it instead of creating a new one
- if (rr->resrec.RecordType == kDNSRecordTypePacketNegative) neg = rr;
- }
-
- if (!rr)
+ // When we're doing parallel unicast and multicast queries for dot-local names (for supporting Microsoft
+ // Active Directory sites) we don't want to waste memory making negative cache entries for all the unicast answers.
+ // Otherwise we just fill up our cache with negative entries for just about every single multicast name we ever look up
+ // (since the Microsoft Active Directory server is going to assert that pretty much every single multicast name doesn't exist).
+ // This is not only a waste of memory, but there's also the problem of those negative entries confusing us later -- e.g. we
+ // suppress sending our mDNS query packet because we think we already have a valid (negative) answer to that query in our cache.
+ // The one exception is that we *DO* want to make a negative cache entry for "local. SOA", for the (common) case where we're
+ // *not* on a Microsoft Active Directory network, and there is no authoritative server for "local". Note that this is not
+ // in conflict with the mDNS spec, because that spec says, "Multicast DNS Zones have no SOA record," so it's okay to cache
+ // negative answers for "local. SOA" from a uDNS server, because the mDNS spec already says that such records do not exist :-)
+ if (!InterfaceID && q.qtype != kDNSType_SOA && IsLocalDomain(&q.qname))
+ LogInfo("Not generating negative cache entry for %##s (%s)", q.qname.c, DNSTypeName(q.qtype));
+ else
{
- // We start off assuming a negative caching TTL of 60 seconds
- // but then look to see if we can find an SOA authority record to tell us a better value we should be using
- mDNSu32 negttl = 60;
- int repeat = 0;
- const domainname *name = &q.qname;
- mDNSu32 hash = q.qnamehash;
-
- // If we're going to make (or update) a negative entry, then look for the appropriate TTL from the SOA record
- if (response->h.numAuthorities && (ptr = LocateAuthorities(response, end)) != mDNSNULL)
- {
- ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
- if (ptr && m->rec.r.resrec.rrtype == kDNSType_SOA)
+ CacheRecord *rr, *neg = mDNSNULL;
+ mDNSu32 slot = HashSlot(&q.qname);
+ CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
+ for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
+ if (SameNameRecordAnswersQuestion(&rr->resrec, &q))
{
- mDNSu32 ttl_s = m->rec.r.resrec.rroriginalttl < m->rec.r.resrec.rdata->u.soa.min ?
- m->rec.r.resrec.rroriginalttl : m->rec.r.resrec.rdata->u.soa.min;
- if (negttl < ttl_s) negttl = ttl_s;
+ // 1. If we got a fresh answer to this query, then don't need to generate a negative entry
+ if (rr->TimeRcvd + TicksTTL(rr) - m->timenow > 0) break;
+ // 2. If we already had a negative entry, keep track of it so we can resurrect it instead of creating a new one
+ if (rr->resrec.RecordType == kDNSRecordTypePacketNegative) neg = rr;
+ }
+
+ if (!rr)
+ {
+ // We start off assuming a negative caching TTL of 60 seconds
+ // but then look to see if we can find an SOA authority record to tell us a better value we should be using
+ mDNSu32 negttl = 60;
+ int repeat = 0;
+ const domainname *name = &q.qname;
+ mDNSu32 hash = q.qnamehash;
- // Special check for SOA queries: If we queried for a.b.c.d.com, and got no answer,
- // with an Authority Section SOA record for d.com, then this is a hint that the authority
- // is d.com, and consequently SOA records b.c.d.com and c.d.com don't exist either.
- // To do this we set the repeat count so the while loop below will make a series of negative cache entries for us
- if (q.qtype == kDNSType_SOA)
+ // Special case for our special Microsoft Active Directory "local SOA" check.
+ // Some cheap home gateways don't include an SOA record in the authority section when
+ // they send negative responses, so we don't know how long to cache the negative result.
+ // Because we don't want to keep hitting the root name servers with our query to find
+ // if we're on a network using Microsoft Active Directory using "local" as a private
+ // internal top-level domain, we make sure to cache the negative result for at least one day.
+ if (q.qtype == kDNSType_SOA && SameDomainName(&q.qname, &localdomain)) negttl = 60 * 60 * 24;
+
+ // If we're going to make (or update) a negative entry, then look for the appropriate TTL from the SOA record
+ if (response->h.numAuthorities && (ptr = LocateAuthorities(response, end)) != mDNSNULL)
+ {
+ ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
+ if (ptr && m->rec.r.resrec.rrtype == kDNSType_SOA)
{
- int qcount = CountLabels(&q.qname);
- int scount = CountLabels(m->rec.r.resrec.name);
- if (qcount - 1 > scount)
- if (SameDomainName(SkipLeadingLabels(&q.qname, qcount - scount), m->rec.r.resrec.name))
- repeat = qcount - 1 - scount;
+ const rdataSOA *const soa = (const rdataSOA *)m->rec.r.resrec.rdata->u.data;
+ mDNSu32 ttl_s = soa->min;
+ // We use the lesser of the SOA.MIN field and the SOA record's TTL, *except*
+ // for the SOA record for ".", where the record is reported as non-cacheable
+ // (TTL zero) for some reason, so in this case we just take the SOA record's TTL as-is
+ if (ttl_s > m->rec.r.resrec.rroriginalttl && m->rec.r.resrec.name->c[0])
+ ttl_s = m->rec.r.resrec.rroriginalttl;
+ if (negttl < ttl_s) negttl = ttl_s;
+
+ // Special check for SOA queries: If we queried for a.b.c.d.com, and got no answer,
+ // with an Authority Section SOA record for d.com, then this is a hint that the authority
+ // is d.com, and consequently SOA records b.c.d.com and c.d.com don't exist either.
+ // To do this we set the repeat count so the while loop below will make a series of negative cache entries for us
+ if (q.qtype == kDNSType_SOA)
+ {
+ int qcount = CountLabels(&q.qname);
+ int scount = CountLabels(m->rec.r.resrec.name);
+ if (qcount - 1 > scount)
+ if (SameDomainName(SkipLeadingLabels(&q.qname, qcount - scount), m->rec.r.resrec.name))
+ repeat = qcount - 1 - scount;
+ }
}
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+
+ // If we already had a negative entry in the cache, then we double our existing negative TTL. This is to avoid
+ // the case where the record doesn't exist (e.g. particularly for things like our lb._dns-sd._udp.<domain> query),
+ // and the server returns no SOA record (or an SOA record with a small MIN TTL) so we assume a TTL
+ // of 60 seconds, and we end up polling the server every minute for a record that doesn't exist.
+ // With this fix in place, when this happens, we double the effective TTL each time (up to one hour),
+ // so that we back off our polling rate and don't keep hitting the server continually.
+ if (neg)
+ {
+ if (negttl < neg->resrec.rroriginalttl * 2)
+ negttl = neg->resrec.rroriginalttl * 2;
+ if (negttl > 3600)
+ negttl = 3600;
+ }
+
+ negttl = GetEffectiveTTL(LLQType, negttl); // Add 25% grace period if necessary
+
+ // If we already had a negative cache entry just update it, else make one or more new negative cache entries
+ if (neg)
+ {
+ debugf("Renewing negative TTL from %d to %d %s", neg->resrec.rroriginalttl, negttl, CRDisplayString(m, neg));
+ RefreshCacheRecord(m, neg, negttl);
+ }
+ else while (1)
+ {
+ debugf("mDNSCoreReceiveResponse making negative cache entry TTL %d for %##s (%s)", negttl, name->c, DNSTypeName(q.qtype));
+ MakeNegativeCacheRecord(m, &m->rec.r, name, hash, q.qtype, q.qclass, negttl, mDNSInterface_Any);
+ CreateNewCacheEntry(m, slot, cg);
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ if (!repeat) break;
+ repeat--;
+ name = (const domainname *)(name->c + 1 + name->c[0]);
+ hash = DomainNameHashValue(name);
+ slot = HashSlot(name);
+ cg = CacheGroupForName(m, slot, hash, name);
}
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
}
+ }
+ }
+ }
+ }
- // If we already had a negative entry in the cache, then we double our existing negative TTL. This is to avoid
- // the case where the record doesn't exist (e.g. particularly for things like our lb._dns-sd._udp.<domain> query),
- // and the server returns no SOA record (or an SOA record with a small MIN TTL) so we assume a TTL
- // of 60 seconds, and we end up polling the server every minute for a record that doesn't exist.
- // With this fix in place, when this happens, we double the effective TTL each time (up to one hour),
- // so that we back off our polling rate and don't keep hitting the server continually.
- if (neg)
- {
- if (negttl < neg->resrec.rroriginalttl * 2)
- negttl = neg->resrec.rroriginalttl * 2;
- if (negttl > 3600)
- negttl = 3600;
- }
+mDNSlocal void SPSRecordCallback(mDNS *const m, AuthRecord *const ar, mStatus result)
+ {
+ if (result && result != mStatus_MemFree)
+ LogInfo("SPS Callback %d %s", result, ARDisplayString(m, ar));
- negttl = GetEffectiveTTL(LLQType, negttl); // Add 25% grace period if necessary
+ if (result == mStatus_NameConflict)
+ {
+ LogMsg("Received Conflicting mDNS -- waking %s %.6a %s",
+ InterfaceNameForID(m, ar->resrec.InterfaceID), &ar->WakeUp.HMAC, ARDisplayString(m, ar));
+ SendWakeup(m, ar->resrec.InterfaceID, &ar->WakeUp.IMAC, &ar->WakeUp.password);
+ }
+ else if (result == mStatus_MemFree)
+ {
+ m->ProxyRecords--;
+ mDNSPlatformMemFree(ar);
+ }
+ }
- // If we already had a negative cache entry just update it, else make one or more new negative cache entries
- if (neg)
- {
- LogOperation("Renewing negative TTL from %d to %d %s", neg->resrec.rroriginalttl, negttl, CRDisplayString(m, neg));
- RefreshCacheRecord(m, neg, negttl);
- }
- else while (1)
+mDNSlocal void mDNSCoreReceiveUpdate(mDNS *const m,
+ const DNSMessage *const msg, const mDNSu8 *end,
+ const mDNSAddr *srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, mDNSIPPort dstport,
+ const mDNSInterfaceID InterfaceID)
+ {
+ int i;
+ AuthRecord opt;
+ mDNSu8 *p = m->omsg.data;
+ OwnerOptData owner;
+ mDNSu32 updatelease = 0;
+ const mDNSu8 *ptr;
+
+ LogSPS("Received Update from %#-15a:%-5d to %#-15a:%-5d on 0x%p with "
+ "%2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
+ srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), InterfaceID,
+ msg->h.numQuestions, msg->h.numQuestions == 1 ? ", " : "s,",
+ msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
+ msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
+ msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s");
+
+ if (!InterfaceID || !m->SPSSocket || !mDNSSameIPPort(dstport, m->SPSSocket->port)) return;
+
+ if (mDNS_PacketLoggingEnabled)
+ DumpPacket(m, mStatus_NoError, mDNSfalse, "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
+
+ ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space + DNSOpt_OwnerData_ID_Space);
+ if (ptr)
+ {
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
+ if (ptr && m->rec.r.resrec.rrtype == kDNSType_OPT)
+ {
+ const rdataOPT *o;
+ const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
+ for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
+ {
+ if (o->opt == kDNSOpt_Lease) updatelease = o->u.updatelease;
+ else if (o->opt == kDNSOpt_Owner && o->u.owner.vers == 0) owner = o->u.owner;
+ }
+ }
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+
+ InitializeDNSMessage(&m->omsg.h, msg->h.id, UpdateRespFlags);
+
+ if (!updatelease || !owner.HMAC.l[0])
+ {
+ static int msgs = 0;
+ if (msgs < 100)
+ {
+ msgs++;
+ LogMsg("Refusing sleep proxy registration from %#a:%d:%s%s", srcaddr, mDNSVal16(srcport),
+ !updatelease ? " No lease" : "", !owner.HMAC.l[0] ? " No owner" : "");
+ }
+ m->omsg.h.flags.b[1] |= kDNSFlag1_RC_FormErr;
+ }
+ else if (m->ProxyRecords + msg->h.mDNS_numUpdates > MAX_PROXY_RECORDS)
+ {
+ static int msgs = 0;
+ if (msgs < 100)
+ {
+ msgs++;
+ LogMsg("Refusing sleep proxy registration from %#a:%d: Too many records %d + %d = %d > %d", srcaddr, mDNSVal16(srcport),
+ m->ProxyRecords, msg->h.mDNS_numUpdates, m->ProxyRecords + msg->h.mDNS_numUpdates, MAX_PROXY_RECORDS);
+ }
+ m->omsg.h.flags.b[1] |= kDNSFlag1_RC_Refused;
+ }
+ else
+ {
+ LogSPS("Received Update for H-MAC %.6a I-MAC %.6a Password %.6a seq %d", &owner.HMAC, &owner.IMAC, &owner.password, owner.seq);
+
+ if (updatelease > 24 * 60 * 60)
+ updatelease = 24 * 60 * 60;
+
+ if (updatelease > 0x40000000UL / mDNSPlatformOneSecond)
+ updatelease = 0x40000000UL / mDNSPlatformOneSecond;
+
+ ptr = LocateAuthorities(msg, end);
+ for (i = 0; i < msg->h.mDNS_numUpdates && ptr && ptr < end; i++)
+ {
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
+ if (ptr)
+ {
+ mDNSu16 RDLengthMem = GetRDLengthMem(&m->rec.r.resrec);
+ AuthRecord *ar = mDNSPlatformMemAllocate(sizeof(AuthRecord) - sizeof(RDataBody) + RDLengthMem);
+ if (!ar) { m->omsg.h.flags.b[1] |= kDNSFlag1_RC_Refused; break; }
+ else
{
- LogOperation("mDNSCoreReceiveResponse making negative cache entry TTL %d for %##s (%s)", negttl, name->c, DNSTypeName(q.qtype));
- MakeNegativeCacheRecord(m, name, hash, q.qtype, q.qclass, negttl);
- CreateNewCacheEntry(m, slot, cg);
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- if (!repeat) break;
- repeat--;
- name = (const domainname *)(name->c + 1 + name->c[0]);
- hash = DomainNameHashValue(name);
- slot = HashSlot(name);
- cg = CacheGroupForName(m, slot, hash, name);
+ mDNSu8 RecordType = m->rec.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask ? kDNSRecordTypeUnique : kDNSRecordTypeShared;
+ m->rec.r.resrec.rrclass &= ~kDNSClass_UniqueRRSet;
+ mDNS_SetupResourceRecord(ar, mDNSNULL, InterfaceID, m->rec.r.resrec.rrtype, m->rec.r.resrec.rroriginalttl, RecordType, SPSRecordCallback, ar);
+ AssignDomainName(&ar->namestorage, m->rec.r.resrec.name);
+ ar->resrec.rdlength = GetRDLength(&m->rec.r.resrec, mDNSfalse);
+ ar->resrec.rdata->MaxRDLength = RDLengthMem;
+ mDNSPlatformMemCopy(ar->resrec.rdata->u.data, m->rec.r.resrec.rdata->u.data, RDLengthMem);
+ ar->WakeUp = owner;
+ if (m->rec.r.resrec.rrtype == kDNSType_PTR)
+ {
+ mDNSs32 t = ReverseMapDomainType(m->rec.r.resrec.name);
+ if (t == mDNSAddrType_IPv4) GetIPv4FromName(&ar->AddressProxy, m->rec.r.resrec.name);
+ else if (t == mDNSAddrType_IPv6) GetIPv6FromName(&ar->AddressProxy, m->rec.r.resrec.name);
+ debugf("mDNSCoreReceiveUpdate: PTR %d %d %#a %s", t, ar->AddressProxy.type, &ar->AddressProxy, ARDisplayString(m, ar));
+ if (ar->AddressProxy.type) SetSPSProxyListChanged(InterfaceID);
+ }
+ ar->TimeRcvd = m->timenow;
+ ar->TimeExpire = m->timenow + updatelease * mDNSPlatformOneSecond;
+ if (m->NextScheduledSPS - ar->TimeExpire > 0)
+ m->NextScheduledSPS = ar->TimeExpire;
+ mDNS_Register_internal(m, ar);
+ // For now, since we don't get IPv6 ND or data packets, we don't advertise AAAA records for our SPS clients
+ if (ar->resrec.rrtype == kDNSType_AAAA) ar->resrec.rroriginalttl = 0;
+ m->ProxyRecords++;
+ LogSPS("SPS Registered %4d %X %s", m->ProxyRecords, RecordType, ARDisplayString(m,ar));
}
}
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+
+ if (m->omsg.h.flags.b[1] & kDNSFlag1_RC_Mask)
+ {
+ LogMsg("Refusing sleep proxy registration from %#a:%d: Out of memory", srcaddr, mDNSVal16(srcport));
+ ClearProxyRecords(m, &owner, m->DuplicateRecords);
+ ClearProxyRecords(m, &owner, m->ResourceRecords);
+ }
+ else
+ {
+ mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
+ opt.resrec.rrclass = NormalMaxDNSMessageData;
+ opt.resrec.rdlength = sizeof(rdataOPT); // One option in this OPT record
+ opt.resrec.rdestimate = sizeof(rdataOPT);
+ opt.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
+ opt.resrec.rdata->u.opt[0].u.updatelease = updatelease;
+ p = PutResourceRecordTTLWithLimit(&m->omsg, p, &m->omsg.h.numAdditionals, &opt.resrec, opt.resrec.rroriginalttl, m->omsg.data + AbsoluteMaxDNSMessageData);
}
}
- }
-mDNSexport void MakeNegativeCacheRecord(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds)
- {
+ if (p) mDNSSendDNSMessage(m, &m->omsg, p, InterfaceID, m->SPSSocket, srcaddr, srcport, mDNSNULL, mDNSNULL);
+ }
+
+mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *end, const mDNSInterfaceID InterfaceID)
+ {
+ if (InterfaceID)
+ {
+ AuthRecord *rr;
+ mDNSu32 updatelease = 60 * 60; // If SPS fails to indicate lease time, assume one hour
+ const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
+ if (ptr)
+ {
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
+ if (ptr && m->rec.r.resrec.rrtype == kDNSType_OPT)
+ {
+ const rdataOPT *o;
+ const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
+ for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
+ if (o->opt == kDNSOpt_Lease)
+ {
+ updatelease = o->u.updatelease;
+ LogSPS("Sleep Proxy granted lease time %4d seconds", updatelease);
+ }
+ }
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == InterfaceID || (!rr->resrec.InterfaceID && (rr->ForceMCast || IsLocalDomain(rr->resrec.name))))
+ if (mDNSSameOpaque16(rr->updateid, msg->h.id))
+ {
+ rr->updateid = zeroID;
+ rr->expire = NonZeroTime(m->timenow + updatelease * mDNSPlatformOneSecond);
+ LogSPS("Sleep Proxy registered record %5d %s", updatelease, ARDisplayString(m,rr));
+ }
+
+ }
+ // If we were waiting to go to sleep, then this SPS registration or wide-area record deletion
+ // may have been the thing we were waiting for, so schedule another check to see if we can sleep now.
+ if (m->SleepLimit) m->NextScheduledSPRetry = m->timenow;
+ }
+
+mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
+ const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds, mDNSInterfaceID InterfaceID)
+ {
+ if (cr == &m->rec.r && m->rec.r.resrec.RecordType)
+ {
+ LogMsg("MakeNegativeCacheRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
+#if ForceAlerts
+ *(long*)0 = 0;
+#endif
+ }
+
// Create empty resource record
- m->rec.r.resrec.RecordType = kDNSRecordTypePacketNegative;
- m->rec.r.resrec.InterfaceID = mDNSInterface_Any;
- m->rec.r.resrec.name = name; // Will be updated to point to cg->name when we call CreateNewCacheEntry
- m->rec.r.resrec.rrtype = rrtype;
- m->rec.r.resrec.rrclass = rrclass;
- m->rec.r.resrec.rroriginalttl = ttl_seconds;
- m->rec.r.resrec.rdlength = 0;
- m->rec.r.resrec.rdestimate = 0;
- m->rec.r.resrec.namehash = namehash;
- m->rec.r.resrec.rdatahash = 0;
- m->rec.r.resrec.rdata = (RData*)&m->rec.r.rdatastorage;
- m->rec.r.resrec.rdata->MaxRDLength = m->rec.r.resrec.rdlength;
-
- m->rec.r.NextInKAList = mDNSNULL;
- m->rec.r.TimeRcvd = m->timenow;
- m->rec.r.DelayDelivery = 0;
- m->rec.r.NextRequiredQuery = m->timenow;
- m->rec.r.LastUsed = m->timenow;
- m->rec.r.CRActiveQuestion = mDNSNULL;
- m->rec.r.UnansweredQueries = 0;
- m->rec.r.LastUnansweredTime = 0;
- m->rec.r.MPUnansweredQ = 0;
- m->rec.r.MPLastUnansweredQT = 0;
- m->rec.r.MPUnansweredKA = 0;
- m->rec.r.MPExpectingKA = mDNSfalse;
- m->rec.r.NextInCFList = mDNSNULL;
+ cr->resrec.RecordType = kDNSRecordTypePacketNegative;
+ cr->resrec.InterfaceID = InterfaceID;
+ cr->resrec.name = name; // Will be updated to point to cg->name when we call CreateNewCacheEntry
+ cr->resrec.rrtype = rrtype;
+ cr->resrec.rrclass = rrclass;
+ cr->resrec.rroriginalttl = ttl_seconds;
+ cr->resrec.rdlength = 0;
+ cr->resrec.rdestimate = 0;
+ cr->resrec.namehash = namehash;
+ cr->resrec.rdatahash = 0;
+ cr->resrec.rdata = (RData*)&cr->smallrdatastorage;
+ cr->resrec.rdata->MaxRDLength = 0;
+
+ cr->NextInKAList = mDNSNULL;
+ cr->TimeRcvd = m->timenow;
+ cr->DelayDelivery = 0;
+ cr->NextRequiredQuery = m->timenow;
+ cr->LastUsed = m->timenow;
+ cr->CRActiveQuestion = mDNSNULL;
+ cr->UnansweredQueries = 0;
+ cr->LastUnansweredTime = 0;
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ cr->MPUnansweredQ = 0;
+ cr->MPLastUnansweredQT = 0;
+ cr->MPUnansweredKA = 0;
+ cr->MPExpectingKA = mDNSfalse;
+#endif
+ cr->NextInCFList = mDNSNULL;
}
mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *const end,
DNSMessage *msg = (DNSMessage *)pkt;
const mDNSu8 StdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery;
const mDNSu8 StdR = kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery;
+ const mDNSu8 UpdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_Update;
const mDNSu8 UpdR = kDNSFlag0_QR_Response | kDNSFlag0_OP_Update;
mDNSu8 QR_OP;
mDNSu8 *ptr = mDNSNULL;
return;
}
}
+#ifdef _LEGACY_NAT_TRAVERSAL_
+ else if (m->SSDPSocket && mDNSSameIPPort(dstport, m->SSDPSocket->port)) { debugf("Ignoring SSDP response from %#a:%d", srcaddr, mDNSVal16(srcport)); return; }
+#endif
+
#endif
if ((unsigned)(end - (mDNSu8 *)pkt) < sizeof(DNSMessageHeader)) { LogMsg("DNS Message too short"); return; }
QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
if (!mDNSOpaque16IsZero(msg->h.id)) // uDNS_ReceiveMsg only needs to get real uDNS responses, not "QU" mDNS responses
{
ifid = mDNSInterface_Any;
- if (mDNS_LogLevel >= MDNS_LOG_VERBOSE_DEBUG)
- DumpPacket(m, mDNSfalse, TLS ? "TLS" : !dstaddr ? "TCP" : "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
+ if (mDNS_PacketLoggingEnabled)
+ DumpPacket(m, mStatus_NoError, mDNSfalse, TLS ? "TLS" : !dstaddr ? "TCP" : "UDP", srcaddr, srcport, dstaddr, dstport, msg, end);
uDNS_ReceiveMsg(m, msg, end, srcaddr, srcport);
// Note: mDNSCore also needs to get access to received unicast responses
}
#endif
if (QR_OP == StdQ) mDNSCoreReceiveQuery (m, msg, end, srcaddr, srcport, dstaddr, dstport, ifid);
else if (QR_OP == StdR) mDNSCoreReceiveResponse(m, msg, end, srcaddr, srcport, dstaddr, dstport, ifid);
- else if (QR_OP != UpdR)
+ else if (QR_OP == UpdQ) mDNSCoreReceiveUpdate (m, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID);
+ else if (QR_OP == UpdR) mDNSCoreReceiveUpdateR (m, msg, end, InterfaceID);
+ else
{
- LogMsg("Unknown DNS packet type %02X%02X from %#-15a:%-5d to %#-15a:%-5d on %p (ignored)",
- msg->h.flags.b[0], msg->h.flags.b[1], srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), InterfaceID);
+ LogMsg("Unknown DNS packet type %02X%02X from %#-15a:%-5d to %#-15a:%-5d length %d on %p (ignored)",
+ msg->h.flags.b[0], msg->h.flags.b[1], srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), end-(mDNSu8 *)pkt, InterfaceID);
+ if (mDNS_LoggingEnabled)
+ {
+ int i = 0;
+ while (i<end-(mDNSu8 *)pkt)
+ {
+ char buffer[128];
+ char *p = buffer + mDNS_snprintf(buffer, sizeof(buffer), "%04X", i);
+ do if (i<end-(mDNSu8 *)pkt) p += mDNS_snprintf(p, sizeof(buffer), " %02X", ((mDNSu8 *)pkt)[i]); while (++i & 15);
+ LogInfo("%s", buffer);
+ }
+ }
}
// Packet reception often causes a change to the task list:
// 1. Inbound queries can cause us to need to send responses
// doing a standard DNS query for the _dns-query-tls._tcp SRV record for company.com. If we make the latter (public) query
// a duplicate of the former (private) query, then it will block forever waiting for an answer that will never come.
+// If IsLLQ(Q) is true, it means the question is both:
+// (a) long-lived and
+// (b) being performed by a unicast DNS long-lived query (either full LLQ, or polling)
+// for multicast questions, we don't want to treat LongLived as anything special
+#define IsLLQ(Q) ((Q)->LongLived && !mDNSOpaque16IsZero((Q)->TargetQID))
+
mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuestion *const question)
{
DNSQuestion *q;
SameQTarget(q, question) && // and same unicast/multicast target settings
q->qtype == question->qtype && // type,
q->qclass == question->qclass && // class,
- q->LongLived == question->LongLived && // and long-lived status matches
+ IsLLQ(q) == IsLLQ(question) && // and long-lived status matches
(!q->AuthInfo || question->AuthInfo) && // to avoid deadlock, don't make public query dup of a private one
q->qnamehash == question->qnamehash &&
SameDomainName(&q->qname, &question->qname)) // and name
// question->tcp = mDNSNULL;
if (q->LocalSocket)
- LogOperation("UpdateQuestionDuplicates transferred LocalSocket pointer for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ debugf("UpdateQuestionDuplicates transferred LocalSocket pointer for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
if (q->nta)
{
- LogOperation("UpdateQuestionDuplicates transferred nta pointer for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("UpdateQuestionDuplicates transferred nta pointer for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->nta->ZoneDataContext = q;
}
// Need to work out how to safely transfer this state too -- appropriate context pointers need to be updated or the code will crash
- if (question->tcp) LogOperation("UpdateQuestionDuplicates did not transfer tcp pointer");
+ if (question->tcp) LogInfo("UpdateQuestionDuplicates did not transfer tcp pointer");
if (question->state == LLQ_Established)
{
- LogOperation("UpdateQuestionDuplicates transferred LLQ state for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("UpdateQuestionDuplicates transferred LLQ state for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
question->state = 0; // Must zero question->state, or mDNS_StopQuery_internal will clean up and cancel our LLQ from the server
}
DNSQuestion *q;
(void)n; // Unused
mDNS_Lock(m);
- LogOperation("LLQNATCallback external address:port %.4a:%u", &n->ExternalAddress, mDNSVal16(n->ExternalPort));
+ LogInfo("LLQNATCallback external address:port %.4a:%u", &n->ExternalAddress, mDNSVal16(n->ExternalPort));
for (q = m->Questions; q; q=q->next)
if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID) && q->LongLived)
startLLQHandshake(m, q); // If ExternalPort is zero, will do StartLLQPolling instead
question->Target.type = mDNSAddrType_None;
}
- if (!question->Target.type) // No question->Target specified, so clear TargetPort and TargetQID
- {
- question->TargetPort = zeroIPPort;
- question->TargetQID = zeroID;
- }
+ if (!question->Target.type) question->TargetPort = zeroIPPort; // If question->Target specified clear TargetPort
question->TargetQID =
#ifndef UNICAST_DISABLED
- (question->InterfaceID != mDNSInterface_LocalOnly && !question->ForceMCast && !IsLocalDomain(&question->qname)) ? mDNS_NewMessageID(m) :
+ (question->Target.type || (question->InterfaceID == mDNSInterface_Unicast) ||
+ (question->InterfaceID != mDNSInterface_LocalOnly && !question->ForceMCast && !IsLocalDomain(&question->qname)))
+ ? mDNS_NewMessageID(m) :
#endif // UNICAST_DISABLED
zeroID;
if (*q)
{
- LogMsg("Error! Tried to add a question %##s (%s) that's already in the active list",
- question->qname.c, DNSTypeName(question->qtype));
+ LogMsg("Error! Tried to add a question %##s (%s) %p that's already in the active list",
+ question->qname.c, DNSTypeName(question->qtype), question);
return(mStatus_AlreadyRegistered);
}
*q = question;
// If this question is referencing a specific interface, verify it exists
- if (question->InterfaceID && question->InterfaceID != mDNSInterface_LocalOnly)
+ if (question->InterfaceID && question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_Unicast)
{
- NetworkInterfaceInfo *intf;
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->InterfaceID == question->InterfaceID) break;
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, question->InterfaceID);
if (!intf)
LogMsg("Note: InterfaceID %p for question %##s (%s) not currently found in active interface list",
question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
question->LastQTxTime = m->timenow;
question->CNAMEReferrals = 0;
+ // We'll create our question->LocalSocket on demand, if needed.
+ // We won't need one for duplicate questions, or from questions answered immediately out of the cache.
+ // We also don't need one for LLQs because (when we're using NAT) we want them all to share a single
+ // NAT mapping for receiving inbound add/remove events.
+ question->LocalSocket = mDNSNULL;
question->qDNSServer = mDNSNULL;
question->unansweredQueries = 0;
question->nta = mDNSNULL;
question->ntries = 0;
question->id = zeroOpaque64;
- question->LocalSocket = mDNSNULL;
-
if (question->DuplicateOf) question->AuthInfo = question->DuplicateOf->AuthInfo;
for (i=0; i<DupSuppressInfoSize; i++)
// this routine with the question list data structures in an inconsistent state.
if (!mDNSOpaque16IsZero(question->TargetQID))
{
- // We don't want to make a separate UDP socket for LLQs because (when we're using NAT)
- // they all share a single NAT mapping for receiving inbound add/remove events.
- if (!question->DuplicateOf && !question->LongLived)
- {
- question->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
- debugf("mDNS_StartQuery_internal: dup %p %##s (%s) port %d",
- question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype), question->LocalSocket ? mDNSVal16(question->LocalSocket->port) : -1);
- // If we fail to get a new on-demand socket (should only happen cases of the most extreme resource exhaustion)
- // then we don't fail the query; we just let it use our pre-canned permanent socket, which is okay (it should
- // never happen in normal operation, and even if it does we still have our cryptographically strong transaction ID).
- }
-
question->qDNSServer = GetServerForName(m, &question->qname);
ActivateUnicastQuery(m, question, mDNSfalse);
// CancelGetZoneData is an internal routine (i.e. must be called with the lock already held)
mDNSexport void CancelGetZoneData(mDNS *const m, ZoneData *nta)
{
- LogOperation("CancelGetZoneData %##s (%s)", nta->question.qname.c, DNSTypeName(nta->question.qtype));
+ debugf("CancelGetZoneData %##s (%s)", nta->question.qname.c, DNSTypeName(nta->question.qtype));
mDNS_StopQuery_internal(m, &nta->question);
mDNSPlatformMemFree(nta);
}
CacheRecord *rr;
DNSQuestion **qp = &m->Questions;
- //LogOperation("mDNS_StopQuery_internal %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+ //LogInfo("mDNS_StopQuery_internal %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
if (question->InterfaceID == mDNSInterface_LocalOnly) qp = &m->LocalOnlyQuestions;
while (*qp && *qp != question) qp=&(*qp)->next;
LogMsg("mDNS_StopQuery ERROR LLQNAT.clientContext NULL");
else
{
- LogOperation("Stopping LLQNAT");
+ LogInfo("Stopping LLQNAT");
mDNS_StopNATOperation_internal(m, &m->LLQNAT);
m->LLQNAT.clientContext = mDNSNULL; // Means LLQ NAT Traversal not running
}
status = mDNS_StopQuery_internal(m, question);
if (status == mStatus_NoError && !qq)
{
- CacheRecord *rr;
+ const CacheRecord *rr;
const mDNSu32 slot = HashSlot(&question->qname);
CacheGroup *const cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
- LogOperation("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+ LogInfo("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (rr->resrec.RecordType != kDNSRecordTypePacketNegative && SameNameRecordAnswersQuestion(&rr->resrec, question))
{
return(status);
}
-mDNSexport mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
+mDNSlocal mStatus mDNS_StartBrowse_internal(mDNS *const m, DNSQuestion *const question,
const domainname *const srv, const domainname *const domain,
const mDNSInterfaceID InterfaceID, mDNSBool ForceMCast, mDNSQuestionCallback *Callback, void *Context)
{
question->LastQTime = m->timenow - question->ThisQInterval;
}
#endif // UNICAST_DISABLED
- return(mDNS_StartQuery(m, question));
+ return(mDNS_StartQuery_internal(m, question));
+ }
+
+mDNSexport mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
+ const domainname *const srv, const domainname *const domain,
+ const mDNSInterfaceID InterfaceID, mDNSBool ForceMCast, mDNSQuestionCallback *Callback, void *Context)
+ {
+ mStatus status;
+ mDNS_Lock(m);
+ status = mDNS_StartBrowse_internal(m, question, srv, domain, InterfaceID, ForceMCast, Callback, Context);
+ mDNS_Unlock(m);
+ return(status);
}
mDNSlocal mDNSBool MachineHasActiveIPv6(mDNS *const m)
mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
- //LogOperation("FoundServiceInfo %d %s", AddRecord, RRDisplayString(m, answer));
+ //LogInfo("FoundServiceInfo %d %s", AddRecord, RRDisplayString(m, answer));
if (!AddRecord) return;
if (answer->rrtype == kDNSType_A)
// even though there's no actual semantic change, so the mDNSPlatformMemSame() check doesn't help us.
// To work around this, we simply unilaterally limit all legacy _ichat-type updates to a single announcement.
if (SameDomainLabel(type.c, (mDNSu8*)"\x6_ichat")) rr->AnnounceCount = 1;
- InitializeLastAPTime(m, rr, DefaultAPIntervalForRecordType(rr->resrec.RecordType));
+ InitializeLastAPTime(m, rr);
while (rr->NextUpdateCredit && m->timenow - rr->NextUpdateCredit >= 0) GrantUpdateCredit(rr);
if (!rr->UpdateBlocked && rr->UpdateCredits) rr->UpdateCredits--;
if (!rr->NextUpdateCredit) rr->NextUpdateCredit = NonZeroTime(m->timenow + kUpdateCreditRefreshInterval);
return(mStatus_NoError);
}
-// NOTE: mDNS_Deregister calls mDNS_Deregister_internal which can call a user callback, which may change
+// Note: mDNS_Deregister calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSexport mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr)
if (!AppendDomainLabel(&newmname, &m->hostlabel)) { LogMsg("ERROR: mDNS_SetFQDN: Cannot create MulticastHostname"); return; }
if (!AppendLiteralLabelString(&newmname, "local")) { LogMsg("ERROR: mDNS_SetFQDN: Cannot create MulticastHostname"); return; }
- if (SameDomainNameCS(&m->MulticastHostname, &newmname)) { LogMsg("mDNS_SetFQDN - hostname unchanged"); return; }
mDNS_Lock(m);
- AssignDomainName(&m->MulticastHostname, &newmname);
- // 1. Stop advertising our address records on all interfaces
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise) DeadvertiseInterface(m, intf);
-
- // 2. Start advertising our address records using the new name
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->Advertise) AdvertiseInterface(m, intf);
+ if (SameDomainNameCS(&m->MulticastHostname, &newmname)) debugf("mDNS_SetFQDN - hostname unchanged");
+ else
+ {
+ AssignDomainName(&m->MulticastHostname, &newmname);
+
+ // 1. Stop advertising our address records on all interfaces
+ for (intf = m->HostInterfaces; intf; intf = intf->next)
+ if (intf->Advertise) DeadvertiseInterface(m, intf);
+
+ // 2. Start advertising our address records using the new name
+ for (intf = m->HostInterfaces; intf; intf = intf->next)
+ if (intf->Advertise) AdvertiseInterface(m, intf);
+ }
- // 3. Make sure that any SRV records (and the like) that reference our
- // host name in their rdata get updated to reference this new host name
+ // 3. Make sure that any AutoTarget SRV records (and the like) get updated
for (rr = m->ResourceRecords; rr; rr=rr->next) if (rr->AutoTarget) SetTargetToHostName(m, rr);
for (rr = m->DuplicateRecords; rr; rr=rr->next) if (rr->AutoTarget) SetTargetToHostName(m, rr);
m->MainCallback(m, mStatus_NameConflict);
// 2. If the client callback didn't do it, add (or increment) an index ourselves
- // This needs to be case-insensitive compare, because we need to know that the name has been changed so as to
+ // This needs to be case-INSENSITIVE compare, because we need to know that the name has been changed so as to
// remedy the conflict, and a name that differs only in capitalization will just suffer the exact same conflict again.
- if (SameDomainLabelCS(m->hostlabel.c, oldlabel.c))
+ if (SameDomainLabel(m->hostlabel.c, oldlabel.c))
IncrementLabelSuffix(&m->hostlabel, mDNSfalse);
// 3. Generate the FQDNs from the hostlabel,
debugf("mDNS_HostNameCallback: MemFree (ignored)");
}
else
- LogMsg("mDNS_HostNameCallback: Unknown error %ld for registration of record %s", result, rr->resrec.name->c);
+ LogMsg("mDNS_HostNameCallback: Unknown error %d for registration of record %s", result, rr->resrec.name->c);
}
mDNSlocal void UpdateInterfaceProtocols(mDNS *const m, NetworkInterfaceInfo *active)
}
}
-mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
+mDNSlocal void RestartRecordGetZoneData(mDNS * const m)
{
AuthRecord *rr;
ServiceRecordSet *s;
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (AuthRecord_uDNS(rr))
+ {
+ debugf("RestartRecordGetZoneData: StartGetZoneData for %##s", rr->resrec.name->c);
+ if (rr->nta) CancelGetZoneData(m, rr->nta);
+ rr->nta = StartGetZoneData(m, rr->resrec.name, ZoneServiceUpdate, RecordRegistrationGotZoneData, rr);
+ }
+
+ for (s = m->ServiceRegistrations; s; s = s->uDNS_next)
+ {
+ debugf("RestartRecordGetZoneData: StartGetZoneData for %##s", s->RR_SRV.resrec.name->c);
+ if (s->srs_nta) CancelGetZoneData(m, s->srs_nta);
+ s->srs_nta = StartGetZoneData(m, s->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, s);
+ }
+ }
+
+mDNSlocal void InitializeNetWakeState(mDNS *const m, NetworkInterfaceInfo *set)
+ {
+ int i;
+ set->NetWakeBrowse.ThisQInterval = -1;
+ for (i=0; i<3; i++)
+ {
+ set->NetWakeResolve[i].ThisQInterval = -1;
+ set->SPSAddr[i].type = mDNSAddrType_None;
+ }
+ set->NextSPSAttempt = -1;
+ set->NextSPSAttemptTime = m->timenow;
+ }
+
+mDNSexport void mDNS_ActivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set)
+ {
+ NetworkInterfaceInfo *p = m->HostInterfaces;
+ while (p && p != set) p=p->next;
+ if (!p) { LogMsg("mDNS_ActivateNetWake_internal: NetworkInterfaceInfo %p not found in active list", set); return; }
+
+ if (set->InterfaceActive)
+ {
+ LogSPS("ActivateNetWake for %s (%#a)", set->ifname, &set->ip);
+ mDNS_StartBrowse_internal(m, &set->NetWakeBrowse, &SleepProxyServiceType, &localdomain, set->InterfaceID, mDNSfalse, m->SPSBrowseCallback, set);
+ }
+ }
+
+mDNSexport void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set)
+ {
+ NetworkInterfaceInfo *p = m->HostInterfaces;
+ while (p && p != set) p=p->next;
+ if (!p) { LogMsg("mDNS_DeactivateNetWake_internal: NetworkInterfaceInfo %p not found in active list", set); return; }
+
+ if (set->NetWakeBrowse.ThisQInterval >= 0)
+ {
+ int i;
+ LogSPS("DeactivateNetWake for %s (%#a)", set->ifname, &set->ip);
+
+ // Stop our browse and resolve operations
+ mDNS_StopQuery_internal(m, &set->NetWakeBrowse);
+ for (i=0; i<3; i++) if (set->NetWakeResolve[i].ThisQInterval >= 0) mDNS_StopQuery_internal(m, &set->NetWakeResolve[i]);
+
+ // Make special call to the browse callback to let it know it can to remove all records for this interface
+ if (m->SPSBrowseCallback) m->SPSBrowseCallback(m, &set->NetWakeBrowse, mDNSNULL, mDNSfalse);
+
+ // Reset our variables back to initial state, so we're ready for when NetWake is turned back on
+ // (includes resetting NetWakeBrowse.ThisQInterval back to -1)
+ InitializeNetWakeState(m, set);
+ }
+ }
+
+mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
+ {
+ AuthRecord *rr;
mDNSBool FirstOfType = mDNStrue;
NetworkInterfaceInfo **p = &m->HostInterfaces;
set->InterfaceActive = mDNStrue;
set->IPv4Available = (set->ip.type == mDNSAddrType_IPv4 && set->McastTxRx);
set->IPv6Available = (set->ip.type == mDNSAddrType_IPv6 && set->McastTxRx);
+
+ InitializeNetWakeState(m, set);
// Scan list to see if this InterfaceID is already represented
while (*p)
if (set->Advertise)
AdvertiseInterface(m, set);
- LogOperation("mDNS_RegisterInterface: InterfaceID %p %s (%#a) %s", set->InterfaceID, set->ifname, &set->ip,
+ LogInfo("mDNS_RegisterInterface: InterfaceID %p %s (%#a) %s", set->InterfaceID, set->ifname, &set->ip,
set->InterfaceActive ?
"not represented in list; marking active and retriggering queries" :
"already represented in list; marking inactive for now");
+ if (set->NetWake) mDNS_ActivateNetWake_internal(m, set);
+
// In early versions of OS X the IPv6 address remains on an interface even when the interface is turned off,
// giving the false impression that there's an active representative of this interface when there really isn't.
// Therefore, when registering an interface, we want to re-trigger our questions and re-probe our Resource Records,
// If flapping, delay between first and second queries is eight seconds instead of one
mDNSs32 delay = flapping ? mDNSPlatformOneSecond * 5 : 0;
mDNSu8 announce = flapping ? (mDNSu8)1 : InitialAnnounceCount;
+ mDNSs32 newSS = 0;
// Use a small amount of randomness:
// In the case of a network administrator turning on an Ethernet hub so that all the
// connected machines establish link at exactly the same time, we don't want them all
// to go and hit the network with identical queries at exactly the same moment.
- if (!m->SuppressSending) m->SuppressSending = m->timenow + (mDNSs32)mDNSRandom((mDNSu32)InitialQuestionInterval);
+ newSS = m->timenow + (mDNSs32)mDNSRandom((mDNSu32)InitialQuestionInterval);
+#if APPLE_OSX_mDNSResponder
+ // We set this to at least 2 seconds, because the MacOSX platform layer typically gets lots
+ // of network change notifications in a row, and we don't know when we're done getting notified.
+ // Note that this will not be set if the interface doesn't do multicast (set->McastTxRx).
+ newSS += mDNSPlatformOneSecond * 2;
+#endif
+ if (!m->SuppressSending || newSS - m->SuppressSending < 0) m->SuppressSending = newSS;
if (flapping)
{
- LogMsg("Note: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect", set->ifname, &set->ip);
+ LogMsg("Note: RegisterInterface: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect",
+ set->ifname, &set->ip);
if (!m->SuppressProbes ||
m->SuppressProbes - (m->timenow + delay) < 0)
m->SuppressProbes = (m->timenow + delay);
mDNSBool dodelay = flapping && (q->FlappingInterface1 == set->InterfaceID || q->FlappingInterface2 == set->InterfaceID);
mDNSs32 initial = dodelay ? InitialQuestionInterval * QuestionIntervalStep2 : InitialQuestionInterval;
mDNSs32 qdelay = dodelay ? mDNSPlatformOneSecond * 5 : 0;
- if (dodelay) LogOperation("No cache records expired for %##s (%s); okay to delay questions a little", q->qname.c, DNSTypeName(q->qtype));
+ if (dodelay) LogInfo("No cache records expired for %##s (%s); okay to delay questions a little", q->qname.c, DNSTypeName(q->qtype));
if (!q->ThisQInterval || q->ThisQInterval > initial)
{
if (rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->DependentOn) rr->resrec.RecordType = kDNSRecordTypeUnique;
rr->ProbeCount = DefaultProbeCountForRecordType(rr->resrec.RecordType);
if (rr->AnnounceCount < announce) rr->AnnounceCount = announce;
- InitializeLastAPTime(m, rr, DefaultAPIntervalForRecordType(rr->resrec.RecordType));
+ InitializeLastAPTime(m, rr);
}
}
- for (rr = m->ResourceRecords; rr; rr=rr->next)
- if (AuthRecord_uDNS(rr))
- {
- LogOperation("mDNS_RegisterInterface: StartGetZoneData for %##s", rr->resrec.name->c);
- if (rr->nta) CancelGetZoneData(m, rr->nta);
- rr->nta = StartGetZoneData(m, rr->resrec.name, ZoneServiceUpdate, RecordRegistrationGotZoneData, rr);
- }
-
- for (s = m->ServiceRegistrations; s; s = s->uDNS_next)
- {
- LogOperation("mDNS_RegisterInterface: StartGetZoneData for %##s", s->RR_SRV.resrec.name->c);
- if (s->nta) CancelGetZoneData(m, s->nta);
- s->nta = StartGetZoneData(m, s->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, s);
- }
+ RestartRecordGetZoneData(m);
mDNS_Unlock(m);
return(mStatus_NoError);
}
-// NOTE: mDNS_DeregisterInterface calls mDNS_Deregister_internal which can call a user callback, which may change
+// Note: mDNS_DeregisterInterface calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
while (*p && *p != set) p=&(*p)->next;
if (!*p) { debugf("mDNS_DeregisterInterface: NetworkInterfaceInfo not found in list"); mDNS_Unlock(m); return; }
+ mDNS_DeactivateNetWake_internal(m, set);
+
// Unlink this record from our list
*p = (*p)->next;
set->next = mDNSNULL;
}
else
{
- NetworkInterfaceInfo *intf;
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->InterfaceID == set->InterfaceID)
- break;
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, set->InterfaceID);
if (intf)
{
- LogOperation("mDNS_DeregisterInterface: Another representative of InterfaceID %p %s (%#a) exists;"
+ LogInfo("mDNS_DeregisterInterface: Another representative of InterfaceID %p %s (%#a) exists;"
" making it active", set->InterfaceID, set->ifname, &set->ip);
+ if (intf->InterfaceActive)
+ LogMsg("mDNS_DeregisterInterface: ERROR intf->InterfaceActive already set for %s (%#a)", set->ifname, &set->ip);
intf->InterfaceActive = mDNStrue;
UpdateInterfaceProtocols(m, intf);
+
+ if (intf->NetWake) mDNS_ActivateNetWake_internal(m, intf);
// See if another representative *of the same type* exists. If not, we mave have gone from
// dual-stack to v6-only (or v4-only) so we need to reconfirm which records are still valid.
DNSQuestion *q;
DNSServer *s;
- LogOperation("mDNS_DeregisterInterface: Last representative of InterfaceID %p %s (%#a) deregistered;"
+ LogInfo("mDNS_DeregisterInterface: Last representative of InterfaceID %p %s (%#a) deregistered;"
" marking questions etc. dormant", set->InterfaceID, set->ifname, &set->ip);
if (flapping)
- LogMsg("Note: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect",
+ LogMsg("Note: DeregisterInterface: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect",
set->ifname, &set->ip);
// 1. Deactivate any questions specific to this interface, and tag appropriate questions
if (result == mStatus_NoError) msg = "Name Registered";
else if (result == mStatus_NameConflict) msg = "Name Conflict";
else if (result == mStatus_MemFree) msg = "Memory Free";
- debugf("ServiceCallback: %##s (%s) %s (%ld)", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), msg, result);
+ debugf("ServiceCallback: %##s (%s) %s (%d)", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype), msg, result);
}
#endif
if (result == mStatus_MemFree)
{
- // If the PTR record or any of the subtype PTR records are still in the process of deregistering,
- // don't pass on the NameConflict/MemFree message until every record is finished cleaning up.
+ // If the SRV/TXT/PTR records, or the _services._dns-sd._udp record, or any of the subtype PTR records,
+ // are still in the process of deregistering, don't pass on the NameConflict/MemFree message until
+ // every record is finished cleaning up.
mDNSu32 i;
+ if (sr->RR_SRV.resrec.RecordType != kDNSRecordTypeUnregistered) return;
+ if (sr->RR_TXT.resrec.RecordType != kDNSRecordTypeUnregistered) return;
if (sr->RR_PTR.resrec.RecordType != kDNSRecordTypeUnregistered) return;
+ if (sr->RR_ADV.resrec.RecordType != kDNSRecordTypeUnregistered) return;
for (i=0; i<sr->NumSubTypes; i++) if (sr->SubTypes[i].resrec.RecordType != kDNSRecordTypeUnregistered) return;
// If this ServiceRecordSet was forcibly deregistered, and now its memory is ready for reuse,
// then we can now report the NameConflict to the client
if (sr->Conflict) result = mStatus_NameConflict;
+
+ if (sr->srs_nta)
+ {
+ LogMsg("ServiceCallback ERROR Got mStatus_MemFree with srs_nta still set for %s", ARDisplayString(m, &sr->RR_SRV));
+ CancelGetZoneData(m, sr->srs_nta);
+ sr->srs_nta = mDNSNULL;
+ }
}
// CAUTION: MUST NOT do anything more with sr after calling sr->Callback(), because the client's callback
sr->ServiceCallback(m, sr, result);
}
+#if !defined(UNICAST_DISABLED) && USE_SEPARATE_UDNS_SERVICE_LIST
mDNSlocal mStatus uDNS_RegisterService(mDNS *const m, ServiceRecordSet *srs)
{
mDNSu32 i;
if (!AuthInfo || !AuthInfo->AutoTunnel) srs->RR_SRV.AutoTarget = Target_AutoHostAndNATMAP;
}
- if (!GetServiceTarget(m, srs))
+ if (!GetServiceTarget(m, &srs->RR_SRV))
{
// defer registration until we've got a target
- LogOperation("uDNS_RegisterService - no target for %##s", srs->RR_SRV.resrec.name->c);
- srs->state = regState_NoTarget;
- srs->nta = mDNSNULL;
+ LogInfo("uDNS_RegisterService - no target for %##s", srs->RR_SRV.resrec.name->c);
+ srs->state = regState_NoTarget;
return mStatus_NoError;
}
ActivateUnicastRegistration(m, &srs->RR_SRV);
srs->state = regState_FetchingZoneData;
- srs->nta = mDNSNULL;
return mStatus_NoError;
}
+#endif
// Note:
// Name is first label of domain name (any dots in the name are actual dots, not label separators)
sr->SRSUpdateServer = zeroAddr;
sr->SRSUpdatePort = zeroIPPort;
mDNSPlatformMemZero(&sr->NATinfo, sizeof(sr->NATinfo));
+ sr->NATinfo.IntPort = port; // Record originally-requested port
sr->ClientCallbackDeferred = 0;
sr->DeferredStatus = 0;
sr->SRVUpdateDeferred = 0;
}
sr->RR_TXT.DependentOn = &sr->RR_SRV;
-#ifndef UNICAST_DISABLED
+ sr->srs_nta = mDNSNULL;
+
+#if !defined(UNICAST_DISABLED) && USE_SEPARATE_UDNS_SERVICE_LIST
// If the client has specified an explicit InterfaceID,
// then we do a multicast registration on that interface, even for unicast domains.
if (!(InterfaceID == mDNSInterface_LocalOnly || IsLocalDomain(&sr->RR_SRV.namestorage)))
return(status);
}
#endif
+
mDNS_Lock(m);
err = mDNS_Register_internal(m, &sr->RR_SRV);
if (!err) err = mDNS_Register_internal(m, &sr->RR_TXT);
(void)m; // Unused
(void)rr; // Unused
(void)result; // Unused
- LogOperation("DummyCallback %d %s", result, ARDisplayString(m, rr));
+ LogInfo("DummyCallback %d %s", result, ARDisplayString(m, rr));
}
mDNSexport mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname)
{
- // NOTE: Don't need to use mDNS_Lock(m) here, because this code is just using public routines
+ // Note: Don't need to use mDNS_Lock(m) here, because this code is just using public routines
// mDNS_RegisterService() and mDNS_AddRecordToService(), which do the right locking internally.
domainlabel name1, name2;
domainname type, domain;
}
if (SameDomainName(&domain, &localdomain))
- LogMsg("%##s service renamed from \"%#s\" to \"%#s\"", type.c, name1.c, newname->c);
- else LogMsg("%##s service (domain %##s) renamed from \"%#s\" to \"%#s\"",type.c, domain.c, name1.c, newname->c);
+ debugf("%##s service renamed from \"%#s\" to \"%#s\"", type.c, name1.c, newname->c);
+ else debugf("%##s service (domain %##s) renamed from \"%#s\" to \"%#s\"",type.c, domain.c, name1.c, newname->c);
err = mDNS_RegisterService(m, sr, newname, &type, &domain,
host, sr->RR_SRV.resrec.rdata->u.srv.port, sr->RR_TXT.resrec.rdata->u.txt.c, sr->RR_TXT.resrec.rdlength,
return(err);
}
-// NOTE: mDNS_DeregisterService calls mDNS_Deregister_internal which can call a user callback,
+// Note: mDNS_DeregisterService calls mDNS_Deregister_internal which can call a user callback,
// which may change the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSexport mStatus mDNS_DeregisterService(mDNS *const m, ServiceRecordSet *sr)
// If port number is zero, that means this was actually registered using mDNS_RegisterNoSuchService()
if (mDNSIPPortIsZero(sr->RR_SRV.resrec.rdata->u.srv.port)) return(mDNS_DeregisterNoSuchService(m, &sr->RR_SRV));
-#ifndef UNICAST_DISABLED
+#if !defined(UNICAST_DISABLED) && USE_SEPARATE_UDNS_SERVICE_LIST
if (!(sr->RR_SRV.resrec.InterfaceID == mDNSInterface_LocalOnly || IsLocalDomain(sr->RR_SRV.resrec.name)))
{
mStatus status;
AuthRecord *r;
DNSQuestion *q;
id = mDNSOpaque16fromIntVal(1 + mDNSRandom(0xFFFE));
- for (r = m->ResourceRecords; r; r=r->next) if (mDNSSameOpaque16(id, r->id )) continue;
+ for (r = m->ResourceRecords; r; r=r->next) if (mDNSSameOpaque16(id, r->updateid )) continue;
for (q = m->Questions; q; q=q->next) if (mDNSSameOpaque16(id, q->TargetQID)) continue;
break;
}
return id;
}
+// ***************************************************************************
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Sleep Proxy Server
+#endif
+
+mDNSlocal void RestartProbing(mDNS *const m, AuthRecord *const rr)
+ {
+ // We reset ProbeCount, so we'll suppress our own answers for a while, to avoid generating ARP conflicts with a waking machine.
+ // If the machine does wake properly then we'll discard our records when we see the first new mDNS probe from that machine.
+ // If it does not wake (perhaps we just picked up a stray delayed packet sent before it went to sleep)
+ // then we'll transition out of probing state and start answering ARPs again.
+ rr->resrec.RecordType = kDNSRecordTypeUnique;
+ rr->ProbeCount = DefaultProbeCountForTypeUnique;
+ rr->AnnounceCount = InitialAnnounceCount;
+ InitializeLastAPTime(m, rr);
+ }
+
+mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, const mDNSu8 *const end, const mDNSInterfaceID InterfaceID)
+ {
+ static const mDNSOpaque16 Ethertype_IP = { { 0x08, 0x00 } };
+ static const mDNSOpaque32 ARP_EthIP_h0 = { { 0x08, 0x06, 0x00, 0x01 } }; // Ethertype (ARP = 0x0806), Hardware address space (Ethernet = 1)
+ static const mDNSOpaque32 ARP_EthIP_h1 = { { 0x08, 0x00, 0x06, 0x04 } }; // Protocol address space (IP = 0x0800), hlen, plen
+ static const mDNSOpaque16 ARP_op_request = { { 0, 1 } };
+ const EthernetHeader *const eth = (const EthernetHeader *)p;
+ const ARP_EthIP *const arp = (const ARP_EthIP *)(eth+1);
+ const IPv4Header *const v4 = (const IPv4Header *)(eth+1);
+ const IPv6Header *const v6 = (const IPv6Header *)(eth+1);
+ if (end >= p+42 && *(mDNSu32*)(p+12) == ARP_EthIP_h0.NotAnInteger && *(mDNSu32*)(p+16) == ARP_EthIP_h1.NotAnInteger)
+ {
+ AuthRecord *rr;
+ NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
+ if (!intf) return;
+
+ debugf("Got ARP from %.4a/%.6a for %.4a", &arp->spa, &arp->sha, &arp->tpa);
+
+ mDNS_Lock(m);
+
+ // Pass 1:
+ // Process ARP Requests and Probes (but not Announcements), and generate an ARP Reply if necessary.
+ // We also process and answer ARPs from our own kernel (no special treatment for localhost).
+ // We ignore ARP Announcements here -- Announcements are not questions, they're assertions, so we don't need to answer them.
+ // The only time we might need to respond to an ARP Announcement is if it's a conflict -- and we check for that in Pass 2 below.
+ if (mDNSSameOpaque16(arp->op, ARP_op_request) && !mDNSSameIPv4Address(arp->spa, arp->tpa))
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->AddressProxy.ip.v4, arp->tpa))
+ {
+ static const char msg1[] = "ARP Req from owner -- re-probing";
+ static const char msg2[] = "Ignoring ARP Request from ";
+ static const char msg3[] = "Creating Local ARP Cache entry ";
+ static const char msg4[] = "Answering ARP Request from ";
+ const char *const msg = mDNSSameEthAddress(&arp->sha, &rr->WakeUp.IMAC) ? msg1 :
+ (rr->AnnounceCount == InitialAnnounceCount) ? msg2 :
+ mDNSSameEthAddress(&arp->sha, &intf->MAC) ? msg3 : msg4;
+ LogSPS("%-7s %s %.6a %.4a for %.4a -- H-MAC %.6a I-MAC %.6a %s",
+ InterfaceNameForID(m, InterfaceID), msg, &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+ if (msg == msg1) RestartProbing(m, rr);
+ else if (msg == msg3) mDNSPlatformSetLocalARP(&arp->tpa, &rr->WakeUp.IMAC, InterfaceID);
+ else if (msg == msg4) SendARP(m, 2, rr, arp->tpa.b, arp->sha.b, arp->spa.b, arp->sha.b);
+ }
+
+ // Pass 2:
+ // For all types of ARP packet we check the Sender IP address to make sure it doesn't conflict with any AddressProxy record we're holding.
+ // (Strictly speaking we're only checking Announcement/Request/Reply packets, since ARP Probes have zero Sender IP address,
+ // so by definition (and by design) they can never conflict with any real (i.e. non-zero) IP address).
+ // We ignore ARPs we sent ourselves (Sender MAC address is our MAC address) because our own proxy ARPs do not constitute a conflict that we need to handle.
+ // If we see an apparently conflicting ARP, we check the sender hardware address:
+ // If the sender hardware address is the original owner this is benign, so we just suppress our own proxy answering for a while longer.
+ // If the sender hardware address is *not* the original owner, then this is a conflict, and we need to wake the sleeping machine to handle it.
+ if (mDNSSameEthAddress(&arp->sha, &intf->MAC))
+ debugf("ARP from self for %.4a", &arp->tpa);
+ else
+ {
+ if (!mDNSSameIPv4Address(arp->spa, zerov4Addr))
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->AddressProxy.ip.v4, arp->spa))
+ {
+ RestartProbing(m, rr);
+ if (mDNSSameEthAddress(&arp->sha, &rr->WakeUp.IMAC))
+ LogSPS("%-7s ARP %s from owner %.6a %.4a for %-15.4a -- re-starting probing for %s",
+ InterfaceNameForID(m, InterfaceID),
+ mDNSSameIPv4Address(arp->spa, arp->tpa) ? "Announcement" : mDNSSameOpaque16(arp->op, ARP_op_request) ? "Request " : "Response ",
+ &arp->sha, &arp->spa, &arp->tpa, ARDisplayString(m, rr));
+ else
+ {
+ LogMsg("%-7s Conflicting ARP from %.6a %.4a for %.4a -- waking H-MAC %.6a I-MAC %.6a %s",
+ InterfaceNameForID(m, InterfaceID), &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+ SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
+ }
+ }
+ }
+
+ mDNS_Unlock(m);
+ }
+ else if (end >= p+34 && mDNSSameOpaque16(eth->ethertype, Ethertype_IP) && (v4->flagsfrags.b[0] & 0x1F) == 0 && v4->flagsfrags.b[1] == 0)
+ {
+ const mDNSu8 *const trans = p + 14 + (v4->vlen & 0xF) * 4;
+ const mDNSu8 *const required = trans + (v4->protocol == 1 ? 4 : v4->protocol == 6 ? 20 : v4->protocol == 17 ? 8 : 0);
+ debugf("Got IPv4 from %.4a to %.4a", &v4->src, &v4->dst);
+ if (end >= required)
+ {
+ #define SSH_AsNumber 22
+ #define ARD_AsNumber 3283
+ #define IPSEC_AsNumber 4500
+ static const mDNSIPPort SSH = { { SSH_AsNumber >> 8, SSH_AsNumber & 0xFF } };
+ static const mDNSIPPort ARD = { { ARD_AsNumber >> 8, ARD_AsNumber & 0xFF } };
+ static const mDNSIPPort IPSEC = { { IPSEC_AsNumber >> 8, IPSEC_AsNumber & 0xFF } };
+
+ mDNSBool wake = mDNSfalse;
+ mDNSIPPort port = zeroIPPort;
+
+ switch (v4->protocol)
+ {
+ #define XX wake ? "Received" : "Ignoring", end-p
+ case 1: LogSPS("%s %d-byte ICMP from %.4a to %.4a", XX, &v4->src, &v4->dst);
+ break;
+
+ case 6: {
+ const TCPHeader *const tcp = (const TCPHeader *)trans;
+ port = tcp->dst;
+
+ // Plan to wake if
+ // (a) RST is not set, AND
+ // (b) packet is SYN, SYN+FIN, or plain data packet (no SYN or FIN). We won't wake for FIN alone.
+ wake = (!(tcp->flags & 4) && (tcp->flags & 3) != 1);
+
+ // For now, to reduce spurious wakeups, we wake only for TCP SYN,
+ // except for ssh connections, where we'll wake for plain data packets too
+ if (!mDNSSameIPPort(port, SSH) && !(tcp->flags & 2)) wake = mDNSfalse;
+
+ LogSPS("%s %d-byte TCP from %.4a:%d to %.4a:%d%s%s%s", XX,
+ &v4->src, mDNSVal16(tcp->src), &v4->dst, mDNSVal16(port),
+ (tcp->flags & 2) ? " SYN" : "",
+ (tcp->flags & 1) ? " FIN" : "",
+ (tcp->flags & 4) ? " RST" : "");
+ }
+ break;
+
+ case 17: {
+ const UDPHeader *const udp = (const UDPHeader *)trans;
+ mDNSu16 len = (mDNSu16)((mDNSu16)trans[4] << 8 | trans[5]);
+ port = udp->dst;
+ wake = mDNStrue;
+
+ // For Back to My Mac UDP port 4500 (IPSEC) packets, we specially ignore NAT keepalive packets
+ if (mDNSSameIPPort(port, IPSEC)) wake = (len != 9 || end < trans + 9 || trans[8] != 0xFF);
+
+ // For now, because we haven't yet worked out a clean elegant way to do this, we just special-case the
+ // Apple Remote Desktop port number -- we ignore all packets to UDP 3283 (the "Net Assistant" port),
+ // except for Apple Remote Desktop's explicit manual wakeup packet, which looks like this:
+ // UDP header (8 bytes) 13 88 00 6a 41 4e 41 20 (8 bytes) ffffffffffff (6 bytes) 16xMAC (96 bytes) = 118 bytes total
+ if (mDNSSameIPPort(port, ARD)) wake = (len >= 118 && end >= trans+10 && trans[8] == 0x13 && trans[9] == 0x88);
+
+ LogSPS("%s %d-byte UDP from %.4a:%d to %.4a:%d", XX, &v4->src, mDNSVal16(udp->src), &v4->dst, mDNSVal16(port));
+ }
+ break;
+
+ default: LogSPS("%s %d-byte IP packet unknown protocol %d from %.4a to %.4a", XX, v4->protocol, &v4->src, &v4->dst);
+ break;
+ }
+
+ if (wake)
+ {
+ AuthRecord *rr, *r2;
+
+ mDNS_Lock(m);
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ 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";
+ 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))
+ break;
+ if (!r2 && mDNSSameIPPort(port, IPSEC)) r2 = rr; // So that we wake for BTMM IPSEC packets, even without a matching SRV record
+ if (r2)
+ {
+ rr->AnnounceCount = 0;
+ LogMsg("Waking host at %s %.4a H-MAC %.6a I-MAC %.6a for %s",
+ InterfaceNameForID(m, rr->resrec.InterfaceID), &v4->dst, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, r2));
+ SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
+ }
+ else
+ LogSPS("Sleeping host at %s %.4a %.6a has no service on %#s %d",
+ InterfaceNameForID(m, rr->resrec.InterfaceID), &v4->dst, &rr->WakeUp.HMAC, tp, mDNSVal16(port));
+ }
+ mDNS_Unlock(m);
+ }
+ }
+ }
+ else if (end >= p+34 && mDNSSameOpaque16(eth->ethertype, Ethertype_IP) && (v4->flagsfrags.b[0] & 0x1F) == 0 && v4->flagsfrags.b[1] == 0)
+ {
+ debugf("Got IPv6 from %.16a to %.16a", &v4->src, &v6->dst);
+ (void)v6;
+ }
+ }
+
+mDNSlocal void ConstructSleepProxyServerName(mDNS *const m, domainlabel *name)
+ {
+ name->c[0] = mDNS_snprintf((char*)name->c+1, 62, "%d-%d-%d-%d %#s",
+ m->SPSType, m->SPSPortability, m->SPSMarginalPower, m->SPSTotalPower, &m->nicelabel);
+ }
+
+mDNSlocal void SleepProxyServerCallback(mDNS *const m, ServiceRecordSet *const srs, mStatus result)
+ {
+ if (result == mStatus_NameConflict)
+ mDNS_RenameAndReregisterService(m, srs, mDNSNULL);
+ else if (result == mStatus_MemFree)
+ {
+ if (m->SleepState)
+ m->SPSState = 3;
+ else
+ {
+ m->SPSState = (m->SPSSocket != mDNSNULL);
+ if (m->SPSState)
+ {
+ domainlabel name;
+ ConstructSleepProxyServerName(m, &name);
+ mDNS_RegisterService(m, srs,
+ &name, &SleepProxyServiceType, &localdomain,
+ mDNSNULL, m->SPSSocket->port, // Host, port
+ (mDNSu8 *)"", 1, // TXT data, length
+ mDNSNULL, 0, // Subtypes (none)
+ mDNSInterface_Any, // Interface ID
+ SleepProxyServerCallback, mDNSNULL); // Callback and context
+ }
+ LogSPS("Sleep Proxy Server %#s %s", srs->RR_SRV.resrec.name->c, m->SPSState ? "started" : "stopped");
+ }
+ }
+ }
+
+mDNSexport void mDNSCoreBeSleepProxyServer(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower)
+ {
+ // If turning off SPS, close our socket
+ // (Do this first, BEFORE calling mDNS_DeregisterService below)
+ if (!sps && m->SPSSocket) { mDNSPlatformUDPClose(m->SPSSocket); m->SPSSocket = mDNSNULL; }
+
+ // If turning off, or changing type, deregister old name
+ if (m->SPSState == 1 && sps != m->SPSType)
+ { m->SPSState = 2; mDNS_DeregisterService(m, &m->SPSRecords); }
+
+ // Record our new SPS parameters
+ m->SPSType = sps;
+ m->SPSPortability = port;
+ m->SPSMarginalPower = marginalpower;
+ m->SPSTotalPower = totpower;
+
+ // If turning on, open socket and advertise service
+ if (sps)
+ {
+ if (!m->SPSSocket)
+ {
+ m->SPSSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ if (!m->SPSSocket) { LogMsg("mDNSCoreBeSleepProxyServer: Failed to allocate SPSSocket"); return; }
+ }
+ if (m->SPSState == 0) SleepProxyServerCallback(m, &m->SPSRecords, mStatus_MemFree);
+ }
+ }
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
if (!rrcachestorage) rrcachesize = 0;
- m->p = p;
- m->KnownBugs = 0;
- m->CanReceiveUnicastOn5353 = mDNSfalse; // Assume we can't receive unicasts on 5353, unless platform layer tells us otherwise
- m->AdvertiseLocalAddresses = AdvertiseLocalAddresses;
- m->mDNSPlatformStatus = mStatus_Waiting;
- m->UnicastPort4 = zeroIPPort;
- m->UnicastPort6 = zeroIPPort;
- m->MainCallback = Callback;
- m->MainContext = Context;
- m->rec.r.resrec.RecordType = 0;
+ m->p = p;
+ m->KnownBugs = 0;
+ m->CanReceiveUnicastOn5353 = mDNSfalse; // Assume we can't receive unicasts on 5353, unless platform layer tells us otherwise
+ m->AdvertiseLocalAddresses = AdvertiseLocalAddresses;
+ m->DivertMulticastAdvertisements = mDNSfalse;
+ m->mDNSPlatformStatus = mStatus_Waiting;
+ m->UnicastPort4 = zeroIPPort;
+ m->UnicastPort6 = zeroIPPort;
+ m->PrimaryMAC = zeroEthAddr;
+ m->MainCallback = Callback;
+ m->MainContext = Context;
+ m->rec.r.resrec.RecordType = 0;
// For debugging: To catch and report locking failures
m->mDNS_busy = 0;
m->NextScheduledProbe = timenow + 0x78000000;
m->NextScheduledResponse = timenow + 0x78000000;
m->NextScheduledNATOp = timenow + 0x78000000;
+ m->NextScheduledSPS = timenow + 0x78000000;
m->RandomQueryDelay = 0;
m->RandomReconfirmDelay = 0;
m->PktNum = 0;
- m->SendDeregistrations = mDNSfalse;
- m->SendImmediateAnswers = mDNSfalse;
- m->SleepState = mDNSfalse;
+ m->SleepState = SleepState_Awake;
+ m->SleepSeqNum = 0;
+ m->SystemWakeOnLANEnabled = mDNSfalse;
+ m->DelaySleep = 0;
+ m->SleepLimit = 0;
// These fields only required for mDNS Searcher...
m->Questions = mDNSNULL;
m->ExternalAddress = zerov4Addr;
m->NATMcastRecvskt = mDNSNULL;
- m->NATMcastRecvsk2 = mDNSNULL;
m->LastNATupseconds = 0;
m->LastNATReplyLocalTime = timenow;
+ m->LastNATMapResultCode = NATErr_None;
m->UPnPInterfaceID = 0;
m->SSDPSocket = mDNSNULL;
m->UPnPSOAPURL = mDNSNULL;
m->UPnPRouterAddressString = mDNSNULL;
m->UPnPSOAPAddressString = mDNSNULL;
+ m->SPSType = 0;
+ m->SPSPortability = 0;
+ m->SPSMarginalPower = 0;
+ m->SPSTotalPower = 0;
+ m->SPSState = 0;
+ m->SPSProxyListChanged = mDNSNULL;
+ m->SPSSocket = mDNSNULL;
+ m->SPSBrowseCallback = mDNSNULL;
+ m->ProxyRecords = 0;
+
#endif
#if APPLE_OSX_mDNSResponder
return(result);
}
+mDNSexport void mDNS_ConfigChanged(mDNS *const m)
+ {
+ if (m->SPSState == 1)
+ {
+ domainlabel name, newname;
+ domainname type, domain;
+ DeconstructServiceName(m->SPSRecords.RR_SRV.resrec.name, &name, &type, &domain);
+ ConstructSleepProxyServerName(m, &newname);
+ if (!SameDomainLabelCS(name.c, newname.c))
+ {
+ LogSPS("Renaming SPS from “%#s” to “%#s”", name.c, newname.c);
+ // When SleepProxyServerCallback gets the mStatus_MemFree message,
+ // it will reregister the service under the new name
+ m->SPSState = 2;
+ mDNS_DeregisterService(m, &m->SPSRecords);
+ }
+ }
+
+ if (m->MainCallback)
+ m->MainCallback(m, mStatus_ConfigChanged);
+ }
+
mDNSlocal void DynDNSHostNameCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
{
(void)m; // unused
mDNSPlatformDynDNSHostNameStatusChanged(rr->resrec.name, result);
}
+mDNSlocal void PurgeOrReconfirmCacheRecord(mDNS *const m, CacheRecord *cr, const DNSServer * const ptr, mDNSBool lameduck)
+ {
+ mDNSBool purge = cr->resrec.RecordType == kDNSRecordTypePacketNegative ||
+ cr->resrec.rrtype == kDNSType_A ||
+ cr->resrec.rrtype == kDNSType_AAAA ||
+ cr->resrec.rrtype == kDNSType_SRV;
+
+ (void) lameduck;
+ (void) ptr;
+ debugf("uDNS_SetupDNSConfig: %s cache record due to %s server %p %#a:%d (%##s): %s", purge ? "purging" : "reconfirming", lameduck ? "lame duck" : "new", ptr, &ptr->addr, mDNSVal16(ptr->port), ptr->domain.c, CRDisplayString(m, cr));
+
+ if (purge) mDNS_PurgeCacheResourceRecord(m, cr);
+ else mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
+ }
+
mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
{
mDNSu32 slot;
DNSServer *ptr, **p = &m->DNSServers;
const DNSServer *oldServers = m->DNSServers;
DNSQuestion *q;
+
+ debugf("uDNS_SetupDNSConfig: entry");
if (m->RegisterSearchDomains) uDNS_RegisterSearchDomains(m);
if (t != s)
{
// If DNS Server for this question has changed, reactivate it
- LogOperation("Updating DNS Server from %p %#a:%d (%##s) to %p %#a:%d (%##s) for %##s (%s)",
+ debugf("uDNS_SetupDNSConfig: Updating DNS Server from %p %#a:%d (%##s) to %p %#a:%d (%##s) for %##s (%s)",
t, t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zeroIPPort), t ? t->domain.c : (mDNSu8*)"",
s, s ? &s->addr : mDNSNULL, mDNSVal16(s ? s->port : zeroIPPort), s ? s->domain.c : (mDNSu8*)"",
q->qname.c, DNSTypeName(q->qtype));
{
ptr = GetServerForName(m, cr->resrec.name);
if (ptr && (ptr->flags & DNSServer_FlagNew) && !cr->resrec.InterfaceID)
- {
- if (cr->resrec.RecordType == kDNSRecordTypePacketNegative)
- mDNS_PurgeCacheResourceRecord(m, cr);
- else
- mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
- }
+ PurgeOrReconfirmCacheRecord(m, cr, ptr, mDNSfalse);
}
while (*p)
ptr->flags &= ~DNSServer_FlagDelete; // Clear del so GetServerForName will (temporarily) find this server again before it's finally deleted
FORALL_CACHERECORDS(slot, cg, cr)
if (!cr->resrec.InterfaceID && GetServerForName(m, cr->resrec.name) == ptr)
- mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
+ PurgeOrReconfirmCacheRecord(m, cr, ptr, mDNStrue);
*p = (*p)->next;
+ debugf("uDNS_SetupDNSConfig: Deleting server %p %#a:%d (%##s)", ptr, &ptr->addr, mDNSVal16(ptr->port), ptr->domain.c);
mDNSPlatformMemFree(ptr);
}
else
{
int count = 0;
FORALL_CACHERECORDS(slot, cg, cr) if (!cr->resrec.InterfaceID) { mDNS_PurgeCacheResourceRecord(m, cr); count++; }
- LogOperation("uDNS_SetupDNSConfig: %s available; purged %d unicast DNS records from cache",
+ LogInfo("uDNS_SetupDNSConfig: %s available; purged %d unicast DNS records from cache",
m->DNSServers ? "DNS server became" : "No DNS servers", count);
}
+ // If we no longer have any DNS servers, we need to force anything that needs to get zone data
+ // to get that information again (which will fail, since we have no more DNS servers)
+ if ((m->DNSServers == mDNSNULL) && (oldServers != mDNSNULL)) RestartRecordGetZoneData(m);
+
// Did our FQDN change?
if (!SameDomainName(&fqdn, &m->FQDN))
{
extern ServiceRecordSet *CurrentServiceRecordSet;
+mDNSlocal void DeregLoop(mDNS *const m, AuthRecord *const start)
+ {
+ m->CurrentRecord = start;
+ while (m->CurrentRecord)
+ {
+ AuthRecord *rr = m->CurrentRecord;
+ if (rr->resrec.RecordType != kDNSRecordTypeDeregistering)
+ {
+ LogInfo("DeregLoop: Deregistering %p %02X %s", rr, rr->resrec.RecordType, ARDisplayString(m, rr));
+ mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
+ }
+ // Note: We mustn't advance m->CurrentRecord until *after* mDNS_Deregister_internal, because
+ // the list may have been changed in that call.
+ if (m->CurrentRecord == rr) // If m->CurrentRecord was not advanced for us, do it now
+ m->CurrentRecord = rr->next;
+ }
+ }
+
mDNSexport void mDNS_StartExit(mDNS *const m)
{
NetworkInterfaceInfo *intf;
m->ShutdownTime = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 5);
+ mDNS_DropLockBeforeCallback(); // mDNSCoreBeSleepProxyServer expects to be called without the lock held, so we emulate that here
+ mDNSCoreBeSleepProxyServer(m, 0, 0, 0, 0);
+ mDNS_ReclaimLockAfterCallback();
+
#ifndef UNICAST_DISABLED
+ {
+ SearchListElem *s;
SuspendLLQs(m);
// Don't need to do SleepRecordRegistrations() or SleepServiceRegistrations() here,
// because we deregister all records and services later in this routine
while (m->Hostnames) mDNS_RemoveDynDNSHostName(m, &m->Hostnames->fqdn);
+
+ // For each member of our SearchList, deregister any records it may have created, and cut them from the list.
+ // Otherwise they'll be forcibly deregistered for us (without being cut them from the appropriate list)
+ // and we may crash because the list still contains dangling pointers.
+ for (s = SearchList; s; s = s->next)
+ while (s->AuthRecs)
+ {
+ ARListElem *dereg = s->AuthRecs;
+ s->AuthRecs = s->AuthRecs->next;
+ mDNS_Deregister_internal(m, &dereg->ar, mDNS_Dereg_normal); // Memory will be freed in the FreeARElemCallback
+ }
+ }
#endif
for (intf = m->HostInterfaces; intf; intf = intf->next)
// Make sure there are nothing but deregistering records remaining in the list
if (m->CurrentRecord)
- LogMsg("mDNS_StartExit ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
-
- // First we deregister any non-shared records. In particular, we want to make sure we deregister
- // any extra records added to a Service Record Set first, before we deregister its PTR record,
- // because the freeing of the memory is triggered off the mStatus_MemFree for the PTR record.
- m->CurrentRecord = m->ResourceRecords;
- while (m->CurrentRecord)
- {
- rr = m->CurrentRecord;
- if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
- mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
- // Note: We mustn't advance m->CurrentRecord until *after* mDNS_Deregister_internal, because when
- // we have records on the DuplicateRecords list, the duplicate gets inserted in place of the record
- // we're removing, and if we've already advanced to rr->next we'll miss the newly activated duplicate
- if (m->CurrentRecord == rr) // If m->CurrentRecord was not auto-advanced, do it ourselves now
- m->CurrentRecord = rr->next;
- }
-
- // Now deregister any remaining records we didn't get the first time through
- m->CurrentRecord = m->ResourceRecords;
- while (m->CurrentRecord)
+ LogMsg("mDNS_StartExit: ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
+
+ // We're in the process of shutting down, so queries, etc. are no longer available.
+ // Consequently, determining certain information, e.g. the uDNS update server's IP
+ // address, will not be possible. The records on the main list are more likely to
+ // already contain such information, so we deregister the duplicate records first.
+ LogInfo("mDNS_StartExit: Deregistering duplicate resource records");
+ DeregLoop(m, m->DuplicateRecords);
+ LogInfo("mDNS_StartExit: Deregistering resource records");
+ DeregLoop(m, m->ResourceRecords);
+
+ // If we scheduled a response to send goodbye packets, we set NextScheduledResponse to now. Normally when deregistering records,
+ // we allow up to 100ms delay (to help improve record grouping) but when shutting down we don't want any such delay.
+ if (m->NextScheduledResponse - m->timenow < mDNSPlatformOneSecond)
{
- rr = m->CurrentRecord;
- if (rr->resrec.RecordType != kDNSRecordTypeDeregistering)
- {
- //LogOperation("mDNS_StartExit: Deregistering %s", ARDisplayString(m, rr));
- mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal);
- }
- // Note: We mustn't advance m->CurrentRecord until *after* mDNS_Deregister_internal, because when
- // we have records on the DuplicateRecords list, the duplicate gets inserted in place of the record
- // we're removing, and if we've already advanced to rr->next we'll miss the newly activated duplicate
- if (m->CurrentRecord == rr) // If m->CurrentRecord was not auto-advanced, do it ourselves now
- m->CurrentRecord = rr->next;
+ m->NextScheduledResponse = m->timenow;
+ m->SuppressSending = 0;
}
+#if !defined(UNICAST_DISABLED) && USE_SEPARATE_UDNS_SERVICE_LIST
CurrentServiceRecordSet = m->ServiceRegistrations;
while (CurrentServiceRecordSet)
{
ServiceRecordSet *srs = CurrentServiceRecordSet;
- LogOperation("mDNS_StartExit: Deregistering %##s", srs->RR_SRV.resrec.name->c);
+ LogInfo("mDNS_StartExit: Deregistering uDNS service %##s", srs->RR_SRV.resrec.name->c);
uDNS_DeregisterService(m, srs);
if (CurrentServiceRecordSet == srs)
CurrentServiceRecordSet = srs->uDNS_next;
}
+#endif
+
+ if (m->ResourceRecords) LogInfo("mDNS_StartExit: Sending final record deregistrations");
+ else LogInfo("mDNS_StartExit: No deregistering records remain");
- if (m->ResourceRecords) LogOperation("mDNS_StartExit: Sending final record deregistrations");
- else LogOperation("mDNS_StartExit: No deregistering records remain");
+ if (m->ServiceRegistrations) LogInfo("mDNS_StartExit: Sending final uDNS service deregistrations");
+ else LogInfo("mDNS_StartExit: No deregistering uDNS services remain");
- if (m->ServiceRegistrations) LogOperation("mDNS_StartExit: Sending final service deregistrations");
- else LogOperation("mDNS_StartExit: No deregistering services remain");
+ for (rr = m->DuplicateRecords; rr; rr = rr->next)
+ LogMsg("mDNS_StartExit: Should not still have Duplicate Records remaining: %02X %s", rr->resrec.RecordType, ARDisplayString(m, rr));
// If any deregistering records remain, send their deregistration announcements before we exit
if (m->mDNSPlatformStatus != mStatus_NoError) DiscardDeregistrations(m);
mDNS_Unlock(m);
- LogOperation("mDNS_StartExit: done");
+ LogInfo("mDNS_StartExit: done");
}
mDNSexport void mDNS_FinalExit(mDNS *const m)
AuthRecord *rr;
ServiceRecordSet *srs;
- LogOperation("mDNS_FinalExit: mDNSPlatformClose");
+ LogInfo("mDNS_FinalExit: mDNSPlatformClose");
mDNSPlatformClose(m);
rrcache_totalused = m->rrcache_totalused;
ReleaseCacheGroup(m, &m->rrcache_hash[slot]);
}
}
- debugf("mDNS_StartExit: RR Cache was using %ld records, %lu active", rrcache_totalused, rrcache_active);
+ debugf("mDNS_FinalExit: RR Cache was using %ld records, %lu active", rrcache_totalused, rrcache_active);
if (rrcache_active != m->rrcache_active)
LogMsg("*** ERROR *** rrcache_active %lu != m->rrcache_active %lu", rrcache_active, m->rrcache_active);
for (rr = m->ResourceRecords; rr; rr = rr->next)
- LogMsg("mDNS_FinalExit failed to send goodbye for: %02X %s", rr->resrec.RecordType, ARDisplayString(m, rr));
+ LogMsg("mDNS_FinalExit failed to send goodbye for: %p %02X %s", rr, rr->resrec.RecordType, ARDisplayString(m, rr));
for (srs = m->ServiceRegistrations; srs; srs = srs->uDNS_next)
- LogMsg("mDNS_FinalExit failed to deregister service: %##s", srs->RR_SRV.resrec.name->c);
+ LogMsg("mDNS_FinalExit failed to deregister service: %p %##s", srs, srs->RR_SRV.resrec.name->c);
- LogOperation("mDNS_FinalExit: done");
+ LogInfo("mDNS_FinalExit: done");
}
Change History (most recent first):
$Log: mDNSDebug.h,v $
+Revision 1.51 2009/06/25 23:36:59 cheshire
+To facilitate testing, added command-line switch "-OfferSleepProxyService"
+to re-enable the previously-supported mode of operation where we offer
+sleep proxy service on desktop Macs that are set to never sleep.
+
+Revision 1.50 2009/05/19 23:34:06 cheshire
+Updated comment to show correct metric of 80 for a low-priority sleep proxy
+
+Revision 1.49 2009/04/24 23:32:28 cheshire
+To facilitate testing, put back code to be a sleep proxy when set to never sleep, compiled out by compile-time switch
+
+Revision 1.48 2009/04/11 01:43:27 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.47 2009/04/11 00:19:41 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.46 2009/02/13 06:36:50 cheshire
+Update LogSPS definition
+
+Revision 1.45 2009/02/13 06:03:12 cheshire
+Added LogInfo for informational message logging
+
+Revision 1.44 2009/02/12 20:57:25 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.43 2008/12/10 02:27:14 cheshire
+Commented out definitions of LogClientOperations, LogTimeStamps, ForceAlerts and MACOSX_MDNS_MALLOC_DEBUGGING
+to allow overriding values to be easily defined in a Makefile or similar build environment
+
+Revision 1.42 2008/11/02 21:22:05 cheshire
+Changed mallocL size parameter back to "unsigned int"
+
+Revision 1.41 2008/11/02 21:14:58 cheshire
+Fixes to make mallocL/freeL debugging checks work on 64-bit
+
+Revision 1.40 2008/10/24 20:53:37 cheshire
+For now, define USE_SEPARATE_UDNS_SERVICE_LIST, so that we use the old service list code for this submission
+
Revision 1.39 2008/02/26 21:17:11 cheshire
Grouped all user settings together near the start of the file; added LogTimeStamps option
typedef enum
{
- MDNS_LOG_NONE,
-// MDNS_LOG_ERROR,
-// MDNS_LOG_WARN,
-// MDNS_LOG_INFO,
-// MDNS_LOG_DEBUG,
- MDNS_LOG_VERBOSE_DEBUG
- } LogLevel_t;
-
-#define MDNS_LOG_INITIAL_LEVEL MDNS_LOG_NONE
+ MDNS_LOG_MSG,
+ MDNS_LOG_OPERATION,
+ MDNS_LOG_SPS,
+ MDNS_LOG_INFO,
+ MDNS_LOG_DEBUG,
+ } mDNSLogLevel_t;
// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
// Set this symbol to 1 to do extra debug checks on malloc() and free()
// Set this symbol to 2 to write a log message for every malloc() and free()
-#define MACOSX_MDNS_MALLOC_DEBUGGING 0
+//#define MACOSX_MDNS_MALLOC_DEBUGGING 1
+
+//#define ForceAlerts 1
+//#define LogTimeStamps 1
-#define LogAllOperations 0
-#define LogTimeStamps 0
-#define ForceAlerts 0
+#define USE_SEPARATE_UDNS_SERVICE_LIST 1
// Developer-settings section ends here
#define IS_A_PRINTF_STYLE_FUNCTION(F,A)
#endif
-#ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
#if (defined(__GNUC__))
#if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
- #define MDNS_C99_VA_ARGS 1
- #define MDNS_GNU_VA_ARGS 0
+ #define MDNS_C99_VA_ARGS 1
+ #define MDNS_GNU_VA_ARGS 0
#else
- #define MDNS_C99_VA_ARGS 0
- #define MDNS_GNU_VA_ARGS 1
+ #define MDNS_C99_VA_ARGS 0
+ #define MDNS_GNU_VA_ARGS 1
#endif
- #define MDNS_HAS_VA_ARG_MACROS 1
+ #define MDNS_HAS_VA_ARG_MACROS 1
#elif (_MSC_VER >= 1400) // Visual Studio 2005 and later
- #define MDNS_C99_VA_ARGS 1
- #define MDNS_GNU_VA_ARGS 0
- #define MDNS_HAS_VA_ARG_MACROS 1
+ #define MDNS_C99_VA_ARGS 1
+ #define MDNS_GNU_VA_ARGS 0
+ #define MDNS_HAS_VA_ARG_MACROS 1
#elif (defined(__MWERKS__))
- #define MDNS_C99_VA_ARGS 1
- #define MDNS_GNU_VA_ARGS 0
- #define MDNS_HAS_VA_ARG_MACROS 1
+ #define MDNS_C99_VA_ARGS 1
+ #define MDNS_GNU_VA_ARGS 0
+ #define MDNS_HAS_VA_ARG_MACROS 1
#else
- #define MDNS_C99_VA_ARGS 0
- #define MDNS_GNU_VA_ARGS 0
- #define MDNS_HAS_VA_ARG_MACROS 0
+ #define MDNS_C99_VA_ARGS 0
+ #define MDNS_GNU_VA_ARGS 0
+ #define MDNS_HAS_VA_ARG_MACROS 0
#endif
-#if MDNS_DEBUGMSGS
-#define debugf debugf_
-extern void debugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
-#else // If debug breaks are off, use a preprocessor trick to optimize those calls out of the code
+#if (MDNS_HAS_VA_ARG_MACROS)
#if (MDNS_C99_VA_ARGS)
- #define debugf( ... ) ((void)0)
+ #define debug_noop( ... ) ((void)0)
+ #define LogMsg( ... ) LogMsgWithLevel(MDNS_LOG_MSG, __VA_ARGS__)
+ #define LogOperation( ... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, __VA_ARGS__); } while (0)
+ #define LogSPS( ... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, __VA_ARGS__); } while (0)
+ #define LogInfo( ... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, __VA_ARGS__); } while (0)
#elif (MDNS_GNU_VA_ARGS)
- #define debugf( ARGS... ) ((void)0)
+ #define debug_noop( ARGS... ) ((void)0)
+ #define LogMsg( ARGS... ) LogMsgWithLevel(MDNS_LOG_MSG, ARGS)
+ #define LogOperation( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, ARGS); } while (0)
+ #define LogSPS( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, ARGS); } while (0)
+ #define LogInfo( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, ARGS); } while (0)
#else
- #define debugf 1 ? ((void)0) : (void)
+ #error Unknown variadic macros
#endif
+#else
+ // If your platform does not support variadic macros, you need to define the following variadic functions.
+ // See mDNSShared/mDNSDebug.c for sample implementation
+ extern void debug_noop(const char *format, ...);
+ #define LogMsg LogMsg_
+ #define LogOperation mDNS_LoggingEnabled == 0 ? ((void)0) : LogOperation_
+ #define LogSPS mDNS_LoggingEnabled == 0 ? ((void)0) : LogSPS_
+ #define LogInfo mDNS_LoggingEnabled == 0 ? ((void)0) : LogInfo_
+ extern void LogMsg_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
+ extern void LogOperation_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
+ extern void LogSPS_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
+ extern void LogInfo_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
+#endif
+
+#if MDNS_DEBUGMSGS
+#define debugf debugf_
+extern void debugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
+#else
+#define debugf debug_noop
#endif
#if MDNS_DEBUGMSGS > 1
#define verbosedebugf verbosedebugf_
extern void verbosedebugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
#else
- #if (MDNS_C99_VA_ARGS)
- #define verbosedebugf( ... ) ((void)0)
- #elif (MDNS_GNU_VA_ARGS)
- #define verbosedebugf( ARGS... ) ((void)0)
- #else
- #define verbosedebugf 1 ? ((void)0) : (void)
- #endif
+#define verbosedebugf debug_noop
#endif
-// LogMsg is used even in shipping code, to write truly serious error messages to syslog (or equivalent)
-extern LogLevel_t mDNS_LogLevel;
+extern int mDNS_LoggingEnabled;
+extern int mDNS_PacketLoggingEnabled;
extern int mDNS_DebugMode; // If non-zero, LogMsg() writes to stderr instead of syslog
-extern const char ProgramName[]; // Program Name for use with LogMsgIdent
+extern const char ProgramName[];
-extern void LogMsg(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
-extern void LogMsgIdent(const char *ident, const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(2,3);
-extern void LogMsgNoIdent(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
-extern void SigLogLevel(void);
+extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(2,3);
+#define LogMsgNoIdent LogMsg
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
extern void *mallocL(char *msg, unsigned int size);
#define freeL(X,Y) free(Y)
#endif
-#if LogAllOperations
-#define LogOperation LogMsg
-#else
-#define LogOperation debugf
-#endif
-
-#ifdef __cplusplus
+#ifdef __cplusplus
}
#endif
Change History (most recent first):
$Log: mDNSEmbeddedAPI.h,v $
-Revision 1.468.2.4 2008/09/30 18:03:02 mcguire
+Revision 1.573 2009/06/30 18:17:45 herscher
+Add to 64 bit macro check for 64 bit Windows OSes
+
+Revision 1.572 2009/06/27 00:52:27 cheshire
+<rdar://problem/6959273> mDNSResponder taking up 13% CPU with 400 KBps incoming bonjour requests
+Removed overly-complicate and ineffective multi-packet known-answer snooping code
+(Bracketed it with "#if ENABLE_MULTI_PACKET_QUERY_SNOOPING" for now; will delete actual code later)
+
+Revision 1.571 2009/06/26 01:55:54 cheshire
+<rdar://problem/6890712> mDNS: iChat's Buddy photo always appears as the "shadow person" over Bonjour
+Additional refinements -- except for the case of explicit queries for record types we don't have (for names we own),
+add additional NSEC records only when there's space to do that without having to generate an additional packet
+
+Revision 1.570 2009/06/24 22:14:21 cheshire
+<rdar://problem/6911445> Plugging and unplugging the power cable shouldn't cause a network change event
+
+Revision 1.569 2009/06/03 23:07:12 cheshire
+<rdar://problem/6890712> mDNS: iChat's Buddy photo always appears as the "shadow person" over Bonjour
+Large records were not being added in cases where an NSEC record was also required
+
+Revision 1.568 2009/05/19 22:37:04 cheshire
+<rdar://problem/6903507> Sleep Proxy: Retransmission logic not working reliably on quiet networks
+Added NextScheduledSPRetry field
+
+Revision 1.567 2009/05/13 17:25:33 mkrochma
+<rdar://problem/6879926> Should not schedule maintenance wake when machine has no advertised services
+Sleep proxy client should only look for services being advertised via Multicast
+
+Revision 1.566 2009/05/12 23:09:24 cheshire
+<rdar://problem/6879926> Should not schedule maintenance wake when machine has no advertised services
+Declare mDNSCoreHaveAdvertisedServices routine so it can be called from daemon.c
+
+Revision 1.565 2009/05/09 00:10:58 jessic2
+Change expected size of NetworkInterfaceInfo to fix build failure
+
+Revision 1.564 2009/05/07 23:31:26 cheshire
+<rdar://problem/6601427> Sleep Proxy: Retransmit and retry Sleep Proxy Server requests
+Added NextSPSAttempt and NextSPSAttemptTime fields to NetworkInterfaceInfo_struct
+
+Revision 1.563 2009/04/24 21:06:38 cheshire
+Added comment about UDP length field (includes UDP header, so minimum value is 8 bytes)
+
+Revision 1.562 2009/04/24 00:22:23 cheshire
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+Added definition of rdataNSEC
+
+Revision 1.561 2009/04/23 22:06:29 cheshire
+Added CacheRecord and InterfaceID parameters to MakeNegativeCacheRecord, in preparation for:
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+
+Revision 1.560 2009/04/23 21:54:50 cheshire
+Updated comments
+
+Revision 1.559 2009/04/22 00:37:38 cheshire
+<rdar://problem/6814427> Remove unused kDNSType_MAC
+
+Revision 1.558 2009/04/21 23:36:25 cheshire
+<rdar://problem/6814427> Remove unused kDNSType_MAC
+
+Revision 1.557 2009/04/15 20:42:51 mcguire
+<rdar://problem/6768947> uDNS: Treat RCODE 5 (Refused) responses as failures
+
+Revision 1.556 2009/04/11 00:19:43 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.555 2009/04/01 21:12:27 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows.
+
+Revision 1.554 2009/04/01 17:50:11 mcguire
+cleanup mDNSRandom
+
+Revision 1.553 2009/03/26 03:59:00 jessic2
+Changes for <rdar://problem/6492552&6492593&6492609&6492613&6492628&6492640&6492699>
+
+Revision 1.552 2009/03/20 23:53:03 jessic2
+<rdar://problem/6646228> SIGHUP should restart all in-progress queries
+
+Revision 1.551 2009/03/18 20:41:04 cheshire
+Added definition of the all-ones mDNSOpaque16 ID
+
+Revision 1.550 2009/03/17 19:10:29 mcguire
+Fix sizechecks for x86_64
+
+Revision 1.549 2009/03/17 01:22:56 cheshire
+<rdar://problem/6601427> Sleep Proxy: Retransmit and retry Sleep Proxy Server requests
+Initial support for resolving up to three Sleep Proxies in parallel
+
+Revision 1.548 2009/03/14 01:42:56 mcguire
+<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
+
+Revision 1.547 2009/03/10 01:14:30 cheshire
+Sleep Proxies with invalid names need to be ignored (score 10000),
+not treated as "Sleep Proxy of last resort" (score 9999)
+
+Revision 1.546 2009/03/06 23:51:51 mcguire
+Fix broken build by defining DiscardPort
+
+Revision 1.545 2009/03/06 22:39:23 cheshire
+<rdar://problem/6655850> Ignore prototype base stations when picking Sleep Proxy to register with
+
+Revision 1.544 2009/03/04 01:33:30 cheshire
+Add m->ProxyRecords counter
+
+Revision 1.543 2009/03/03 23:04:43 cheshire
+For clarity, renamed "MAC" field to "HMAC" (Host MAC, as opposed to Interface MAC)
+
+Revision 1.542 2009/03/03 22:51:53 cheshire
+<rdar://problem/6504236> Sleep Proxy: Waking on same network but different interface will cause conflicts
+
+Revision 1.541 2009/03/03 00:45:19 cheshire
+Added m->PrimaryMAC field
+
+Revision 1.540 2009/02/27 02:56:57 cheshire
+Moved struct SearchListElem definition from uDNS.c into mDNSEmbeddedAPI.h
+
+Revision 1.539 2009/02/17 23:29:01 cheshire
+Throttle logging to a slower rate when running on SnowLeopard
+
+Revision 1.538 2009/02/11 02:31:57 cheshire
+Moved SystemWakeOnLANEnabled from mDNSMacOSX.h, so it's accessible to mDNSCore routines
+
+Revision 1.537 2009/02/07 02:51:48 cheshire
+<rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+Added new functions and timing variables
+
+Revision 1.536 2009/01/30 23:50:31 cheshire
+Added LastLabel() routine to get the last label of a domainname
+
+Revision 1.535 2009/01/23 00:38:36 mcguire
+<rdar://problem/5570906> BTMM: Doesn't work with Linksys WRT54GS firmware 4.71.1
+
+Revision 1.534 2009/01/22 02:14:25 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.533 2009/01/21 03:43:57 mcguire
+<rdar://problem/6511765> BTMM: Add support for setting kDNSServiceErr_NATPortMappingDisabled in DynamicStore
+
+Revision 1.532 2009/01/16 19:50:36 cheshire
+Oops. Fixed definition of SleepProxyServiceType.
+
+Revision 1.531 2009/01/16 19:48:09 cheshire
+Added definition of SleepProxyServiceType
+
+Revision 1.530 2009/01/15 00:22:49 mcguire
+<rdar://problem/6437092> NAT-PMP: mDNSResponder needs to listen on 224.0.0.1:5350/UDP with REUSEPORT
+
+Revision 1.529 2009/01/13 00:31:44 cheshire
+Fixed off-by-one error in computing the implicit limit pointer in the "DomainNameLength(name)" macro
+
+Revision 1.528 2009/01/10 01:43:52 cheshire
+Changed misleading function name 'AnsweredLOQ' to more informative 'AnsweredLocalQ'
+
+Revision 1.527 2008/12/12 01:23:19 cheshire
+Added m->SPSProxyListChanged state variable to flag when we need to update our BPF filter program
+
+Revision 1.526 2008/12/12 00:51:14 cheshire
+Added structure definitions for IPv6Header, etc.
+
+Revision 1.525 2008/12/10 02:18:31 cheshire
+Increased MaxMsg to 160 for showing longer TXT records in SIGINFO output
+
+Revision 1.524 2008/12/10 01:49:39 cheshire
+Fixes for alignment issues on ARMv5
+
+Revision 1.523 2008/12/05 02:35:24 mcguire
+<rdar://problem/6107390> Write to the DynamicStore when a Sleep Proxy server is available on the network
+
+Revision 1.522 2008/12/04 21:08:51 mcguire
+<rdar://problem/6116863> mDNS: Provide mechanism to disable Multicast advertisements
+
+Revision 1.521 2008/12/04 02:19:24 cheshire
+Updated comment
+
+Revision 1.520 2008/11/26 20:28:05 cheshire
+Added new SSHPort constant
+
+Revision 1.519 2008/11/25 22:46:30 cheshire
+For ease of code searching, renamed ZoneData field of ServiceRecordSet_struct from "nta" to "srs_nta"
+
+Revision 1.518 2008/11/25 05:07:15 cheshire
+<rdar://problem/6374328> Advertise Sleep Proxy metrics in service name
+
+Revision 1.517 2008/11/20 01:51:19 cheshire
+Exported RecreateNATMappings so it's callable from other files
+
+Revision 1.516 2008/11/16 16:49:25 cheshire
+<rdar://problem/6375808> LLQs broken in mDNSResponder-184
+DNSOpt_LLQData_Space was incorrectly defined to be 18 instead of 22
+
+Revision 1.515 2008/11/14 20:59:41 cheshire
+Added mDNSEthAddressIsZero(A) macro
+
+Revision 1.514 2008/11/14 02:17:41 cheshire
+Added NextScheduledSPS task scheduling variable
+
+Revision 1.513 2008/11/14 00:47:19 cheshire
+Added TimeRcvd and TimeExpire fields to AuthRecord_struct
+
+Revision 1.512 2008/11/14 00:00:53 cheshire
+After client machine wakes up, Sleep Proxy machine need to remove any records
+it was temporarily holding as proxy for that client
+
+Revision 1.511 2008/11/13 19:04:44 cheshire
+Added definition of OwnerOptData
+
+Revision 1.510 2008/11/06 23:48:32 cheshire
+Changed SleepProxyServerType to mDNSu8
+
+Revision 1.509 2008/11/04 23:06:50 cheshire
+Split RDataBody union definition into RDataBody and RDataBody2, and removed
+SOA from the normal RDataBody union definition, saving 270 bytes per AuthRecord
+
+Revision 1.508 2008/11/04 22:21:43 cheshire
+Changed zone field of AuthRecord_struct from domainname to pointer, saving 252 bytes per AuthRecord
+
+Revision 1.507 2008/11/04 22:13:43 cheshire
+Made RDataBody parameter to GetRRDisplayString_rdb "const"
+
+Revision 1.506 2008/11/04 20:06:19 cheshire
+<rdar://problem/6186231> Change MAX_DOMAIN_NAME to 256
+
+Revision 1.505 2008/11/03 23:49:47 mkrochma
+Increase NATMAP_DEFAULT_LEASE to 2 hours so we do maintenance wake less often
+
+Revision 1.504 2008/10/31 22:55:04 cheshire
+Initial support for structured SPS names
+
+Revision 1.503 2008/10/24 23:58:47 cheshire
+Ports should be mDNSIPPort, not mDNSOpaque16
+
+Revision 1.502 2008/10/23 22:25:56 cheshire
+Renamed field "id" to more descriptive "updateid"
+
+Revision 1.501 2008/10/22 22:22:27 cheshire
+Added packet structure definitions
+
+Revision 1.500 2008/10/22 19:55:35 cheshire
+Miscellaneous fixes; renamed FindFirstAnswerInCache to FindSPSInCache
+
+Revision 1.499 2008/10/22 17:15:47 cheshire
+Updated definitions of mDNSIPv4AddressIsZero/mDNSIPv4AddressIsOnes, etc.
+
+Revision 1.498 2008/10/22 01:01:52 cheshire
+Added onesEthAddr constant, used for sending ARP broadcasts
+
+Revision 1.497 2008/10/21 00:51:11 cheshire
+Added declaration of mDNSPlatformSetBPF(), used by uds_daemon.c to pass BPF fd to mDNSMacOSX.c
+
+Revision 1.496 2008/10/16 22:38:52 cheshire
+Added declaration of mDNSCoreReceiveRawPacket()
+
+Revision 1.495 2008/10/15 22:53:51 cheshire
+Removed unused "#define LocalReverseMapDomain"
+
+Revision 1.494 2008/10/15 20:37:17 cheshire
+Added "#define DNSOpt_Lease_Space 19"
+
+Revision 1.493 2008/10/14 21:37:56 cheshire
+Removed unnecessary m->BeSleepProxyServer variable
+
+Revision 1.492 2008/10/14 20:26:36 cheshire
+Added definition of a new kDNSType_MAC rdata type
+
+Revision 1.491 2008/10/09 22:29:04 cheshire
+Added "mDNSEthAddr MAC" to NetworkInterfaceInfo_struct
+
+Revision 1.490 2008/10/09 21:39:20 cheshire
+Update list of DNS types
+
+Revision 1.489 2008/10/09 18:59:19 cheshire
+Added NetWakeResolve code, removed unused m->SendDeregistrations and m->SendImmediateAnswers
+
+Revision 1.488 2008/10/08 01:02:03 cheshire
+Added mDNS_SetupQuestion() convenience function
+
+Revision 1.487 2008/10/07 21:41:57 mcguire
+Increase sizecheck limits to account for DNSQuestion added to NetworkInterfaceInfo_struct in 64bit builds
+
+Revision 1.486 2008/10/07 15:56:24 cheshire
+Increase sizecheck limits to account for DNSQuestion added to NetworkInterfaceInfo_struct
+
+Revision 1.485 2008/10/04 00:48:37 cheshire
+Added DNSQuestion to NetworkInterfaceInfo_struct, used for browsing for Sleep Proxy Servers
+
+Revision 1.484 2008/10/04 00:01:45 cheshire
+Move NetworkInterfaceInfo_struct further down in file (we'll need to add a DNSQuestion to it later)
+
+Revision 1.483 2008/10/03 23:28:41 cheshire
+Added declaration of mDNSPlatformSendRawPacket
+
+Revision 1.482 2008/10/03 17:30:05 cheshire
+Added declaration of mDNS_ConfigChanged(mDNS *const m);
+
+Revision 1.481 2008/10/02 22:38:58 cheshire
+Added SleepProxyServer fields, and mDNSCoreBeSleepProxyServer() call for turning SleepProxyServer on and off
+
+Revision 1.480 2008/10/01 21:22:17 cheshire
+Added NetWake field to NetworkInterfaceInfo structure, to signal when Wake-On-Magic-Packet is enabled for that interface
+
+Revision 1.479 2008/09/29 20:12:37 cheshire
+Rename 'AnswerLocalQuestions' to more descriptive 'AnswerLocalOnlyQuestions' and 'AnsweredLocalQ' to 'AnsweredLOQ'
+
+Revision 1.478 2008/09/23 02:37:10 cheshire
+Added FirstLabel/SecondLabel macros
+
+Revision 1.477 2008/09/20 00:34:22 mcguire
<rdar://problem/6129039> BTMM: Add support for WANPPPConnection
-Revision 1.468.2.3 2008/07/29 20:46:57 mcguire
-<rdar://problem/6090007> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-merge r1.474 from <rdar://problem/3988320>
+Revision 1.476 2008/09/05 22:22:01 cheshire
+Move "UDPSocket *LocalSocket" field to more logical place in DNSQuestion_struct
+
+Revision 1.475 2008/07/25 22:34:11 mcguire
+fix sizecheck issues for 64bit
-Revision 1.468.2.2 2008/07/29 19:44:38 mcguire
-<rdar://problem/6090024> BTMM: alternate SSDP queries between multicast & unicast
-merge r1.472, r1.473 for <rdar://problem/5736845>
+Revision 1.474 2008/07/24 20:23:03 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-Revision 1.468.2.1 2008/07/29 19:10:53 mcguire
-<rdar://problem/6090041> Use all configured DNS servers
-merege 1.470 from <rdar://problem/4206534>
+Revision 1.473 2008/07/18 21:37:42 mcguire
+<rdar://problem/5736845> BTMM: alternate SSDP queries between multicast & unicast
+
+Revision 1.472 2008/07/01 01:39:59 mcguire
+<rdar://problem/5823010> 64-bit fixes
+
+Revision 1.471 2008/06/26 17:24:11 mkrochma
+<rdar://problem/5450912> BTMM: Stop listening on UDP 5351 for NAT Status Announcements
+
+Revision 1.470 2008/06/19 01:20:49 mcguire
+<rdar://problem/4206534> Use all configured DNS servers
+
+Revision 1.469 2008/03/07 18:56:02 cheshire
+<rdar://problem/5777647> dnsbugtest query every three seconds when source IP address of response doesn't match
Revision 1.468 2008/03/06 02:48:34 mcguire
<rdar://problem/5321824> write status to the DS
Revision 1.428 2007/09/05 21:48:01 cheshire
<rdar://problem/5385864> BTMM: mDNSResponder flushes wide-area Bonjour records after an hour for a zone.
-Now that we're respecting the TTL of uDNS records in the cache, the LLQ maintenance cod needs
+Now that we're respecting the TTL of uDNS records in the cache, the LLQ maintenance code needs
to update the cache lifetimes of all relevant records every time it successfully renews an LLQ,
otherwise those records will expire and vanish from the cache.
#endif
#include "mDNSDebug.h"
+#if APPLE_OSX_mDNSResponder
+#include <uuid/uuid.h>
+#endif
#ifdef __cplusplus
extern "C" {
kDNSType_MINFO, // 14 Mailbox information
kDNSType_MX, // 15 Mail Exchanger
kDNSType_TXT, // 16 Arbitrary text string
- kDNSType_RP, // 17 Responsible person.
- kDNSType_AFSDB, // 18 AFS cell database.
- kDNSType_X25, // 19 X_25 calling address.
- kDNSType_ISDN, // 20 ISDN calling address.
- kDNSType_RT, // 21 Router.
- kDNSType_NSAP, // 22 NSAP address.
- kDNSType_NSAP_PTR, // 23 Reverse NSAP lookup (deprecated).
- kDNSType_SIG, // 24 Security signature.
- kDNSType_KEY, // 25 Security key.
- kDNSType_PX, // 26 X.400 mail mapping.
- kDNSType_GPOS, // 27 Geographical position (withdrawn).
- kDNSType_AAAA, // 28 IPv6 Address.
- kDNSType_LOC, // 29 Location Information.
- kDNSType_NXT, // 30 Next domain (security).
- kDNSType_EID, // 31 Endpoint identifier.
- kDNSType_NIMLOC, // 32 Nimrod Locator.
- kDNSType_SRV, // 33 Service record.
+ kDNSType_RP, // 17 Responsible person
+ kDNSType_AFSDB, // 18 AFS cell database
+ kDNSType_X25, // 19 X_25 calling address
+ kDNSType_ISDN, // 20 ISDN calling address
+ kDNSType_RT, // 21 Router
+ kDNSType_NSAP, // 22 NSAP address
+ kDNSType_NSAP_PTR, // 23 Reverse NSAP lookup (deprecated)
+ kDNSType_SIG, // 24 Security signature
+ kDNSType_KEY, // 25 Security key
+ kDNSType_PX, // 26 X.400 mail mapping
+ kDNSType_GPOS, // 27 Geographical position (withdrawn)
+ kDNSType_AAAA, // 28 IPv6 Address
+ kDNSType_LOC, // 29 Location Information
+ kDNSType_NXT, // 30 Next domain (security)
+ kDNSType_EID, // 31 Endpoint identifier
+ kDNSType_NIMLOC, // 32 Nimrod Locator
+ kDNSType_SRV, // 33 Service record
kDNSType_ATMA, // 34 ATM Address
kDNSType_NAPTR, // 35 Naming Authority PoinTeR
kDNSType_KX, // 36 Key Exchange
kDNSType_CERT, // 37 Certification record
kDNSType_A6, // 38 IPv6 Address (deprecated)
kDNSType_DNAME, // 39 Non-terminal DNAME (for IPv6)
- kDNSType_SINK, // 40 Kitchen sink (experimentatl)
+ kDNSType_SINK, // 40 Kitchen sink (experimental)
kDNSType_OPT, // 41 EDNS0 option (meta-RR)
kDNSType_APL, // 42 Address Prefix List
kDNSType_DS, // 43 Delegation Signer
kDNSType_SSHFP, // 44 SSH Key Fingerprint
kDNSType_IPSECKEY, // 45 IPSECKEY
kDNSType_RRSIG, // 46 RRSIG
- kDNSType_NSEC, // 47 NSEC
+ kDNSType_NSEC, // 47 Denial of Existence
kDNSType_DNSKEY, // 48 DNSKEY
- kDNSType_DHCID, // 49 DHCID
+ kDNSType_DHCID, // 49 DHCP Client Identifier
+ kDNSType_NSEC3, // 50 Hashed Authenticated Denial of Existence
+ kDNSType_NSEC3PARAM, // 51 Hashed Authenticated Denial of Existence
+
+ kDNSType_HIP = 55, // 55 Host Identity Protocol
+
+ kDNSType_SPF = 99, // 99 Sender Policy Framework for E-Mail
+ kDNSType_UINFO, // 100 IANA-Reserved
+ kDNSType_UID, // 101 IANA-Reserved
+ kDNSType_GID, // 102 IANA-Reserved
+ kDNSType_UNSPEC, // 103 IANA-Reserved
kDNSType_TKEY = 249, // 249 Transaction key
- kDNSType_TSIG, // 250 Transaction signature.
- kDNSType_IXFR, // 251 Incremental zone transfer.
- kDNSType_AXFR, // 252 Transfer zone of authority.
- kDNSType_MAILB, // 253 Transfer mailbox records.
- kDNSType_MAILA, // 254 Transfer mail agent records.
+ kDNSType_TSIG, // 250 Transaction signature
+ kDNSType_IXFR, // 251 Incremental zone transfer
+ kDNSType_AXFR, // 252 Transfer zone of authority
+ kDNSType_MAILB, // 253 Transfer mailbox records
+ kDNSType_MAILA, // 254 Transfer mail agent records
kDNSQType_ANY // Not a DNS type, but a DNS query type, meaning "all types"
} DNS_TypeValues;
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Simple types
#endif
// less than, add, multiply, increment, decrement, etc., are undefined for opaque identifiers,
// and if you make the mistake of trying to do those using the NotAnInteger field, then you'll
// find you get code that doesn't work consistently on big-endian and little-endian machines.
-typedef packedunion { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16;
-typedef packedunion { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32;
+#if defined(_WIN32)
+ #pragma pack(push,2)
+#endif
+typedef union { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16;
+typedef union { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32;
typedef packedunion { mDNSu8 b[ 6]; mDNSu16 w[3]; mDNSu32 l[1]; } mDNSOpaque48;
-typedef packedunion { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64;
-typedef packedunion { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128;
+typedef union { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64;
+typedef union { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128;
+#if defined(_WIN32)
+ #pragma pack(pop)
+#endif
typedef mDNSOpaque16 mDNSIPPort; // An IP port is a two-byte opaque identifier (not an integer)
typedef mDNSOpaque32 mDNSv4Addr; // An IP address is a four-byte opaque identifier (not an integer)
#define MAX_DOMAIN_LABEL 63
typedef struct { mDNSu8 c[ 64]; } domainlabel; // One label: length byte and up to 63 characters
-// RFC 1034/1035 specify that a domain name, including length bytes, data bytes, and terminating zero, may be up to 255 bytes long
-#define MAX_DOMAIN_NAME 255
-typedef struct { mDNSu8 c[256]; } domainname; // Up to 255 bytes of length-prefixed domainlabels
+// RFC 1034/1035/2181 specify that a domain name, including length bytes, data bytes, and terminating zero, may be up to 256 bytes long
+#define MAX_DOMAIN_NAME 256
+typedef struct { mDNSu8 c[256]; } domainname; // Up to 256 bytes of length-prefixed domainlabels
typedef struct { mDNSu8 c[256]; } UTF8str255; // Null-terminated C string
-// The longest legal textual form of a DNS name is 1005 bytes, including the C-string terminating NULL at the end.
+// The longest legal textual form of a DNS name is 1009 bytes, including the C-string terminating NULL at the end.
// Explanation:
// When a native domainname object is converted to printable textual form using ConvertDomainNameToCString(),
// non-printing characters are represented in the conventional DNS way, as '\ddd', where ddd is a three-digit decimal number.
-// The longest legal domain name is 255 bytes, in the form of four labels as shown below:
-// Length byte, 63 data bytes, length byte, 63 data bytes, length byte, 63 data bytes, length byte, 61 data bytes, zero byte.
+// The longest legal domain name is 256 bytes, in the form of four labels as shown below:
+// Length byte, 63 data bytes, length byte, 63 data bytes, length byte, 63 data bytes, length byte, 62 data bytes, zero byte.
// Each label is encoded textually as characters followed by a trailing dot.
// If every character has to be represented as a four-byte escape sequence, then this makes the maximum textual form four labels
// plus the C-string terminating NULL as shown below:
-// 63*4+1 + 63*4+1 + 63*4+1 + 61*4+1 + 1 = 1005.
+// 63*4+1 + 63*4+1 + 63*4+1 + 62*4+1 + 1 = 1009.
// Note that MAX_ESCAPED_DOMAIN_LABEL is not normally used: If you're only decoding a single label, escaping is usually not required.
// It is for domain names, where dots are used as label separators, that proper escaping is vital.
#define MAX_ESCAPED_DOMAIN_LABEL 254
-#define MAX_ESCAPED_DOMAIN_NAME 1005
+#define MAX_ESCAPED_DOMAIN_NAME 1009
// MAX_REVERSE_MAPPING_NAME
// For IPv4: "123.123.123.123.in-addr.arpa." 30 bytes including terminating NUL
typedef struct NATTraversalInfo_struct NATTraversalInfo;
// Structure to abstract away the differences between TCP/SSL sockets, and one for UDP sockets
-// The actual definition of these structures in the in the appropriate platform support code
+// The actual definition of these structures appear in the appropriate platform support code
typedef struct TCPSocket_struct TCPSocket;
typedef struct UDPSocket_struct UDPSocket;
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - DNS Message structures
#endif
// ***************************************************************************
#if 0
+#pragma mark -
+#pragma mark - Other Packet Format Structures
+#endif
+
+typedef packedstruct
+ {
+ mDNSEthAddr dst;
+ mDNSEthAddr src;
+ mDNSOpaque16 ethertype;
+ } EthernetHeader; // 14 bytes
+
+typedef packedstruct
+ {
+ mDNSOpaque16 hrd;
+ mDNSOpaque16 pro;
+ mDNSu8 hln;
+ mDNSu8 pln;
+ mDNSOpaque16 op;
+ mDNSEthAddr sha;
+ mDNSv4Addr spa;
+ mDNSEthAddr tha;
+ mDNSv4Addr tpa;
+ } ARP_EthIP; // 28 bytes
+
+typedef packedstruct
+ {
+ mDNSu8 vlen;
+ mDNSu8 tos;
+ mDNSu16 totlen;
+ mDNSOpaque16 id;
+ mDNSOpaque16 flagsfrags;
+ mDNSu8 ttl;
+ mDNSu8 protocol;
+ mDNSu16 checksum;
+ mDNSv4Addr src;
+ mDNSv4Addr dst;
+ } IPv4Header; // 20 bytes
+
+typedef packedstruct
+ {
+ mDNSu32 vcf; // Version, Traffic Class, Flow Label
+ mDNSu16 len; // Payload Length
+ mDNSu8 protocol; // Type of next header: 0x06 = TCP, 0x11 = UDP, 0x3A = ICMPv6
+ mDNSu8 ttl; // Hop Limit
+ mDNSv6Addr src;
+ mDNSv6Addr dst;
+ } IPv6Header; // 40 bytes
+
+typedef packedstruct
+ {
+ mDNSu8 type; // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement
+ mDNSu8 code;
+ mDNSu16 checksum;
+ mDNSu32 reserved;
+ mDNSv6Addr target;
+ } IPv6ND; // 24 bytes
+
+typedef packedstruct
+ {
+ mDNSIPPort src;
+ mDNSIPPort dst;
+ mDNSu16 len; // Length including UDP header (ie. minimum value is 8 bytes)
+ mDNSu16 checksum;
+ } UDPHeader; // 8 bytes
+
+typedef packedstruct
+ {
+ mDNSIPPort src;
+ mDNSIPPort dst;
+ mDNSu32 seq;
+ mDNSu32 ack;
+ mDNSu8 offset;
+ mDNSu8 flags;
+ mDNSu16 window;
+ mDNSu16 checksum;
+ mDNSu16 urgent;
+ } TCPHeader; // 20 bytes
+
+// ***************************************************************************
+#if 0
+#pragma mark -
#pragma mark - Resource Record structures
#endif
mDNSu32 min; // Nominally the minimum record TTL for this zone, in seconds; also used for negative caching.
} rdataSOA;
-typedef packedstruct
+// EDNS Option Code registrations are recorded in the "DNS EDNS0 Options" section of
+// <http://www.iana.org/assignments/dns-parameters>
+
+#define kDNSOpt_LLQ 1
+#define kDNSOpt_Lease 2
+#define kDNSOpt_NSID 3
+#define kDNSOpt_Owner 4
+
+typedef struct
{
mDNSu16 vers;
mDNSu16 llqOp;
mDNSu16 err; // Or UDP reply port, in setup request
+ // Note: In the in-memory form, there's typically a two-byte space here, so that the following 64-bit id is word-aligned
mDNSOpaque64 id;
mDNSu32 llqlease;
} LLQOptData;
-// Windows adds pad bytes to sizeof(LLQOptData).
-// Use this macro when setting length fields or validating option rdata from off the wire.
-// Use sizeof(LLQOptData) when dealing with structures (e.g. memcpy).
-// Never memcpy between on-the-wire representation and a structure.
-
-#define LLQ_OPTLEN ((3 * sizeof(mDNSu16)) + 8 + sizeof(mDNSu32))
-
-// NOTE: rdataOPT format may be repeated an arbitrary number of times in a single resource record
+typedef struct
+ {
+ mDNSu8 vers; // Version number of this Owner OPT record
+ mDNSs8 seq; // Sleep/wake epoch
+ mDNSEthAddr HMAC; // Host's primary identifier (e.g. MAC of on-board Ethernet)
+ mDNSEthAddr IMAC; // Interface's MAC address (if different to primary MAC)
+ mDNSOpaque48 password; // Optional password
+ } OwnerOptData;
+
+// Note: rdataOPT format may be repeated an arbitrary number of times in a single resource record
typedef packedstruct
{
mDNSu16 opt;
mDNSu16 optlen;
- union { LLQOptData llq; mDNSu32 updatelease; } OptData;
+ union { LLQOptData llq; mDNSu32 updatelease; OwnerOptData owner; } u;
} rdataOPT;
+// Space needed to put OPT records into a packet:
+// Header 11 bytes (name 1, type 2, class 2, TTL 4, length 2)
+// LLQ rdata 18 bytes (opt 2, len 2, vers 2, op 2, err 2, id 8, lease 4)
+// Lease rdata 8 bytes (opt 2, len 2, lease 4)
+// Owner rdata 12-24 (opt 2, len 2, owner 8-20)
+
+#define DNSOpt_Header_Space 11
+#define DNSOpt_LLQData_Space (4 + 2 + 2 + 2 + 8 + 4)
+#define DNSOpt_LeaseData_Space (4 + 4)
+#define DNSOpt_OwnerData_ID_Space (4 + 2 + 6)
+#define DNSOpt_OwnerData_ID_Wake_Space (4 + 2 + 6 + 6)
+#define DNSOpt_OwnerData_ID_Wake_PW4_Space (4 + 2 + 6 + 6 + 4)
+#define DNSOpt_OwnerData_ID_Wake_PW6_Space (4 + 2 + 6 + 6 + 6)
+
+#define ValidOwnerLength(X) ( (X) == DNSOpt_OwnerData_ID_Space - 4 || \
+ (X) == DNSOpt_OwnerData_ID_Wake_Space - 4 || \
+ (X) == DNSOpt_OwnerData_ID_Wake_PW4_Space - 4 || \
+ (X) == DNSOpt_OwnerData_ID_Wake_PW6_Space - 4 )
+
+#define ValidDNSOpt(O) (((O)->opt == kDNSOpt_LLQ && (O)->optlen == DNSOpt_LLQData_Space - 4) || \
+ ((O)->opt == kDNSOpt_Lease && (O)->optlen == DNSOpt_LeaseData_Space - 4) || \
+ ((O)->opt == kDNSOpt_Owner && ValidOwnerLength((O)->optlen) ) )
+
+#define DNSOpt_Owner_Space(O) (mDNSSameEthAddress(&(O)->u.owner.HMAC, &(O)->u.owner.IMAC) ? DNSOpt_OwnerData_ID_Space : DNSOpt_OwnerData_ID_Wake_Space)
+
+#define DNSOpt_Data_Space(O) ( \
+ (O)->opt == kDNSOpt_LLQ ? DNSOpt_LLQData_Space : \
+ (O)->opt == kDNSOpt_Lease ? DNSOpt_LeaseData_Space : \
+ (O)->opt == kDNSOpt_Owner ? DNSOpt_Owner_Space(O) : 0x10000)
+
+// A maximal NSEC record is:
+// 256 bytes domainname 'nextname'
+// + 256 * 34 = 8704 bytes of bitmap data
+// = 8960 bytes total
+// For now we only support NSEC records encoding DNS types 0-255 and ignore the nextname (we always set it to be the same as the rrname),
+// which gives us a fixed in-memory size of 32 bytes (256 bits)
+typedef struct
+ {
+ mDNSu8 bitmap[32];
+ } rdataNSEC;
+
// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
// MaximumRDSize is 8K the absolute maximum we support (at least for now)
#define StandardAuthRDSize 264
// have them both be the same size. Making one smaller without making the other smaller won't actually save any memory.
#define InlineCacheRDSize 68
-#define InlineCacheGroupNameSize 144
+// On 64-bit, the pointers in a CacheRecord are bigger, and that creates 8 bytes more space for the name in a CacheGroup
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ #if defined(_ILP64) || defined(__ILP64__) || defined(_LP64) || defined(__LP64__) || defined(_WIN64)
+ #define InlineCacheGroupNameSize 152
+ #else
+ #define InlineCacheGroupNameSize 144
+ #endif
+#else
+ #if defined(_ILP64) || defined(__ILP64__) || defined(_LP64) || defined(__LP64__) || defined(_WIN64)
+ #define InlineCacheGroupNameSize 136
+ #else
+ #define InlineCacheGroupNameSize 128
+ #endif
+#endif
+// The RDataBody union defines the common rdata types that fit into our 264-byte limit
typedef union
{
mDNSu8 data[StandardAuthRDSize];
mDNSv4Addr ipv4; // For 'A' record
domainname name; // For PTR, NS, CNAME, DNAME
- rdataSOA soa;
UTF8str255 txt;
rdataMX mx;
- rdataRP rp;
- rdataPX px;
mDNSv6Addr ipv6; // For 'AAAA' record
rdataSRV srv;
- rdataOPT opt; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together
+ rdataOPT opt[2]; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together
+ rdataNSEC nsec;
} RDataBody;
+// The RDataBody2 union is the same as above, except it includes fields for the larger types like soa, rp, px
+typedef union
+ {
+ mDNSu8 data[StandardAuthRDSize];
+ mDNSv4Addr ipv4; // For 'A' record
+ domainname name; // For PTR, NS, CNAME, DNAME
+ rdataSOA soa; // This is large; not included in the normal RDataBody definition
+ UTF8str255 txt;
+ rdataMX mx;
+ rdataRP rp; // This is large; not included in the normal RDataBody definition
+ rdataPX px; // This is large; not included in the normal RDataBody definition
+ mDNSv6Addr ipv6; // For 'AAAA' record
+ rdataSRV srv;
+ rdataOPT opt[2]; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together
+ rdataNSEC nsec;
+ } RDataBody2;
+
typedef struct
{
mDNSu16 MaxRDLength; // Amount of storage allocated for rdata (usually sizeof(RDataBody))
+ mDNSu16 padding; // So that RDataBody is aligned on 32-bit boundary
RDataBody u;
} RData;
+
+// sizeofRDataHeader should be 4 bytes
#define sizeofRDataHeader (sizeof(RData) - sizeof(RDataBody))
+// RData_small is a smaller version of the RData object, used for inline data storage embedded in a CacheRecord_struct
+typedef struct
+ {
+ mDNSu16 MaxRDLength; // Storage allocated for data (may be greater than InlineCacheRDSize if additional storage follows this object)
+ mDNSu16 padding; // So that data is aligned on 32-bit boundary
+ mDNSu8 data[InlineCacheRDSize];
+ } RData_small;
+
// Note: Within an mDNSRecordCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute()
typedef void mDNSRecordCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - NAT Traversal structures and constants
#endif
-#define NATMAP_MAX_RETRY_INTERVAL ((mDNSPlatformOneSecond * 60) * 15) // Max retry interval is 15 minutes
-#define NATMAP_MIN_RETRY_INTERVAL (mDNSPlatformOneSecond * 2) // Min retry interval is 2 seconds
-#define NATMAP_INIT_RETRY (mDNSPlatformOneSecond / 4) // start at 250ms w/ exponential decay
-#define NATMAP_DEFAULT_LEASE (60 * 60) // lease life in seconds
+#define NATMAP_MAX_RETRY_INTERVAL ((mDNSPlatformOneSecond * 60) * 15) // Max retry interval is 15 minutes
+#define NATMAP_MIN_RETRY_INTERVAL (mDNSPlatformOneSecond * 2) // Min retry interval is 2 seconds
+#define NATMAP_INIT_RETRY (mDNSPlatformOneSecond / 4) // start at 250ms w/ exponential decay
+#define NATMAP_DEFAULT_LEASE (60 * 60 * 2) // 2 hour lease life in seconds
#define NATMAP_VERS 0
typedef enum
// Client API fields: The client must set up these fields *before* making any NAT traversal API calls
mDNSu8 Protocol; // NATOp_MapUDP or NATOp_MapTCP, or zero if just requesting the external IP address
mDNSIPPort IntPort; // Client's internal port number (doesn't change)
- mDNSIPPort RequestedPort; // Requested public port mapping; may be updated with actual value assigned by gateway
+ mDNSIPPort RequestedPort; // Requested external port; may be updated with actual value assigned by gateway
mDNSu32 NATLease; // Requested lifetime in seconds (doesn't change)
NATTraversalClientCallback clientCallback;
void *clientContext;
};
-typedef struct
+typedef struct // Size is 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
{
mDNSu8 RecordType; // See enum above
- mDNSInterfaceID InterfaceID; // Set if this RR is specific to one interface
- // For records received off the wire, InterfaceID is *always* set to the receiving interface
- // For our authoritative records, InterfaceID is usually zero, except for those few records
- // that are interface-specific (e.g. address records, especially linklocal addresses)
- const domainname *name;
mDNSu16 rrtype;
mDNSu16 rrclass;
mDNSu32 rroriginalttl; // In seconds
mDNSu16 rdlength; // Size of the raw rdata, in bytes, in the on-the-wire format
- // (in-memory storage may be larger, for structures containing 'holes', like SOA)
- mDNSu16 rdestimate; // Upper bound on size of rdata after name compression
+ // (In-memory storage may be larger, for structures containing 'holes', like SOA,
+ // or smaller, for NSEC where we don't bother storing the nextname field)
+ mDNSu16 rdestimate; // Upper bound on on-the-wire size of rdata after name compression
mDNSu32 namehash; // Name-based (i.e. case-insensitive) hash of name
mDNSu32 rdatahash; // For rdata containing domain name (e.g. PTR, SRV, CNAME etc.), case-insensitive name hash
// else, for all other rdata, 32-bit hash of the raw rdata
// ReconfirmAntecedents(), etc., use rdatahash as a pre-flight check to see
// whether it's worth doing a full SameDomainName() call. If the rdatahash
// is not a correct case-insensitive name hash, they'll get false negatives.
+
+ // Grouping pointers together at the end of the structure improves the memory layout efficiency
+ mDNSInterfaceID InterfaceID; // Set if this RR is specific to one interface
+ // For records received off the wire, InterfaceID is *always* set to the receiving interface
+ // For our authoritative records, InterfaceID is usually zero, except for those few records
+ // that are interface-specific (e.g. address records, especially linklocal addresses)
+ const domainname *name;
RData *rdata; // Pointer to storage for this rdata
} ResourceRecord;
AuthRecord *next; // Next in list; first element of structure for efficiency reasons
// Field Group 1: Common ResourceRecord fields
- ResourceRecord resrec;
+ ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
// Field Group 2: Persistent metadata for Authoritative Records
AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record)
- AuthRecord *Additional2; // Another additional (e.g. TXT for record)
+ AuthRecord *Additional2; // Another additional (e.g. TXT for PTR record)
AuthRecord *DependentOn; // This record depends on another for its uniqueness checking
AuthRecord *RRSet; // This unique record is part of an RRSet
mDNSRecordCallback *RecordCallback; // Callback function to call for state changes, and to free memory asynchronously on deregistration
mDNSu8 AllowRemoteQuery; // Set if we allow hosts not on the local link to query this record
mDNSu8 ForceMCast; // Set by client to advertise solely via multicast, even for apparently unicast names
+ OwnerOptData WakeUp; // Fpr Sleep Proxy records, MAC address of original owner (so we can wake it)
+ mDNSAddr AddressProxy; // For reverse-mapping Sleep Proxy PTR records, address in question
+ mDNSs32 TimeRcvd; // In platform time units
+ mDNSs32 TimeExpire; // In platform time units
+
+
// Field Group 3: Transient state for Authoritative Records
mDNSu8 Acknowledged; // Set if we've given the success callback to the client
mDNSu8 ProbeCount; // Number of probes remaining before this record is valid (kDNSRecordTypeUnique)
mDNSu8 AnnounceCount; // Number of announcements remaining (kDNSRecordTypeShared)
mDNSu8 RequireGoodbye; // Set if this RR has been announced on the wire and will require a goodbye packet
- mDNSu8 AnsweredLocalQ; // Set if this RR has been delivered to LocalOnly questions
+ mDNSu8 AnsweredLocalQ; // Set if this AuthRecord has been delivered to any local question (LocalOnly or mDNSInterface_Any)
mDNSu8 IncludeInProbe; // Set if this RR is being put into a probe right now
- mDNSInterfaceID ImmedAnswer; // Someone on this interface issued a query we need to answer (all-ones for all interfaces)
mDNSu8 ImmedUnicast; // Set if we may send our response directly via unicast to the requester
+ mDNSInterfaceID SendNSECNow; // Set if we need to generate associated NSEC data for this rrname
+ mDNSInterfaceID ImmedAnswer; // Someone on this interface issued a query we need to answer (all-ones for all interfaces)
#if MDNS_LOG_ANSWER_SUPPRESSION_TIMES
mDNSs32 ImmedAnswerMarkTime;
#endif
// and rr->state can be regState_Unregistered
// What if we find one of those statements is true and the other false? What does that mean?
mDNSBool uselease; // dynamic update contains (should contain) lease option
- mDNSs32 expire; // expiration of lease (-1 for static)
+ mDNSs32 expire; // In platform time units: expiration of lease (-1 for static)
mDNSBool Private; // If zone is private, DNS updates may have to be encrypted to prevent eavesdropping
- mDNSOpaque16 id; // identifier to match update request and response
- domainname zone; // the zone that is updated
+ mDNSOpaque16 updateid; // Identifier to match update request and response -- also used when transferring records to Sleep Proxy
+ const domainname *zone; // the zone that is updated
mDNSAddr UpdateServer; // DNS server that handles updates for this zone
mDNSIPPort UpdatePort; // port on which server accepts dynamic updates
// !!!KRS not technically correct to cache longer than TTL
// uDNS_UpdateRecord support fields
// Do we really need all these in *addition* to NewRData and newrdlength above?
- RData *OrigRData;
mDNSu16 OrigRDLen; // previously registered, being deleted
- RData *InFlightRData;
mDNSu16 InFlightRDLen; // currently being registered
- RData *QueuedRData; // if the client call Update while an update is in flight, we must finish the
mDNSu16 QueuedRDLen; // pending operation (re-transmitting if necessary) THEN register the queued update
+ RData *OrigRData;
+ RData *InFlightRData;
+ RData *QueuedRData;
// Field Group 5: Large data objects go at the end
domainname namestorage;
CacheRecord *members; // List of CacheRecords with this same name
CacheRecord **rrcache_tail; // Tail end of that list
domainname *name; // Common name for all CacheRecords in this list
+ // Size to here is 20 bytes when compiling 32-bit; 40 bytes when compiling 64-bit
mDNSu8 namestorage[InlineCacheGroupNameSize];
};
struct CacheRecord_struct
{
CacheRecord *next; // Next in list; first element of structure for efficiency reasons
- ResourceRecord resrec;
+ ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
// Transient state for Cache Records
CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send
DNSQuestion *CRActiveQuestion; // Points to an active question referencing this answer
mDNSu32 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer
mDNSs32 LastUnansweredTime; // In platform time units; last time we incremented UnansweredQueries
+#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
mDNSu32 MPUnansweredQ; // Multi-packet query handling: Number of times we've seen a query for this record
mDNSs32 MPLastUnansweredQT; // Multi-packet query handling: Last time we incremented MPUnansweredQ
mDNSu32 MPUnansweredKA; // Multi-packet query handling: Number of times we've seen this record in a KA list
mDNSBool MPExpectingKA; // Multi-packet query handling: Set when we increment MPUnansweredQ; allows one KA
+#endif
CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set
-
- struct { mDNSu16 MaxRDLength; mDNSu8 data[InlineCacheRDSize]; } rdatastorage; // Storage for small records is right here
+ // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit
+ RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes)
};
// Storage sufficient to hold either a CacheGroup header or a CacheRecord
+// -- for best efficiency (to avoid wasted unused storage) they should be the same size
typedef union CacheEntity_union CacheEntity;
union CacheEntity_union { CacheEntity *next; CacheGroup cg; CacheRecord cr; };
mDNSInterfaceID interface; // For specialized uses; we can have DNS servers reachable over specific interfaces
mDNSAddr addr;
mDNSIPPort port;
+ mDNSOpaque16 testid;
mDNSu32 flags; // Set when we're planning to delete this from the list
mDNSu32 teststate; // Have we sent bug-detection query to this server?
mDNSs32 lasttest; // Time we sent last bug-detection query to this server
domainname domain; // name->server matching for "split dns"
} DNSServer;
-typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo;
-
-// A NetworkInterfaceInfo_struct serves two purposes:
-// 1. It holds the address, PTR and HINFO records to advertise a given IP address on a given physical interface
-// 2. It tells mDNSCore which physical interfaces are available; each physical interface has its own unique InterfaceID.
-// Since there may be multiple IP addresses on a single physical interface,
-// there may be multiple NetworkInterfaceInfo_structs with the same InterfaceID.
-// In this case, to avoid sending the same packet n times, when there's more than one
-// struct with the same InterfaceID, mDNSCore picks one member of the set to be the
-// active representative of the set; all others have the 'InterfaceActive' flag unset.
-
-struct NetworkInterfaceInfo_struct
- {
- // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
- NetworkInterfaceInfo *next;
-
- mDNSBool InterfaceActive; // Set if interface is sending & receiving packets (see comment above)
- mDNSBool IPv4Available; // If InterfaceActive, set if v4 available on this InterfaceID
- mDNSBool IPv6Available; // If InterfaceActive, set if v6 available on this InterfaceID
-
- // Standard AuthRecords that every Responder host should have (one per active IP address)
- AuthRecord RR_A; // 'A' or 'AAAA' (address) record for our ".local" name
- AuthRecord RR_PTR; // PTR (reverse lookup) record
- AuthRecord RR_HINFO;
-
- // Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface()
- mDNSInterfaceID InterfaceID; // Identifies physical interface; MUST NOT be 0, -1, or -2
- mDNSAddr ip; // The IPv4 or IPv6 address to advertise
- mDNSAddr mask;
- char ifname[64]; // Windows uses a GUID string for the interface name, which doesn't fit in 16 bytes
- mDNSBool Advertise; // False if you are only searching on this interface
- mDNSBool McastTxRx; // Send/Receive multicast on this { InterfaceID, address family } ?
- };
-
typedef struct ExtraResourceRecord_struct ExtraResourceRecord;
struct ExtraResourceRecord_struct
{
// all required data is passed as parameters to that function.
// Begin uDNS info ****************
- // Hopefully much of this stuff can be simplified or eliminated
+ // All of these fields should be eliminated
- // NOTE: The current uDNS code keeps an explicit list of registered services, and handles them
+ // Note: The current uDNS code keeps an explicit list of registered services, and handles them
// differently to how individual records are treated (this is probably a mistake). What this means is
// that ServiceRecordSets for uDNS are kept in a linked list, whereas ServiceRecordSets for mDNS exist
// just as a convenient placeholder to group the component records together and are not kept on any list.
mDNSBool srs_uselease; // dynamic update contains (should contain) lease option
mDNSBool TestForSelfConflict; // on name conflict, check if we're just seeing our own orphaned records
mDNSBool Private; // If zone is private, DNS updates may have to be encrypted to prevent eavesdropping
- ZoneData *nta;
+ ZoneData *srs_nta;
mDNSOpaque16 id;
domainname zone; // the zone that is updated
mDNSAddr SRSUpdateServer; // primary name server for the record's zone !!!KRS not technically correct to cache longer than TTL
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Question structures
#endif
} LLQ_State;
// LLQ constants
-#define kDNSOpt_LLQ 1
-#define kDNSOpt_Lease 2
#define kLLQ_Vers 1
#define kLLQ_DefLease 7200 // 2 hours
#define kLLQ_MAX_TRIES 3 // retry an operation 3 times max
#define kLLQOp_Refresh 2
#define kLLQOp_Event 3
-#define LLQ_OPT_RDLEN ((2 * sizeof(mDNSu16)) + LLQ_OPTLEN )
-#define LEASE_OPT_RDLEN ((2 * sizeof(mDNSu16)) + sizeof(mDNSs32))
-
// LLQ Errror Codes
enum
{
mDNSu32 CNAMEReferrals; // Count of how many CNAME redirections we've done
// Wide Area fields. These are used internally by the uDNS core
+ UDPSocket *LocalSocket;
DNSServer *qDNSServer; // Caching server for this query (in the absence of an SRV saying otherwise)
mDNSu8 unansweredQueries;// The number of unanswered queries to this server
// LLQ-specific fields. These fields are only meaningful when LongLived flag is set
LLQ_State state;
- mDNSu32 ReqLease; // seconds (relative)
+ mDNSu32 ReqLease; // seconds (relative)
mDNSs32 expire; // ticks (absolute)
mDNSs16 ntries;
mDNSOpaque64 id;
mDNSAddr Target; // Non-zero if you want to direct queries to a specific unicast target address
mDNSIPPort TargetPort; // Must be set if Target is set
mDNSOpaque16 TargetQID; // Must be set if Target is set
- UDPSocket *LocalSocket;
domainname qname;
mDNSu16 qtype;
mDNSu16 qclass;
mDNSv6Addr rmt_inner;
mDNSv4Addr rmt_outer;
mDNSIPPort rmt_outer_port;
- char b64keydata[32];
DNSQuestion q;
} ClientTunnel;
#endif
// ***************************************************************************
#if 0
+#pragma mark -
+#pragma mark - NetworkInterfaceInfo_struct
+#endif
+
+typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo;
+
+// A NetworkInterfaceInfo_struct serves two purposes:
+// 1. It holds the address, PTR and HINFO records to advertise a given IP address on a given physical interface
+// 2. It tells mDNSCore which physical interfaces are available; each physical interface has its own unique InterfaceID.
+// Since there may be multiple IP addresses on a single physical interface,
+// there may be multiple NetworkInterfaceInfo_structs with the same InterfaceID.
+// In this case, to avoid sending the same packet n times, when there's more than one
+// struct with the same InterfaceID, mDNSCore picks one member of the set to be the
+// active representative of the set; all others have the 'InterfaceActive' flag unset.
+
+struct NetworkInterfaceInfo_struct
+ {
+ // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
+ NetworkInterfaceInfo *next;
+
+ mDNSu8 InterfaceActive; // Set if interface is sending & receiving packets (see comment above)
+ mDNSu8 IPv4Available; // If InterfaceActive, set if v4 available on this InterfaceID
+ mDNSu8 IPv6Available; // If InterfaceActive, set if v6 available on this InterfaceID
+
+ DNSQuestion NetWakeBrowse;
+ DNSQuestion NetWakeResolve[3]; // For fault-tolerance, we try up to three Sleep Proxies
+ mDNSAddr SPSAddr[3];
+ mDNSIPPort SPSPort[3];
+ mDNSs32 NextSPSAttempt; // -1 if we're not currently attempting to register with any Sleep Proxy
+ mDNSs32 NextSPSAttemptTime;
+
+ // Standard AuthRecords that every Responder host should have (one per active IP address)
+ AuthRecord RR_A; // 'A' or 'AAAA' (address) record for our ".local" name
+ AuthRecord RR_PTR; // PTR (reverse lookup) record
+ AuthRecord RR_HINFO;
+
+ // Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface()
+ mDNSInterfaceID InterfaceID; // Identifies physical interface; MUST NOT be 0, -1, or -2
+ mDNSAddr ip; // The IPv4 or IPv6 address to advertise
+ mDNSAddr mask;
+ mDNSEthAddr MAC;
+ char ifname[64]; // Windows uses a GUID string for the interface name, which doesn't fit in 16 bytes
+ mDNSu8 Advertise; // False if you are only searching on this interface
+ mDNSu8 McastTxRx; // Send/Receive multicast on this { InterfaceID, address family } ?
+ mDNSu8 NetWake; // Set if Wake-On-Magic-Packet is enabled on this interface
+ };
+
+typedef struct SearchListElem
+ {
+ struct SearchListElem *next;
+ domainname domain;
+ int flag; // -1 means delete, 0 means unchanged, +1 means newly added
+ DNSQuestion BrowseQ;
+ DNSQuestion DefBrowseQ;
+ DNSQuestion AutomaticBrowseQ;
+ DNSQuestion RegisterQ;
+ DNSQuestion DefRegisterQ;
+ ARListElem *AuthRecs;
+ } SearchListElem;
+
+// For domain enumeration and automatic browsing
+// This is the user's DNS search list.
+// In each of these domains we search for our special pointer records (lb._dns-sd._udp.<domain>, etc.)
+// to discover recommended domains for domain enumeration (browse, default browse, registration,
+// default registration) and possibly one or more recommended automatic browsing domains.
+extern SearchListElem *SearchList; // This really ought to be part of mDNS_struct -- SC
+
+// ***************************************************************************
+#if 0
+#pragma mark -
#pragma mark - Main mDNS object, used to hold all the mDNS state
#endif
enum
{
- mDNS_KnownBug_PhantomInterfaces = 1
+ mDNS_KnownBug_PhantomInterfaces = 1,
+ mDNS_KnownBug_LossySyslog = 2 // <rdar://problem/6561888>
+ };
+
+enum
+ {
+ SleepState_Awake = 0,
+ SleepState_Transferring = 1,
+ SleepState_Sleeping = 2
};
struct mDNS_struct
mDNSu32 KnownBugs;
mDNSBool CanReceiveUnicastOn5353;
mDNSBool AdvertiseLocalAddresses;
+ mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only
mStatus mDNSPlatformStatus;
mDNSIPPort UnicastPort4;
mDNSIPPort UnicastPort6;
+ mDNSEthAddr PrimaryMAC; // Used as unique host ID
mDNSCallback *MainCallback;
void *MainContext;
mDNSu8 lock_rrcache; // For debugging: Set at times when these lists may not be modified
mDNSu8 lock_Questions;
mDNSu8 lock_Records;
- #define MaxMsg 120
+#ifndef MaxMsg
+ #define MaxMsg 160
+#endif
char MsgBuffer[MaxMsg]; // Temp storage used while building error log messages
// Task Scheduling variables
mDNSs32 timenow; // The time that this particular activation of the mDNS code started
mDNSs32 timenow_last; // The time the last time we ran
mDNSs32 NextScheduledEvent; // Derived from values below
- mDNSs32 ShutdownTime; // Set when we're shutting down, allows us to skip some unnecessary steps
+ mDNSs32 ShutdownTime; // Set when we're shutting down; allows us to skip some unnecessary steps
mDNSs32 SuppressSending; // Don't send *any* packets during this time
mDNSs32 NextCacheCheck; // Next time to refresh cache record before it expires
mDNSs32 NextScheduledQuery; // Next time to send query in its exponential backoff sequence
mDNSs32 NextScheduledProbe; // Next time to probe for new authoritative record
mDNSs32 NextScheduledResponse; // Next time to send authoritative record(s) in responses
mDNSs32 NextScheduledNATOp; // Next time to send NAT-traversal packets
+ mDNSs32 NextScheduledSPS; // Next time to purge expiring Sleep Proxy records
mDNSs32 RandomQueryDelay; // For de-synchronization of query packets on the wire
mDNSu32 RandomReconfirmDelay; // For de-synchronization of reconfirmation queries on the wire
mDNSs32 PktNum; // Unique sequence number assigned to each received packet
- mDNSBool SendDeregistrations; // Set if we need to send deregistrations (immediately)
- mDNSBool SendImmediateAnswers; // Set if we need to send answers (immediately -- or as soon as SuppressSending clears)
- mDNSBool SleepState; // Set if we're sleeping (send no more packets)
+ mDNSu8 SleepState; // Set if we're sleeping
+ mDNSu8 SleepSeqNum; // "Epoch number" of our current period of wakefulness
+ mDNSu8 SystemWakeOnLANEnabled; // Set if we want to register with a Sleep Proxy before going to sleep
+ 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.
// These fields only required for mDNS Searcher...
DNSQuestion *Questions; // List of all registered questions, active and inactive
mDNSu32 NumFailedProbes;
mDNSs32 SuppressProbes;
- // unicast-specific data
+ // Unicast-specific data
mDNSs32 NextuDNSEvent; // uDNS next event
mDNSs32 NextSRVUpdate; // Time to perform delayed update
mDNSs32 SuppressStdPort53Queries; // Wait before allowing the next standard unicast query to the user's configured DNS server
mDNSBool RegisterSearchDomains;
- // NAT traversal fields
+ // NAT-Traversal fields
NATTraversalInfo LLQNAT; // Single shared NAT Traversal to receive inbound LLQ notifications
NATTraversalInfo *NATTraversals;
NATTraversalInfo *CurrentNATTraversal;
mDNSv4Addr ExternalAddress;
UDPSocket *NATMcastRecvskt; // For receiving NAT-PMP AddrReply multicasts from router on port 5350
- UDPSocket *NATMcastRecvsk2; // For backwards compatibility, same as above but listening on port 5351
mDNSu32 LastNATupseconds; // NAT engine uptime in seconds, from most recent NAT packet
mDNSs32 LastNATReplyLocalTime; // Local time in ticks when most recent NAT packet was received
+ mDNSu16 LastNATMapResultCode; // Most recent error code for mappings
tcpLNTInfo tcpAddrInfo; // legacy NAT traversal TCP connection info for external address
tcpLNTInfo tcpDeviceInfo; // legacy NAT traversal TCP connection info for device info
mDNSu8 *UPnPRouterAddressString; // holds both the router's address and port
mDNSu8 *UPnPSOAPAddressString; // holds both address and port for SOAP messages
+ // Sleep Proxy Server fields
+ mDNSu8 SPSType; // 0 = off, 10-99 encodes desirability metric
+ mDNSu8 SPSPortability; // 10-99
+ mDNSu8 SPSMarginalPower; // 10-99
+ mDNSu8 SPSTotalPower; // 10-99
+ mDNSu8 SPSState; // 0 = off, 1 = running, 2 = shutting down, 3 = suspended during sleep
+ mDNSInterfaceID SPSProxyListChanged;
+ UDPSocket *SPSSocket;
+ ServiceRecordSet SPSRecords;
+ mDNSQuestionCallback *SPSBrowseCallback; // So the platform layer can do something useful with SPS browse results
+ int ProxyRecords; // Total number of records we're holding as proxy
+ #define MAX_PROXY_RECORDS 10000 /* DOS protection: 400 machines at 25 records each */
+
#if APPLE_OSX_mDNSResponder
ClientTunnel *TunnelClients;
+ uuid_t asl_uuid; // uuid for ASL logging
#endif
// Fixed storage, to avoid creating large objects on the stack
- DNSMessage imsg; // Incoming message received from wire
+ // The imsg is declared as a union with a pointer type to enforce CPU-appropriate alignment
+ union { DNSMessage m; void *p; } imsg; // Incoming message received from wire
DNSMessage omsg; // Outgoing message we're building
LargeCacheRecord rec; // Resource Record extracted from received message
};
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Useful Static Constants
#endif
extern const mDNSEthAddr zeroEthAddr;
extern const mDNSv4Addr onesIPv4Addr;
extern const mDNSv6Addr onesIPv6Addr;
+extern const mDNSEthAddr onesEthAddr;
extern const mDNSAddr zeroAddr;
+extern const OwnerOptData zeroOwner;
+
extern const mDNSInterfaceID mDNSInterface_Any; // Zero
extern const mDNSInterfaceID mDNSInterface_LocalOnly; // Special value
extern const mDNSInterfaceID mDNSInterface_Unicast; // Special value
-extern const mDNSIPPort SSDPPort;
-
+extern const mDNSIPPort DiscardPort;
+extern const mDNSIPPort SSHPort;
extern const mDNSIPPort UnicastDNSPort;
+extern const mDNSIPPort SSDPPort;
+extern const mDNSIPPort NSIPCPort;
extern const mDNSIPPort NATPMPAnnouncementPort;
extern const mDNSIPPort NATPMPPort;
extern const mDNSIPPort DNSEXTPort;
extern const mDNSIPPort MulticastDNSPort;
extern const mDNSIPPort LoopbackIPCPort;
-
-extern const mDNSIPPort NSIPCPort;
extern const mDNSIPPort PrivateDNSPort;
extern const mDNSv4Addr AllDNSAdminGroup;
+extern const mDNSv4Addr AllSystemsMcast;
extern const mDNSAddr AllDNSLinkGroup_v4;
extern const mDNSAddr AllDNSLinkGroup_v6;
extern const mDNSOpaque16 zeroID;
+extern const mDNSOpaque16 onesID;
extern const mDNSOpaque16 QueryFlags;
extern const mDNSOpaque16 uQueryFlags;
extern const mDNSOpaque16 ResponseFlags;
extern const mDNSOpaque64 zeroOpaque64;
-#define localdomain (*(const domainname *)"\x5" "local")
-#define LocalReverseMapDomain (*(const domainname *)"\x3" "254" "\x3" "169" "\x7" "in-addr" "\x4" "arpa")
-#define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
+#define localdomain (*(const domainname *)"\x5" "local")
+#define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
+#define SleepProxyServiceType (*(const domainname *)"\xC" "_sleep-proxy" "\x4" "_udp")
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Inline functions
#endif
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Main Client Functions
#endif
// In principle, a proxy-like registration service could manually create address records for its own machine too,
// but this would be pointless extra effort when using mDNS_Init_AdvertiseLocalAddresses does that for you.
//
+// Note that a client-only device that wishes to prohibit multicast advertisements (e.g. from
+// higher-layer API calls) must also set DivertMulticastAdvertisements in the mDNS structure and
+// advertise local address(es) on a loopback interface.
+//
// When mDNS has finished setting up the client's callback is called
// A client can also spin and poll the mDNSPlatformStatus field to see when it changes from mStatus_Waiting to mStatus_NoError
//
#define mDNS_Init_NoInitCallback mDNSNULL
#define mDNS_Init_NoInitCallbackContext mDNSNULL
+extern void mDNS_ConfigChanged(mDNS *const m);
extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords);
extern void mDNS_StartExit (mDNS *const m);
extern void mDNS_FinalExit (mDNS *const m);
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Platform support functions that are accessible to the client layer too
#endif
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - General utility and helper functions
#endif
const mDNSInterfaceID InterfaceID, mDNSRecordCallback Callback, void *Context);
#define mDNS_DeregisterNoSuchService mDNS_Deregister
+extern void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID InterfaceID, const domainname *const name,
+ const mDNSu16 qtype, mDNSQuestionCallback *const callback, void *const context);
+
extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
const domainname *const srv, const domainname *const domain,
const mDNSInterfaceID InterfaceID, mDNSBool ForceMCast, mDNSQuestionCallback *Callback, void *Context);
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - DNS name utility functions
#endif
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 FirstLabel(X) ((const domainlabel *)(X))
+#define SecondLabel(X) ((const domainlabel *)&(X)->c[1 + (X)->c[0]])
+extern const mDNSu8 *LastLabel(const domainname *d);
+
// Get total length of domain name, in native DNS format, including terminal root label
// (e.g. length of "com." is 5 (length byte, three data bytes, final zero)
extern mDNSu16 DomainNameLengthLimit(const domainname *const name, const mDNSu8 *limit);
-#define DomainNameLength(name) DomainNameLengthLimit((name), (name)->c + MAX_DOMAIN_NAME + 1)
+#define DomainNameLength(name) DomainNameLengthLimit((name), (name)->c + MAX_DOMAIN_NAME)
// Append functions to append one or more labels to an existing native format domain name:
// AppendLiteralLabelString adds a single label from a literal C string, with no escape character interpretation.
// When using ConvertDomainLabelToCString, the target buffer must be MAX_ESCAPED_DOMAIN_LABEL (254) bytes long
// to guarantee there will be no buffer overrun. It is only safe to use a buffer shorter than this in rare cases
// where the label is known to be constrained somehow (for example, if the label is known to be either "_tcp" or "_udp").
-// Similarly, when using ConvertDomainNameToCString, the target buffer must be MAX_ESCAPED_DOMAIN_NAME (1005) bytes long.
+// Similarly, when using ConvertDomainNameToCString, the target buffer must be MAX_ESCAPED_DOMAIN_NAME (1009) bytes long.
// See definitions of MAX_ESCAPED_DOMAIN_LABEL and MAX_ESCAPED_DOMAIN_NAME for more detailed explanation.
extern char *ConvertDomainLabelToCString_withescape(const domainlabel *const name, char *cstr, char esc);
#define ConvertDomainLabelToCString_unescaped(D,C) ConvertDomainLabelToCString_withescape((D), (C), 0)
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Other utility functions and macros
#endif
extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id);
extern char *DNSTypeName(mDNSu16 rrtype);
-extern char *GetRRDisplayString_rdb(const ResourceRecord *rr, RDataBody *rd, char *buffer);
+extern char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RDataBody *const rd1, char *const buffer);
#define RRDisplayString(m, rr) GetRRDisplayString_rdb(rr, &(rr)->rdata->u, (m)->MsgBuffer)
#define ARDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer)
#define CRDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer)
#define mDNSSameIPPort(A,B) ((A).NotAnInteger == (B).NotAnInteger)
#define mDNSSameOpaque16(A,B) ((A).NotAnInteger == (B).NotAnInteger)
+#define mDNSSameOpaque32(A,B) ((A).NotAnInteger == (B).NotAnInteger)
+#define mDNSSameOpaque64(A,B) ((A)->l[0] == (B)->l[0] && (A)->l[1] == (B)->l[1])
+
#define mDNSSameIPv4Address(A,B) ((A).NotAnInteger == (B).NotAnInteger)
#define mDNSSameIPv6Address(A,B) ((A).l[0] == (B).l[0] && (A).l[1] == (B).l[1] && (A).l[2] == (B).l[2] && (A).l[3] == (B).l[3])
#define mDNSSameEthAddress(A,B) ((A)->w[0] == (B)->w[0] && (A)->w[1] == (B)->w[1] && (A)->w[2] == (B)->w[2])
-#define mDNSSameOpaque64(A,B) ((A)->l[0] == (B)->l[0] && (A)->l[1] == (B)->l[1])
-#define mDNSOpaque64IsZero(A) ((A)->l[0] == 0 && (A)->l[1] == 0)
-
-#define mDNSIPPortIsZero(A) mDNSSameIPPort((A), zeroIPPort)
-#define mDNSOpaque16IsZero(A) mDNSSameOpaque16((A), zeroIPPort)
-#define mDNSIPv4AddressIsZero(A) mDNSSameIPv4Address((A), zerov4Addr)
-#define mDNSIPv6AddressIsZero(A) mDNSSameIPv6Address((A), zerov6Addr)
+#define mDNSIPPortIsZero(A) ((A).NotAnInteger == 0)
+#define mDNSOpaque16IsZero(A) ((A).NotAnInteger == 0)
+#define mDNSOpaque64IsZero(A) (((A)->l[0] | (A)->l[1] ) == 0)
+#define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger == 0)
+#define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0)
+#define mDNSEthAddressIsZero(A) (((A).w[0] | (A).w[1] | (A).w[2] ) == 0)
-#define mDNSIPv4AddressIsOnes(A) mDNSSameIPv4Address((A), onesIPv4Addr)
-#define mDNSIPv6AddressIsOnes(A) mDNSSameIPv6Address((A), onesIPv6Addr)
+#define mDNSIPv4AddressIsOnes(A) ((A).NotAnInteger == 0xFFFFFFFF)
+#define mDNSIPv6AddressIsOnes(A) (((A).l[0] & (A).l[1] & (A).l[2] & (A).l[3]) == 0xFFFFFFFF)
#define mDNSAddressIsAllDNSLinkGroup(X) ( \
((X)->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address((X)->ip.v4, AllDNSLinkGroup_v4.ip.v4)) || \
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Authentication Support
#endif
extern mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info,
const domainname *domain, const domainname *keyname, const char *b64keydata, mDNSBool AutoTunnel);
+extern void RecreateNATMappings(mDNS *const m);
+
// Hostname/Unicast Interface Configuration
// All hostnames advertised point to one IPv4 address and/or one IPv6 address, set via SetPrimaryInterfaceInfo. Invoking this routine
extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router);
extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port);
+extern void PushDNSServerToEnd(mDNS *const m, DNSQuestion *q);
extern void mDNS_AddSearchDomain(const domainname *const domain);
// We use ((void *)0) here instead of mDNSNULL to avoid compile warnings on gcc 4.2
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - PlatformSupport interface
#endif
// Note: mDNSPlatformMemAllocate/mDNSPlatformMemFree are only required for handling oversized resource records and unicast DNS.
// If your target platform has a well-defined specialized application, and you know that all the records it uses
// are InlineCacheRDSize or less, then you can just make a simple mDNSPlatformMemAllocate() stub that always returns
-// NULL. InlineCacheRDSize is a compile-time constant, which is set by default to 64. If you need to handle records
+// NULL. InlineCacheRDSize is a compile-time constant, which is set by default to 68. If you need to handle records
// a little larger than this and you don't want to have to implement run-time allocation and freeing, then you
// can raise the value of this constant to a suitable value (at the expense of increased memory usage).
//
extern void * mDNSPlatformMemAllocate (mDNSu32 len);
#endif
extern void mDNSPlatformMemFree (void *mem);
+
+// If the platform doesn't have a strong PRNG, we define a naive multiply-and-add based on a seed
+// from the platform layer. Long-term, we should embed an arc4 implementation, but the strength
+// will still depend on the randomness of the seed.
+#if !defined(_PLATFORM_HAS_STRONG_PRNG_) && (_BUILDING_XCODE_PROJECT_ || defined(_WIN32))
+#define _PLATFORM_HAS_STRONG_PRNG_ 1
+#endif
+#if _PLATFORM_HAS_STRONG_PRNG_
+extern mDNSu32 mDNSPlatformRandomNumber(void);
+#else
extern mDNSu32 mDNSPlatformRandomSeed (void);
+#endif // _PLATFORM_HAS_STRONG_PRNG_
+
extern mStatus mDNSPlatformTimeInit (void);
extern mDNSs32 mDNSPlatformRawTime (void);
extern mDNSs32 mDNSPlatformUTC (void);
#if MDNS_DEBUGMSGS
extern void mDNSPlatformWriteDebugMsg(const char *msg);
#endif
-extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, int flags);
+extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel);
+
+#if APPLE_OSX_mDNSResponder
+// Utility function for ASL logging
+mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *result, const char *signature, const char *fmt, ...);
+#endif
// Platform support modules should provide the following functions to map between opaque interface IDs
// and interface indexes in order to support the DNS-SD API. If your target platform does not support
extern long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len);
extern UDPSocket *mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport);
extern void mDNSPlatformUDPClose(UDPSocket *sock);
+extern void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd);
+extern void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID);
+extern void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID);
+extern void mDNSPlatformSetLocalARP(const mDNSv4Addr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
extern void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst);
// mDNSPlatformTLSSetupCerts/mDNSPlatformTLSTearDownCerts used by dnsextd
extern mStatus LNT_GetExternalAddress(mDNS *m);
extern mStatus LNT_MapPort(mDNS *m, NATTraversalInfo *n);
extern mStatus LNT_UnmapPort(mDNS *m, NATTraversalInfo *n);
+extern void LNT_ClearState(mDNS *const m);
#endif // _LEGACY_NAT_TRAVERSAL_
// The core mDNS code provides these functions, for the platform support code to call at appropriate times
// not lightweight second-by-second CPU power management modes.)
extern void mDNS_SetFQDN(mDNS *const m);
+extern void mDNS_ActivateNetWake_internal (mDNS *const m, NetworkInterfaceInfo *set);
+extern void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set);
extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
extern void mDNSCoreInitComplete(mDNS *const m, mStatus result);
extern void mDNSCoreReceive(mDNS *const m, void *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
const mDNSAddr *const dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID);
+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 mDNSs32 mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now);
+
+extern void mDNSCoreBeSleepProxyServer(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower);
+extern void mDNSCoreReceiveRawPacket (mDNS *const m, const mDNSu8 *const p, const mDNSu8 *const end, const mDNSInterfaceID InterfaceID);
extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip);
extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg);
extern void GrantCacheExtensions(mDNS *const m, DNSQuestion *q, mDNSu32 lease);
-extern void MakeNegativeCacheRecord(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds);
+extern void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
+ const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds, mDNSInterfaceID InterfaceID);
extern void CompleteDeregistration(mDNS *const m, AuthRecord *rr);
+extern void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3]);
+#define PrototypeSPSName(X) ((X)[0] >= 11 && (X)[3] == '-' && (X)[ 4] == '9' && (X)[ 5] == '9' && \
+ (X)[6] == '-' && (X)[ 7] == '9' && (X)[ 8] == '9' && \
+ (X)[9] == '-' && (X)[10] == '9' && (X)[11] == '9' )
+#define ValidSPSName(X) ((X)[0] >= 5 && mDNSIsDigit((X)[1]) && mDNSIsDigit((X)[2]) && mDNSIsDigit((X)[4]) && mDNSIsDigit((X)[5]))
+#define SPSMetric(X) (!ValidSPSName(X) || PrototypeSPSName(X) ? 1000000 : \
+ ((X)[1]-'0') * 100000 + ((X)[2]-'0') * 10000 + ((X)[4]-'0') * 1000 + ((X)[5]-'0') * 100 + ((X)[7]-'0') * 10 + ((X)[8]-'0'))
extern void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord);
// For now this AutoTunnel stuff is specific to Mac OS X.
// ***************************************************************************
#if 0
+#pragma mark -
#pragma mark - Compile-Time assertion checks
#endif
char assert9[(sizeof(mDNSOpaque16) == 2 ) ? 1 : -1];
char assertA[(sizeof(mDNSOpaque32) == 4 ) ? 1 : -1];
char assertB[(sizeof(mDNSOpaque128) == 16 ) ? 1 : -1];
- char assertC[(sizeof(CacheRecord ) >= sizeof(CacheGroup) ) ? 1 : -1];
+ char assertC[(sizeof(CacheRecord ) == sizeof(CacheGroup) ) ? 1 : -1];
char assertD[(sizeof(int) >= 4 ) ? 1 : -1];
char assertE[(StandardAuthRDSize >= 256 ) ? 1 : -1];
+ char assertF[(sizeof(EthernetHeader) == 14 ) ? 1 : -1];
+ char assertG[(sizeof(ARP_EthIP ) == 28 ) ? 1 : -1];
+ char assertH[(sizeof(IPv4Header ) == 20 ) ? 1 : -1];
+ char assertI[(sizeof(IPv6Header ) == 40 ) ? 1 : -1];
+ char assertJ[(sizeof(IPv6ND ) == 24 ) ? 1 : -1];
+ char assertK[(sizeof(UDPHeader ) == 8 ) ? 1 : -1];
+ char assertL[(sizeof(TCPHeader ) == 20 ) ? 1 : -1];
// 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_RDataBody [(sizeof(RDataBody) == 264) ? 1 : -1];
char sizecheck_ResourceRecord [(sizeof(ResourceRecord) <= 56) ? 1 : -1];
- char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1416) ? 1 : -1];
- char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 200) ? 1 : -1];
- char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 184) ? 1 : -1];
- char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 720) ? 1 : -1];
- char sizecheck_ZoneData [(sizeof(ZoneData) <= 1552) ? 1 : -1];
+ char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1000) ? 1 : -1];
+ char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 176) ? 1 : -1];
+ char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 176) ? 1 : -1];
+ char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 728) ? 1 : -1];
+ char sizecheck_ZoneData [(sizeof(ZoneData) <= 1560) ? 1 : -1];
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 192) ? 1 : -1];
- char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3304) ? 1 : -1];
+ char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 2800) ? 1 : -1];
char sizecheck_DNSServer [(sizeof(DNSServer) <= 312) ? 1 : -1];
- char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 4392) ? 1 : -1];
- char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 6248) ? 1 : -1];
- char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 6544) ? 1 : -1];
- char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 2912) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 5968) ? 1 : -1];
+ char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5500) ? 1 : -1];
+ char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 5500) ? 1 : -1];
+ char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 2944) ? 1 : -1];
#if APPLE_OSX_mDNSResponder
- char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1064) ? 1 : -1];
+ char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1072) ? 1 : -1];
#endif
};
Change History (most recent first):
$Log: uDNS.c,v $
-Revision 1.553.2.4 2008/07/29 20:47:44 mcguire
-<rdar://problem/6090007> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-merge r1.567 & r1.568 from <rdar://problem/3988320>
+Revision 1.617 2009/06/30 20:51:02 cheshire
+Improved "Error! Tried to add a NAT traversal that's already in the active list" debugging message
-Revision 1.553.2.3 2008/07/29 19:09:21 mcguire
-<rdar://problem/6090041> Use all configured DNS servers
-merge r1.558-r1.565 from <rdar://problem/4206534>
+Revision 1.616 2009/05/27 20:29:36 cheshire
+<rdar://problem/6926465> Sleep is delayed by 10 seconds if BTMM is on
+After receiving confirmation of LLQ deletion, need to schedule another evaluation of whether we're ready to sleep yet
-Revision 1.553.2.2 2008/07/29 18:50:09 mcguire
-<rdar://problem/6090002> LLQ refresh randomization not working properly
-merge r1.555 & r1.556 from <rdar://problem/5787898>
+Revision 1.615 2009/05/05 01:32:50 jessic2
+<rdar://problem/6830541> regservice_callback: instance->request is NULL 0 -- Clean up spurious logs resulting from fixing this bug.
-Revision 1.553.2.1 2008/03/14 20:11:25 mcguire
+Revision 1.614 2009/04/24 02:17:57 mcguire
+<rdar://problem/5264124> uDNS: Not always respecting preference order of DNS servers
+
+Revision 1.613 2009/04/23 22:06:29 cheshire
+Added CacheRecord and InterfaceID parameters to MakeNegativeCacheRecord, in preparation for:
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+
+Revision 1.612 2009/04/22 01:19:57 jessic2
+<rdar://problem/6814585> Daemon: mDNSResponder is logging garbage for error codes because it's using %ld for int 32
+
+Revision 1.611 2009/04/15 20:42:51 mcguire
+<rdar://problem/6768947> uDNS: Treat RCODE 5 (Refused) responses as failures
+
+Revision 1.610 2009/04/15 01:10:39 jessic2
+<rdar://problem/6466541> BTMM: Add support for setting kDNSServiceErr_NoSuchRecord in DynamicStore
+
+Revision 1.609 2009/04/11 00:19:45 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.608 2009/04/06 23:44:59 cheshire
+<rdar://problem/6757838> mDNSResponder thrashing kernel lock in the UDP close path, hurting SPECweb performance
+
+Revision 1.607 2009/04/02 22:36:34 jessic2
+Fix crash when calling debugf with null opt
+
+Revision 1.606 2009/03/26 03:59:00 jessic2
+Changes for <rdar://problem/6492552&6492593&6492609&6492613&6492628&6492640&6492699>
+
+Revision 1.605 2009/03/04 00:40:14 cheshire
+Updated DNS server error codes to be more consistent with definitions at
+<http://www.iana.org/assignments/dns-parameters>
+
+Revision 1.604 2009/02/27 03:08:47 cheshire
+<rdar://problem/6547720> Crash while shutting down when "local" is in the user's DNS searchlist
+
+Revision 1.603 2009/02/27 02:56:57 cheshire
+Moved struct SearchListElem definition from uDNS.c into mDNSEmbeddedAPI.h
+
+Revision 1.602 2009/02/13 06:29:54 cheshire
+Converted LogOperation messages to LogInfo
+
+Revision 1.601 2009/02/12 20:57:25 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.600 2009/01/31 21:05:12 cheshire
+Improved "Failed to obtain NAT port mapping" debugging log message
+
+Revision 1.599 2009/01/23 00:38:36 mcguire
+<rdar://problem/5570906> BTMM: Doesn't work with Linksys WRT54GS firmware 4.71.1
+
+Revision 1.598 2009/01/21 03:43:57 mcguire
+<rdar://problem/6511765> BTMM: Add support for setting kDNSServiceErr_NATPortMappingDisabled in DynamicStore
+
+Revision 1.597 2009/01/10 01:55:49 cheshire
+Added LogOperation message showing when domains are added and removed in FoundDomain
+
+Revision 1.596 2008/12/19 20:23:33 mcguire
+<rdar://problem/6459269> Lots of duplicate log messages about failure to bind to NAT-PMP Announcement port
+
+Revision 1.595 2008/12/18 23:32:19 mcguire
+<rdar://problem/6019470> BTMM: Include the question in the LLQ notification acknowledgment
+
+Revision 1.594 2008/12/10 02:25:31 cheshire
+Minor fixes to use of LogClientOperations symbol
+
+Revision 1.593 2008/12/10 02:11:42 cheshire
+ARMv5 compiler doesn't like uncommented stuff after #endif
+
+Revision 1.592 2008/12/06 01:42:55 mcguire
+<rdar://problem/6418958> Need to exponentially back-off after failure to get public address
+
+Revision 1.591 2008/12/06 00:17:11 cheshire
+<rdar://problem/6380477> mDNS_StopNATOperation doesn't handle duplicate NAT mapping requests properly
+Refinement: For duplicate ssh mappings we want to suppress the syslog warning message, but not the "unmap = mDNSfalse"
+
+Revision 1.590 2008/12/04 20:57:36 mcguire
+fix build
+
+Revision 1.589 2008/12/04 02:24:09 cheshire
+Improved NAT-PMP debugging messages
+
+Revision 1.588 2008/11/26 20:38:08 cheshire
+Changed some "LogOperation" debugging messages to "debugf"
+
+Revision 1.587 2008/11/26 19:53:26 cheshire
+Don't overwrite srs->NATinfo.IntPort in StartSRVNatMap()
+
+Revision 1.586 2008/11/25 23:43:07 cheshire
+<rdar://problem/5745355> Crashes at ServiceRegistrationGotZoneData + 397
+Made code more defensive to guard against ServiceRegistrationGotZoneData being called with invalid ServiceRecordSet object
+
+Revision 1.585 2008/11/25 22:46:30 cheshire
+For ease of code searching, renamed ZoneData field of ServiceRecordSet_struct from "nta" to "srs_nta"
+
+Revision 1.584 2008/11/24 19:46:40 cheshire
+When sending query over TCP, don't include LLQ option when we're talking to a conventional DNS server or cache
+
+Revision 1.583 2008/11/21 00:34:58 cheshire
+<rdar://problem/6380477> mDNS_StopNATOperation doesn't handle duplicate NAT mapping requests properly
+
+Revision 1.582 2008/11/20 02:23:37 mcguire
+<rdar://problem/6041208> need to handle URLBase
+
+Revision 1.581 2008/11/20 01:51:19 cheshire
+Exported RecreateNATMappings so it's callable from other files
+
+Revision 1.580 2008/11/13 19:08:45 cheshire
+Fixed code to handle rdataOPT properly
+
+Revision 1.579 2008/11/07 00:18:01 mcguire
+<rdar://problem/6351068> uDNS: Supress reverse DNS query until required
+
+Revision 1.578 2008/11/04 22:21:46 cheshire
+Changed zone field of AuthRecord_struct from domainname to pointer, saving 252 bytes per AuthRecord
+
+Revision 1.577 2008/10/29 21:37:01 cheshire
+Removed some old debugging messages
+
+Revision 1.576 2008/10/23 22:25:57 cheshire
+Renamed field "id" to more descriptive "updateid"
+
+Revision 1.575 2008/10/20 02:07:49 mkrochma
+<rdar://problem/6296804> Remove Note: DNS Server <ip> for domain <d> registered more than once
+
+Revision 1.574 2008/10/14 19:06:45 cheshire
+In uDNS_ReceiveMsg(), only do checkUpdateResult() for uDNS records
+
+Revision 1.573 2008/09/25 20:43:44 cheshire
+<rdar://problem/6245044> Stop using separate m->ServiceRegistrations list
+In UpdateSRVRecords, call mDNS_SetFQDN(m) to update AutoTarget SRV records on the main m->ResourceRecords list
+
+Revision 1.572 2008/09/24 23:48:05 cheshire
+Don't need to pass whole ServiceRecordSet reference to GetServiceTarget;
+it only needs to access the embedded SRV member of the set
+
+Revision 1.571 2008/09/23 22:56:53 cheshire
+<rdar://problem/5298845> Remove dnsbugtest query
+
+Revision 1.570 2008/09/23 01:30:18 cheshire
+The putLLQ() routine was not setting the OPT record's rrclass to NormalMaxDNSMessageData
+
+Revision 1.569 2008/07/25 22:34:11 mcguire
+fix sizecheck issues for 64bit
+
+Revision 1.568 2008/07/24 20:23:03 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+
+Revision 1.567 2008/07/01 01:40:00 mcguire
+<rdar://problem/5823010> 64-bit fixes
+
+Revision 1.566 2008/06/26 17:24:11 mkrochma
+<rdar://problem/5450912> BTMM: Stop listening on UDP 5351 for NAT Status Announcements
+
+Revision 1.565 2008/06/21 19:06:58 mcguire
+<rdar://problem/4206534> Use all configured DNS servers
+
+Revision 1.564 2008/06/19 23:42:03 mcguire
+<rdar://problem/4206534> Use all configured DNS servers
+
+Revision 1.563 2008/06/19 17:46:14 mcguire
+<rdar://problem/4206534> Use all configured DNS servers
+Don't do extra work for log messages if we're not going to log
+
+Revision 1.562 2008/06/19 17:35:19 mcguire
+<rdar://problem/4206534> Use all configured DNS servers
+cleanup log messages
+check for null pointers
+
+Revision 1.561 2008/06/19 01:20:49 mcguire
+<rdar://problem/4206534> Use all configured DNS servers
+
+Revision 1.560 2008/05/31 01:51:09 mcguire
+fixed typo in log message
+
+Revision 1.559 2008/04/15 22:37:58 mkrochma
+Change LogMsg to LogOperation
+
+Revision 1.558 2008/03/17 18:02:35 mkrochma
+Add space to log message for consistency
+
+Revision 1.557 2008/03/14 19:58:38 mcguire
<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
Make sure we add the record when sending LLQ refreshes
+Revision 1.556 2008/03/07 23:55:05 cheshire
+<rdar://problem/5787898> LLQ refresh randomization not working properly
+
+Revision 1.555 2008/03/07 23:25:56 cheshire
+Improved debugging messages
+
+Revision 1.554 2008/03/07 18:56:03 cheshire
+<rdar://problem/5777647> dnsbugtest query every three seconds when source IP address of response doesn't match
+
Revision 1.553 2008/03/06 02:48:34 mcguire
<rdar://problem/5321824> write status to the DS
Revision 1.457 2007/09/05 21:48:01 cheshire
<rdar://problem/5385864> BTMM: mDNSResponder flushes wide-area Bonjour records after an hour for a zone.
-Now that we're respecting the TTL of uDNS records in the cache, the LLQ maintenance cod needs
+Now that we're respecting the TTL of uDNS records in the cache, the LLQ maintenance code needs
to update the cache lifetimes of all relevant records every time it successfully renews an LLQ,
otherwise those records will expire and vanish from the cache.
#pragma warning(disable:4706)
#endif
-typedef struct SearchListElem
- {
- struct SearchListElem *next;
- domainname domain;
- int flag; // -1 means delete, 0 means unchanged, +1 means newly added
- DNSQuestion BrowseQ;
- DNSQuestion DefBrowseQ;
- DNSQuestion AutomaticBrowseQ;
- DNSQuestion RegisterQ;
- DNSQuestion DefRegisterQ;
- ARListElem *AuthRecs;
- } SearchListElem;
-
// For domain enumeration and automatic browsing
// This is the user's DNS search list.
// In each of these domains we search for our special pointer records (lb._dns-sd._udp.<domain>, etc.)
// to discover recommended domains for domain enumeration (browse, default browse, registration,
// default registration) and possibly one or more recommended automatic browsing domains.
-static SearchListElem *SearchList = mDNSNULL;
+mDNSexport SearchListElem *SearchList = mDNSNULL;
// Temporary workaround to make ServiceRecordSet list management safe.
// Ideally a ServiceRecordSet shouldn't be a special entity that's given special treatment by the uDNS code
// Code for stress-testing registration renewal code
if (rr->expire && rr->expire - m->timenow > mDNSPlatformOneSecond * 120)
{
- LogOperation("Adjusting expiry from %d to 120 seconds for %s",
+ LogInfo("Adjusting expiry from %d to 120 seconds for %s",
(rr->expire - m->timenow) / mDNSPlatformOneSecond, ARDisplayString(m, rr));
rr->expire = m->timenow + mDNSPlatformOneSecond * 120;
}
{
mDNSs32 remaining = rr->expire - m->timenow;
rr->ThisAPInterval = remaining/2 + mDNSRandom(remaining/10);
- LogOperation("SetRecordRetry refresh in %4d of %4d for %s",
- rr->ThisAPInterval / mDNSPlatformOneSecond,
- (rr->expire - m->timenow) / mDNSPlatformOneSecond,
- ARDisplayString(m, rr));
+ debugf("SetRecordRetry refresh in %4d of %4d for %s",
+ rr->ThisAPInterval / mDNSPlatformOneSecond, (rr->expire - m->timenow) / mDNSPlatformOneSecond, ARDisplayString(m, rr));
return;
}
if (rr->ThisAPInterval > 30 * 60 * mDNSPlatformOneSecond)
rr->ThisAPInterval = 30 * 60 * mDNSPlatformOneSecond;
- LogOperation("SetRecordRetry retry in %4d for %s", rr->ThisAPInterval / mDNSPlatformOneSecond, ARDisplayString(m, rr));
+ LogInfo("SetRecordRetry retry in %4d for %s", rr->ThisAPInterval / mDNSPlatformOneSecond, ARDisplayString(m, rr));
}
// ***************************************************************************
mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port)
{
DNSServer **p = &m->DNSServers;
-
+ DNSServer *tmp = mDNSNULL;
+
if (!d) d = (const domainname *)"";
- LogOperation("mDNS_AddDNSServer: Adding %#a for %##s", addr, d->c);
+ LogInfo("mDNS_AddDNSServer: Adding %#a for %##s", addr, d->c);
if (m->mDNS_busy != m->mDNS_reentrancy+1)
LogMsg("mDNS_AddDNSServer: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
- while (*p) // Check if we already have this {server,domain} pair registered
+ while (*p) // Check if we already have this {interface,address,port,domain} tuple registered
{
if ((*p)->interface == interface && (*p)->teststate != DNSServer_Disabled &&
mDNSSameAddress(&(*p)->addr, addr) && mDNSSameIPPort((*p)->port, port) && SameDomainName(&(*p)->domain, d))
{
- if (!((*p)->flags & DNSServer_FlagDelete)) LogMsg("Note: DNS Server %#a for domain %##s registered more than once", addr, d->c);
+ if (!((*p)->flags & DNSServer_FlagDelete)) debugf("Note: DNS Server %#a:%d for domain %##s (%p) registered more than once", addr, mDNSVal16(port), d->c, interface);
(*p)->flags &= ~DNSServer_FlagDelete;
- return(*p);
+ tmp = *p;
+ *p = tmp->next;
+ tmp->next = mDNSNULL;
}
- p=&(*p)->next;
+ else
+ p=&(*p)->next;
}
- // allocate, add to list
- *p = mDNSPlatformMemAllocate(sizeof(**p));
- if (!*p) LogMsg("Error: mDNS_AddDNSServer - malloc");
+ if (tmp) *p = tmp; // move to end of list, to ensure ordering from platform layer
else
{
- (*p)->interface = interface;
- (*p)->addr = *addr;
- (*p)->port = port;
- (*p)->flags = DNSServer_FlagNew;
- (*p)->teststate = DNSServer_Untested;
- (*p)->lasttest = m->timenow - INIT_UCAST_POLL_INTERVAL;
- AssignDomainName(&(*p)->domain, d);
- (*p)->next = mDNSNULL;
+ // allocate, add to list
+ *p = mDNSPlatformMemAllocate(sizeof(**p));
+ if (!*p) LogMsg("Error: mDNS_AddDNSServer - malloc");
+ else
+ {
+ (*p)->interface = interface;
+ (*p)->addr = *addr;
+ (*p)->port = port;
+ (*p)->flags = DNSServer_FlagNew;
+ (*p)->teststate = /* DNSServer_Untested */ DNSServer_Passed;
+ (*p)->lasttest = m->timenow - INIT_UCAST_POLL_INTERVAL;
+ AssignDomainName(&(*p)->domain, d);
+ (*p)->next = mDNSNULL;
+ }
}
return(*p);
}
-mDNSlocal void PushDNSServerToEnd(mDNS *const m, DNSQuestion *q)
+mDNSexport void PushDNSServerToEnd(mDNS *const m, DNSQuestion *q)
{
+ DNSServer *orig = q->qDNSServer;
DNSServer **p = &m->DNSServers;
if (m->mDNS_busy != m->mDNS_reentrancy+1)
if (!q->qDNSServer)
{
LogMsg("PushDNSServerToEnd: Null DNS server for %##s (%s) %d", q->qname.c, DNSTypeName(q->qtype), q->unansweredQueries);
- return;
+ goto end;
}
- LogOperation("PushDNSServerToEnd: Pushing DNS server %#a:%d (%##s) due to %d unanswered queries for %##s (%s)", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qDNSServer->domain.c, q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("PushDNSServerToEnd: Pushing DNS server %#a:%d (%##s) due to %d unanswered queries for %##s (%s)",
+ &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qDNSServer->domain.c, q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype));
while (*p)
{
}
*p = q->qDNSServer;
- q->qDNSServer->next = mDNSNULL;
+ q->qDNSServer->next = mDNSNULL;
+
+end:
+ q->qDNSServer = GetServerForName(m, &q->qname);
+
+ if (q->qDNSServer != orig)
+ {
+ if (q->qDNSServer) LogInfo("PushDNSServerToEnd: Server for %##s (%s) changed to %#a:%d (%##s)", q->qname.c, DNSTypeName(q->qtype), &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qDNSServer->domain.c);
+ else LogInfo("PushDNSServerToEnd: Server for %##s (%s) changed to <null>", q->qname.c, DNSTypeName(q->qtype));
+ q->ThisQInterval = q->ThisQInterval / QuestionIntervalStep; // Decrease interval one step so we don't quickly bounce between servers for queries that will not be answered.
+ }
}
// ***************************************************************************
}
n = (const domainname *)(n->c + 1 + n->c[0]);
}
- //LogOperation("GetAuthInfoForName none found for %##s", name->c);
+ //LogInfo("GetAuthInfoForName none found for %##s", name->c);
return mDNSNULL;
}
{
DNSQuestion *q;
DomainAuthInfo *info = *p;
- LogOperation("GetAuthInfoForName_internal deleting expired key %##s %##s", info->domain.c, info->keyname.c);
+ LogInfo("GetAuthInfoForName_internal deleting expired key %##s %##s", info->domain.c, info->keyname.c);
*p = info->next; // Cut DomainAuthInfo from list *before* scanning our question list updating AuthInfo pointers
for (q = m->Questions; q; q=q->next)
if (q->AuthInfo == info)
DomainAuthInfo **p = &m->AuthInfoList;
if (!info || !b64keydata) { LogMsg("mDNS_SetSecretForDomain: ERROR: info %p b64keydata %p", info, b64keydata); return(mStatus_BadParamErr); }
- LogOperation("mDNS_SetSecretForDomain: domain %##s key %##s%s", domain->c, keyname->c, AutoTunnel ? " AutoTunnel" : "");
+ LogInfo("mDNS_SetSecretForDomain: domain %##s key %##s%s", domain->c, keyname->c, AutoTunnel ? " AutoTunnel" : "");
info->AutoTunnel = AutoTunnel;
AssignDomainName(&info->domain, domain);
if (DNSDigest_ConstructHMACKeyfromBase64(info, b64keydata) < 0)
{
- LogMsg("mDNS_SetSecretForDomain: ERROR: Could not convert shared secret from base64: domain %##s key %##s %s",
- domain->c, keyname->c, LogAllOperations ? b64keydata : "");
+ LogMsg("mDNS_SetSecretForDomain: ERROR: Could not convert shared secret from base64: domain %##s key %##s %s", domain->c, keyname->c, mDNS_LoggingEnabled ? b64keydata : "");
return(mStatus_BadParamErr);
}
err = mDNSPlatformSendUDP(m, (mDNSu8 *)&u, end, 0, mDNSNULL, &m->Router, NATPMPPort);
#ifdef _LEGACY_NAT_TRAVERSAL_
- if (mDNSIPPortIsZero(m->UPnPSOAPPort)) LNT_SendDiscoveryMsg(m);
+ if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort)) LNT_SendDiscoveryMsg(m);
else if (info) err = LNT_MapPort(m, info);
else err = LNT_GetExternalAddress(m);
#endif // _LEGACY_NAT_TRAVERSAL_
return(err);
}
-mDNSlocal void RecreateNATMappings(mDNS *const m)
+mDNSexport void RecreateNATMappings(mDNS *const m)
{
NATTraversalInfo *n;
for (n = m->NATTraversals; n; n=n->next)
m->NextScheduledNATOp = m->timenow; // Need to send packets immediately
}
-#ifdef _LEGACY_NAT_TRAVERSAL_
-mDNSlocal void ClearUPnPState(mDNS *const m)
- {
- if (m->tcpAddrInfo.sock) { mDNSPlatformTCPCloseConnection(m->tcpAddrInfo.sock); m->tcpAddrInfo.sock = mDNSNULL; }
- if (m->tcpDeviceInfo.sock) { mDNSPlatformTCPCloseConnection(m->tcpDeviceInfo.sock); m->tcpDeviceInfo.sock = mDNSNULL; }
- m->UPnPSOAPPort = m->UPnPRouterPort = zeroIPPort; // Reset UPnP ports
- }
-#else
-#define ClearUPnPState(X)
-#endif // _LEGACY_NAT_TRAVERSAL_
-
mDNSexport void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr)
{
- static mDNSu16 last_err;
+ static mDNSu16 last_err = 0;
+
if (err)
{
if (err != last_err) LogMsg("Error getting external address %d", err);
+ ExtAddr = zerov4Addr;
}
- else if (!mDNSSameIPv4Address(m->ExternalAddress, ExtAddr))
+ else
{
- LogOperation("Received external IP address %.4a from NAT", &ExtAddr);
+ LogInfo("Received external IP address %.4a from NAT", &ExtAddr);
if (mDNSv4AddrIsRFC1918(&ExtAddr))
LogMsg("Double NAT (external NAT gateway address %.4a is also a private RFC 1918 address)", &ExtAddr);
+ if (mDNSIPv4AddressIsZero(ExtAddr))
+ err = NATErr_NetFail; // fake error to handle routers that pathologically report success with the zero address
+ }
+
+ if (!mDNSSameIPv4Address(m->ExternalAddress, ExtAddr))
+ {
m->ExternalAddress = ExtAddr;
RecreateNATMappings(m); // Also sets NextScheduledNATOp for us
}
- if (err || mDNSIPv4AddressIsZero(ExtAddr)) m->retryIntervalGetAddr = NATMAP_INIT_RETRY * 32; // 8 seconds
- else m->retryIntervalGetAddr = NATMAP_MAX_RETRY_INTERVAL;
+ if (!err) // Success, back-off to maximum interval
+ m->retryIntervalGetAddr = NATMAP_MAX_RETRY_INTERVAL;
+ else if (!last_err) // Failure after success, retry quickly (then back-off exponentially)
+ m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
+ // else back-off normally in case of pathological failures
m->retryGetAddr = m->timenow + m->retryIntervalGetAddr;
if (m->NextScheduledNATOp - m->retryIntervalGetAddr > 0)
// Note: When called from handleLNTPortMappingResponse() only pkt->err, pkt->extport and pkt->NATRep_lease fields are filled in
mDNSexport void natTraversalHandlePortMapReply(mDNS *const m, NATTraversalInfo *n, const mDNSInterfaceID InterfaceID, mDNSu16 err, mDNSIPPort extport, mDNSu32 lease)
{
+ const char *prot = n->Protocol == NATOp_MapUDP ? "UDP" : n->Protocol == NATOp_MapTCP ? "TCP" : "?";
+ (void)prot;
n->NewResult = err;
if (err || lease == 0 || mDNSIPPortIsZero(extport))
{
- LogOperation("natTraversalHandlePortMapReply: received error making port mapping error %d port %d", err, mDNSVal16(extport));
+ LogInfo("natTraversalHandlePortMapReply: %p Response %s Port %5d External Port %5d lease %d error %d",
+ n, prot, mDNSVal16(n->IntPort), mDNSVal16(extport), lease, err);
n->retryInterval = NATMAP_MAX_RETRY_INTERVAL;
n->retryPortMap = m->timenow + NATMAP_MAX_RETRY_INTERVAL;
// No need to set m->NextScheduledNATOp here, since we're only ever extending the m->retryPortMap time
n->ExpiryTime = NonZeroTime(m->timenow + lease * mDNSPlatformOneSecond);
if (!mDNSSameIPPort(n->RequestedPort, extport))
- LogOperation("natTraversalHandlePortMapReply: public port changed from %d to %d", mDNSVal16(n->RequestedPort), mDNSVal16(extport));
+ LogInfo("natTraversalHandlePortMapReply: %p Response %s Port %5d External Port %5d changed to %5d",
+ n, prot, mDNSVal16(n->IntPort), mDNSVal16(n->RequestedPort), mDNSVal16(extport));
n->InterfaceID = InterfaceID;
n->RequestedPort = extport;
- LogOperation("natTraversalHandlePortMapReply %p %s Internal Port %d External Port %d", n,
- n->Protocol == NATOp_MapUDP ? "UDP Response" :
- n->Protocol == NATOp_MapTCP ? "TCP Response" : "?", mDNSVal16(n->IntPort), mDNSVal16(n->RequestedPort));
+ LogInfo("natTraversalHandlePortMapReply: %p Response %s Port %5d External Port %5d lease %d",
+ n, prot, mDNSVal16(n->IntPort), mDNSVal16(extport), lease);
NATSetNextRenewalTime(m, n); // Got our port mapping; now set timer to renew it at halfway point
m->NextScheduledNATOp = m->timenow; // May need to invoke client callback immediately
{
NATTraversalInfo **n;
- LogOperation("mDNS_StartNATOperation_internal %d %d %d %d",
+ LogInfo("mDNS_StartNATOperation_internal Protocol %d IntPort %d RequestedPort %d NATLease %d",
traversal->Protocol, mDNSVal16(traversal->IntPort), mDNSVal16(traversal->RequestedPort), traversal->NATLease);
// Note: It important that new traversal requests are appended at the *end* of the list, not prepended at the start
- n = &m->NATTraversals;
- while (*n && *n != traversal) n=&(*n)->next;
- if (*n) { LogMsg("Error! Tried to add a NAT traversal that's already in the active list"); return(mStatus_AlreadyRegistered); }
+ for (n = &m->NATTraversals; *n; n=&(*n)->next)
+ {
+ if (traversal == *n)
+ {
+ LogMsg("Error! Tried to add a NAT traversal that's already in the active list: request %p Prot %d Int %d TTL %d",
+ traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease);
+ return(mStatus_AlreadyRegistered);
+ }
+ if (traversal->Protocol && traversal->Protocol == (*n)->Protocol && mDNSSameIPPort(traversal->IntPort, (*n)->IntPort) &&
+ !mDNSSameIPPort(traversal->IntPort, SSHPort))
+ LogMsg("Warning: Created port mapping request %p Prot %d Int %d TTL %d "
+ "duplicates existing port mapping request %p Prot %d Int %d TTL %d",
+ traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease,
+ *n, (*n) ->Protocol, mDNSVal16((*n) ->IntPort), (*n) ->NATLease);
+ }
// Initialize necessary fields
traversal->next = mDNSNULL;
#ifdef _LEGACY_NAT_TRAVERSAL_
mDNSPlatformMemZero(&traversal->tcpInfo, sizeof(traversal->tcpInfo));
-#endif _LEGACY_NAT_TRAVERSAL_
+#endif // _LEGACY_NAT_TRAVERSAL_
if (!m->NATTraversals) // If this is our first NAT request, kick off an address request too
{
// Must be called with the mDNS_Lock held
mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *traversal)
{
+ mDNSBool unmap = mDNStrue;
+ NATTraversalInfo *p;
NATTraversalInfo **ptr = &m->NATTraversals;
-
+
while (*ptr && *ptr != traversal) ptr=&(*ptr)->next;
if (*ptr) *ptr = (*ptr)->next; // If we found it, cut this NATTraversalInfo struct from our list
else
return(mStatus_BadReferenceErr);
}
- LogOperation("mDNS_StopNATOperation_internal %d %d %d %d",
+ LogInfo("mDNS_StopNATOperation_internal %d %d %d %d",
traversal->Protocol, mDNSVal16(traversal->IntPort), mDNSVal16(traversal->RequestedPort), traversal->NATLease);
if (m->CurrentNATTraversal == traversal)
m->CurrentNATTraversal = m->CurrentNATTraversal->next;
- if (traversal->ExpiryTime)
+ if (traversal->Protocol)
+ for (p = m->NATTraversals; p; p=p->next)
+ if (traversal->Protocol == p->Protocol && mDNSSameIPPort(traversal->IntPort, p->IntPort))
+ {
+ if (!mDNSSameIPPort(traversal->IntPort, SSHPort))
+ LogMsg("Warning: Removed port mapping request %p Prot %d Int %d TTL %d "
+ "duplicates existing port mapping request %p Prot %d Int %d TTL %d",
+ traversal, traversal->Protocol, mDNSVal16(traversal->IntPort), traversal->NATLease,
+ p, p ->Protocol, mDNSVal16(p ->IntPort), p ->NATLease);
+ unmap = mDNSfalse;
+ }
+
+ if (traversal->ExpiryTime && unmap)
{
traversal->NATLease = 0;
traversal->retryInterval = 0;
uDNS_SendNATMsg(m, traversal);
}
+
// Even if we DIDN'T make a successful UPnP mapping yet, we might still have a partially-open TCP connection we need to clean up
#ifdef _LEGACY_NAT_TRAVERSAL_
{
mStatus err = LNT_UnmapPort(m, traversal);
- if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %ld", err);
+ if (err) LogMsg("Legacy NAT Traversal - unmap request failed with error %d", err);
}
#endif // _LEGACY_NAT_TRAVERSAL_
+
return(mStatus_NoError);
}
// Lock must be held -- otherwise m->timenow is undefined
mDNSlocal void StartLLQPolling(mDNS *const m, DNSQuestion *q)
{
- LogOperation("StartLLQPolling: %##s", q->qname.c);
+ debugf("StartLLQPolling: %##s", q->qname.c);
q->state = LLQ_Poll;
q->ThisQInterval = INIT_UCAST_POLL_INTERVAL;
// We want to send our poll query ASAP, but the "+ 1" is because if we set the time to now,
#endif
}
-mDNSlocal mDNSu8 *putLLQ(DNSMessage *const msg, mDNSu8 *ptr, const DNSQuestion *const question, const LLQOptData *const data, mDNSBool includeQuestion)
+mDNSlocal mDNSu8 *putLLQ(DNSMessage *const msg, mDNSu8 *ptr, const DNSQuestion *const question, const LLQOptData *const data)
{
AuthRecord rr;
ResourceRecord *opt = &rr.resrec;
rdataOPT *optRD;
//!!!KRS when we implement multiple llqs per message, we'll need to memmove anything past the question section
- if (includeQuestion)
- {
- ptr = putQuestion(msg, ptr, msg->data + AbsoluteMaxDNSMessageData, &question->qname, question->qtype, question->qclass);
- if (!ptr) { LogMsg("ERROR: putLLQ - putQuestion"); return mDNSNULL; }
- }
+ ptr = putQuestion(msg, ptr, msg->data + AbsoluteMaxDNSMessageData, &question->qname, question->qtype, question->qclass);
+ if (!ptr) { LogMsg("ERROR: putLLQ - putQuestion"); return mDNSNULL; }
+
// locate OptRR if it exists, set pointer to end
// !!!KRS implement me
// format opt rr (fields not specified are zero-valued)
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
- opt->rdlength = LLQ_OPT_RDLEN;
- opt->rdestimate = LLQ_OPT_RDLEN;
+ opt->rrclass = NormalMaxDNSMessageData;
+ opt->rdlength = sizeof(rdataOPT); // One option in this OPT record
+ opt->rdestimate = sizeof(rdataOPT);
- optRD = &rr.resrec.rdata->u.opt;
+ optRD = &rr.resrec.rdata->u.opt[0];
optRD->opt = kDNSOpt_LLQ;
- optRD->optlen = LLQ_OPTLEN;
- optRD->OptData.llq = *data;
+ optRD->u.llq = *data;
ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.numAdditionals, opt, 0);
if (!ptr) { LogMsg("ERROR: putLLQ - PutResourceRecordTTLJumbo"); return mDNSNULL; }
//if (q->ntries == 1) return;
InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
- responsePtr = putQuestion(&m->omsg, responsePtr, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
- if (responsePtr) responsePtr = putLLQ(&m->omsg, responsePtr, q, llq, mDNSfalse);
+ responsePtr = putLLQ(&m->omsg, responsePtr, q, llq);
if (responsePtr)
{
mStatus err = mDNSSendDNSMessage(m, &m->omsg, responsePtr, mDNSInterface_Any, q->LocalSocket, &q->servAddr, q->servPort, q->tcp ? q->tcp->sock : mDNSNULL, q->AuthInfo);
if (q->state == LLQ_InitialRequest)
{
- //LogOperation("Got LLQ_InitialRequest");
+ //LogInfo("Got LLQ_InitialRequest");
if (llq->err) { LogMsg("recvSetupResponse - received llq->err %d from server", llq->err); StartLLQPolling(m,q); return; }
}
else if (q->state == LLQ_SecondaryRequest)
{
- //LogOperation("Got LLQ_SecondaryRequest");
+ //LogInfo("Got LLQ_SecondaryRequest");
// Fix this immediately if not sooner. Copy the id from the LLQOptData into our DNSQuestion struct. This is only
// an issue for private LLQs, because we skip parts 2 and 3 of the handshake. This is related to a bigger
// if the server sends back SERVFULL or STATIC.
if (q->AuthInfo)
{
- LogOperation("Private LLQ_SecondaryRequest; copying id %08X%08X", llq->id.l[0], llq->id.l[1]);
+ LogInfo("Private LLQ_SecondaryRequest; copying id %08X%08X", llq->id.l[0], llq->id.l[1]);
q->id = llq->id;
}
{
debugf("uDNS_recvLLQResponse found %##s (%s) %d %#a %#a %X %X %X %X %d",
q->qname.c, DNSTypeName(q->qtype), q->state, srcaddr, &q->servAddr,
- opt->OptData.llq.id.l[0], opt->OptData.llq.id.l[1], q->id.l[0], q->id.l[1], opt->OptData.llq.llqOp);
+ opt ? opt->u.llq.id.l[0] : 0, opt ? opt->u.llq.id.l[1] : 0, q->id.l[0], q->id.l[1], opt ? opt->u.llq.llqOp : 0);
if (q->state == LLQ_Poll) debugf("uDNS_LLQ_Events: q->state == LLQ_Poll msg->h.id %d q->TargetQID %d", mDNSVal16(msg->h.id), mDNSVal16(q->TargetQID));
if (q->state == LLQ_Poll && mDNSSameOpaque16(msg->h.id, q->TargetQID))
{
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- LogOperation("uDNS_recvLLQResponse got poll response; moving to LLQ_InitialRequest for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ debugf("uDNS_recvLLQResponse got poll response; moving to LLQ_InitialRequest for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->state = LLQ_InitialRequest;
q->servPort = zeroIPPort; // Clear servPort so that startLLQHandshake will retry the GetZoneData processing
q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10); // Retry LLQ setup in approx 15 minutes
return uDNS_LLQ_Entire; // uDNS_LLQ_Entire means flush stale records; assume a large effective TTL
}
// Note: In LLQ Event packets, the msg->h.id does not match our q->TargetQID, because in that case the msg->h.id nonce is selected by the server
- else if (opt && q->state == LLQ_Established && opt->OptData.llq.llqOp == kLLQOp_Event && mDNSSameOpaque64(&opt->OptData.llq.id, &q->id))
+ else if (opt && q->state == LLQ_Established && opt->u.llq.llqOp == kLLQOp_Event && mDNSSameOpaque64(&opt->u.llq.id, &q->id))
{
mDNSu8 *ackEnd;
//debugf("Sending LLQ ack for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
InitializeDNSMessage(&m->omsg.h, msg->h.id, ResponseFlags);
- ackEnd = putLLQ(&m->omsg, m->omsg.data, mDNSNULL, &opt->OptData.llq, mDNSfalse);
+ ackEnd = putLLQ(&m->omsg, m->omsg.data, q, &opt->u.llq);
if (ackEnd) mDNSSendDNSMessage(m, &m->omsg, ackEnd, mDNSInterface_Any, q->LocalSocket, srcaddr, srcport, mDNSNULL, mDNSNULL);
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
debugf("uDNS_LLQ_Events: q->state == LLQ_Established msg->h.id %d q->TargetQID %d", mDNSVal16(msg->h.id), mDNSVal16(q->TargetQID));
}
if (opt && mDNSSameOpaque16(msg->h.id, q->TargetQID))
{
- if (q->state == LLQ_Established && opt->OptData.llq.llqOp == kLLQOp_Refresh && mDNSSameOpaque64(&opt->OptData.llq.id, &q->id) && msg->h.numAdditionals && !msg->h.numAnswers)
+ if (q->state == LLQ_Established && opt->u.llq.llqOp == kLLQOp_Refresh && mDNSSameOpaque64(&opt->u.llq.id, &q->id) && msg->h.numAdditionals && !msg->h.numAnswers)
{
- if (opt->OptData.llq.err != LLQErr_NoError) LogMsg("recvRefreshReply: received error %d from server", opt->OptData.llq.err);
+ if (opt->u.llq.err != LLQErr_NoError) LogMsg("recvRefreshReply: received error %d from server", opt->u.llq.err);
else
{
- //LogOperation("Received refresh confirmation ntries %d for %##s (%s)", q->ntries, q->qname.c, DNSTypeName(q->qtype));
- GrantCacheExtensions(m, q, opt->OptData.llq.llqlease);
- SetLLQTimer(m, q, &opt->OptData.llq);
+ //LogInfo("Received refresh confirmation ntries %d for %##s (%s)", q->ntries, q->qname.c, DNSTypeName(q->qtype));
+ // If we're waiting to go to sleep, then this LLQ deletion may have been the thing
+ // we were waiting for, so schedule another check to see if we can sleep now.
+ if (opt->u.llq.llqlease == 0 && m->SleepLimit) m->NextScheduledSPRetry = m->timenow;
+ GrantCacheExtensions(m, q, opt->u.llq.llqlease);
+ SetLLQTimer(m, q, &opt->u.llq);
q->ntries = 0;
}
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
if (q->state < LLQ_Established && mDNSSameAddress(srcaddr, &q->servAddr))
{
LLQ_State oldstate = q->state;
- recvSetupResponse(m, msg->h.flags.b[1] & kDNSFlag1_RC_Mask, q, &opt->OptData.llq);
+ recvSetupResponse(m, msg->h.flags.b[1] & kDNSFlag1_RC_Mask, q, &opt->u.llq);
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
// We have a protocol anomaly here in the LLQ definition.
- // Both the challenge packet from the server and the ack+answers packet have opt->OptData.llq.llqOp == kLLQOp_Setup.
+ // Both the challenge packet from the server and the ack+answers packet have opt->u.llq.llqOp == kLLQOp_Setup.
// However, we need to treat them differently:
// The challenge packet has no answers in it, and tells us nothing about whether our cache entries
// are still valid, so this packet should not cause us to do anything that messes with our cache.
{
end = ((mDNSu8*) &tcpInfo->request) + tcpInfo->requestLen;
}
- else if (q && q->LongLived && q->state != LLQ_Poll && !mDNSIPPortIsZero(m->LLQNAT.ExternalPort))
+ else if (q && q->LongLived && q->state != LLQ_Poll && !mDNSIPPortIsZero(m->LLQNAT.ExternalPort) && !mDNSIPPortIsZero(q->servPort))
{
// Notes:
// If we have a NAT port mapping, ExternalPort is the external port
llqData.vers = kLLQ_Vers;
llqData.llqOp = kLLQOp_Setup;
llqData.err = GetLLQEventPort(m, &tcpInfo->Addr); // We're using TCP; tell server what UDP port to send notifications to
- LogOperation("tcpCallback: eventPort %d", llqData.err);
+ LogInfo("tcpCallback: eventPort %d", llqData.err);
llqData.id = zeroOpaque64;
llqData.llqlease = kLLQ_DefLease;
InitializeDNSMessage(&tcpInfo->request.h, q->TargetQID, uQueryFlags);
- end = putLLQ(&tcpInfo->request, tcpInfo->request.data, q, &llqData, mDNStrue);
+ end = putLLQ(&tcpInfo->request, tcpInfo->request.data, q, &llqData);
if (!end) { LogMsg("ERROR: tcpCallback - putLLQ"); err = mStatus_UnknownErr; goto exit; }
AuthInfo = q->AuthInfo; // Need to add TSIG to this message
}
}
err = mDNSSendDNSMessage(m, &tcpInfo->request, end, mDNSInterface_Any, mDNSNULL, &tcpInfo->Addr, tcpInfo->Port, sock, AuthInfo);
- if (err) { debugf("ERROR: tcpCallback: mDNSSendDNSMessage - %ld", err); err = mStatus_UnknownErr; goto exit; }
+ if (err) { debugf("ERROR: tcpCallback: mDNSSendDNSMessage - %d", err); err = mStatus_UnknownErr; goto exit; }
// Record time we sent this question
if (q)
if (rr && rr->resrec.RecordType == kDNSRecordTypeDeregistering)
{
mDNS_Lock(m);
- LogOperation("tcpCallback: CompleteDeregistration %s", ARDisplayString(m, rr));
+ LogInfo("tcpCallback: CompleteDeregistration %s", ARDisplayString(m, rr));
CompleteDeregistration(m, rr); // Don't touch rr after this
mDNS_Unlock(m);
}
// Don't need to log "connection failed" in customer builds -- it happens quite often during sleep, wake, configuration changes, etc.
if (err == mStatus_ConnEstablished) { tcpCallback(info->sock, info, mDNStrue, mStatus_NoError); }
- else if (err != mStatus_ConnPending ) { LogOperation("MakeTCPConnection: connection failed"); DisposeTCPConn(info); return(mDNSNULL); }
+ else if (err != mStatus_ConnPending ) { LogInfo("MakeTCPConnection: connection failed"); DisposeTCPConn(info); return(mDNSNULL); }
return(info);
}
{
if (mDNSIPv4AddressIsOnes(m->LLQNAT.ExternalAddress))
{
- LogOperation("startLLQHandshake: waiting for NAT status for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("startLLQHandshake: waiting for NAT status for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10); // Retry in approx 15 minutes
q->LastQTime = m->timenow;
SetNextQueryTime(m, q);
if (mDNSIPPortIsZero(m->LLQNAT.ExternalPort))
{
- LogOperation("startLLQHandshake: Cannot receive inbound packets; will poll for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("startLLQHandshake: Cannot receive inbound packets; will poll for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
StartLLQPolling(m, q);
return;
}
if (mDNSIPPortIsZero(q->servPort))
{
- LogOperation("startLLQHandshake: StartGetZoneData for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ debugf("startLLQHandshake: StartGetZoneData for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10); // Retry in approx 15 minutes
q->LastQTime = m->timenow;
SetNextQueryTime(m, q);
q->servAddr = zeroAddr;
- q->servPort = zeroIPPort;
+ // We know q->servPort is zero because of check above
if (q->nta) CancelGetZoneData(m, q->nta);
q->nta = StartGetZoneData(m, &q->qname, ZoneServiceLLQ, LLQGotZoneData, q);
return;
if (q->AuthInfo)
{
- if (q->tcp) LogOperation("startLLQHandshake: Disposing existing TCP connection for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ if (q->tcp) LogInfo("startLLQHandshake: Disposing existing TCP connection for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
if (q->tcp) DisposeTCPConn(q->tcp);
q->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_UseTLS, &q->servAddr, q->servPort, q, mDNSNULL, mDNSNULL);
if (!q->tcp)
}
else
{
- LogOperation("startLLQHandshake m->AdvertisedV4 %#a%s Server %#a:%d%s %##s (%s)",
+ debugf("startLLQHandshake: m->AdvertisedV4 %#a%s Server %#a:%d%s %##s (%s)",
&m->AdvertisedV4, mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4) ? " (RFC 1918)" : "",
&q->servAddr, mDNSVal16(q->servPort), mDNSAddrIsRFC1918(&q->servAddr) ? " (RFC 1918)" : "",
q->qname.c, DNSTypeName(q->qtype));
llqData.llqlease = kLLQ_DefLease;
InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
- end = putLLQ(&m->omsg, m->omsg.data, q, &llqData, mDNStrue);
+ end = putLLQ(&m->omsg, m->omsg.data, q, &llqData);
if (!end) { LogMsg("ERROR: startLLQHandshake - putLLQ"); StartLLQPolling(m,q); return; }
mDNSSendDNSMessage(m, &m->omsg, end, mDNSInterface_Any, q->LocalSocket, &q->servAddr, q->servPort, mDNSNULL, mDNSNULL);
}
}
-mDNSexport const domainname *GetServiceTarget(mDNS *m, ServiceRecordSet *srs)
+// forward declaration so GetServiceTarget can do reverse lookup if needed
+mDNSlocal void GetStaticHostname(mDNS *m);
+
+mDNSexport const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr)
{
- LogOperation("GetServiceTarget %##s", srs->RR_SRV.resrec.name->c);
+ debugf("GetServiceTarget %##s", rr->resrec.name->c);
- if (!srs->RR_SRV.AutoTarget) // If not automatically tracking this host's current name, just return the existing target
- return(&srs->RR_SRV.resrec.rdata->u.srv.target);
+ if (!rr->AutoTarget) // If not automatically tracking this host's current name, just return the existing target
+ return(&rr->resrec.rdata->u.srv.target);
else
{
#if APPLE_OSX_mDNSResponder
- DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, srs->RR_SRV.resrec.name);
+ DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
if (AuthInfo && AuthInfo->AutoTunnel)
{
// If this AutoTunnel is not yet active, start it now (which entails activating its NAT Traversal request,
return(&AuthInfo->AutoTunnelHostRecord.namestorage);
}
else
-#endif APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
{
- const int srvcount = CountLabels(srs->RR_SRV.resrec.name);
+ const int srvcount = CountLabels(rr->resrec.name);
HostnameInfo *besthi = mDNSNULL, *hi;
int best = 0;
for (hi = m->Hostnames; hi; hi = hi->next)
{
int x, hostcount = CountLabels(&hi->fqdn);
for (x = hostcount < srvcount ? hostcount : srvcount; x > 0 && x > best; x--)
- if (SameDomainName(SkipLeadingLabels(srs->RR_SRV.resrec.name, srvcount - x), SkipLeadingLabels(&hi->fqdn, hostcount - x)))
+ if (SameDomainName(SkipLeadingLabels(rr->resrec.name, srvcount - x), SkipLeadingLabels(&hi->fqdn, hostcount - x)))
{ best = x; besthi = hi; }
}
if (besthi) return(&besthi->fqdn);
}
if (m->StaticHostname.c[0]) return(&m->StaticHostname);
+ else GetStaticHostname(m); // asynchronously do reverse lookup for primary IPv4 address
return(mDNSNULL);
}
}
else
if (!(ptr = PutResourceRecordTTLJumbo(&m->omsg, ptr, &m->omsg.h.mDNS_numUpdates, &srs->RR_TXT.resrec, srs->RR_TXT.resrec.rroriginalttl))) { err = mStatus_UnknownErr; goto exit; }
- target = GetServiceTarget(m, srs);
+ target = GetServiceTarget(m, &srs->RR_SRV);
if (!target || target->c[0] == 0)
{
- LogOperation("SendServiceRegistration - no target for %##s", srs->RR_SRV.resrec.name->c);
+ debugf("SendServiceRegistration - no target for %##s", srs->RR_SRV.resrec.name->c);
srs->state = regState_NoTarget;
return;
}
if (srs->Private)
{
- if (srs->tcp) LogOperation("SendServiceRegistration: Disposing existing TCP connection for %s", ARDisplayString(m, &srs->RR_SRV));
+ if (srs->tcp) LogInfo("SendServiceRegistration: Disposing existing TCP connection for %s", ARDisplayString(m, &srs->RR_SRV));
if (srs->tcp) DisposeTCPConn(srs->tcp);
srs->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &srs->SRSUpdateServer, srs->SRSUpdatePort, mDNSNULL, srs, mDNSNULL);
if (!srs->tcp) srs->RR_SRV.ThisAPInterval = mDNSPlatformOneSecond * 5; // If failed to make TCP connection, try again in ten seconds (5*2)
else
{
err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &srs->SRSUpdateServer, srs->SRSUpdatePort, mDNSNULL, GetAuthInfoForName_internal(m, srs->RR_SRV.resrec.name));
- if (err) debugf("ERROR: SendServiceRegistration - mDNSSendDNSMessage - %ld", err);
+ if (err) debugf("ERROR: SendServiceRegistration - mDNSSendDNSMessage - %d", err);
}
SetRecordRetry(m, &srs->RR_SRV, err);
}
else
{
- LogOperation("GetZoneData recursed to root label of %##s without finding SOA", zd->ChildName.c);
+ LogInfo("GetZoneData recursed to root label of %##s without finding SOA", zd->ChildName.c);
zd->ZoneDataCallback(m, mStatus_NoSuchNameErr, zd);
mDNSPlatformMemFree(zd);
}
{
AssignDomainName(&zd->question.qname, ZoneDataSRV(zd));
AppendDomainName(&zd->question.qname, &zd->ZoneName);
- LogOperation("lookupDNSPort %##s", zd->question.qname.c);
+ debugf("lookupDNSPort %##s", zd->question.qname.c);
}
zd->question.ThisQInterval = -1; // So that GetZoneData_QuestionCallback() knows whether to cancel this question (Is this necessary?)
mDNSlocal void CompleteSRVNatMap(mDNS *m, NATTraversalInfo *n)
{
ServiceRecordSet *srs = (ServiceRecordSet *)n->clientContext;
- LogOperation("SRVNatMap complete %.4a %u %u TTL %u", &n->ExternalAddress, mDNSVal16(n->IntPort), mDNSVal16(n->ExternalPort), n->NATLease);
+ debugf("SRVNatMap complete %.4a IntPort %u ExternalPort %u NATLease %u", &n->ExternalAddress, mDNSVal16(n->IntPort), mDNSVal16(n->ExternalPort), n->NATLease);
if (!srs) { LogMsg("CompleteSRVNatMap called with unknown ServiceRecordSet object"); return; }
if (!n->NATLease) return;
else
{
// SHOULD NEVER HAPPEN!
- LogOperation("ERROR: CompleteSRVNatMap called but srs->SRSUpdateServer.ip.v4 is zero!");
+ LogInfo("ERROR: CompleteSRVNatMap called but srs->SRSUpdateServer.ip.v4 is zero!");
srs->state = regState_FetchingZoneData;
- if (srs->nta) CancelGetZoneData(m, srs->nta); // Make sure we cancel old one before we start a new one
- srs->nta = StartGetZoneData(m, srs->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, srs);
+ if (srs->srs_nta) CancelGetZoneData(m, srs->srs_nta); // Make sure we cancel old one before we start a new one
+ srs->srs_nta = StartGetZoneData(m, srs->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, srs);
}
mDNS_Unlock(m);
}
else { LogMsg("StartSRVNatMap: could not determine transport protocol of service %##s", srs->RR_SRV.resrec.name->c); return; }
if (srs->NATinfo.clientContext) mDNS_StopNATOperation_internal(m, &srs->NATinfo);
- srs->NATinfo.IntPort = srs->RR_SRV.resrec.rdata->u.srv.port;
+ // Don't try to set IntPort here --
+ // SendServiceRegistration overwrites srs->RR_SRV.resrec.rdata->u.srv.port with external (mapped) port number
+ //srs->NATinfo.IntPort = srs->RR_SRV.resrec.rdata->u.srv.port;
srs->NATinfo.RequestedPort = srs->RR_SRV.resrec.rdata->u.srv.port;
srs->NATinfo.NATLease = 0; // Request default lease
srs->NATinfo.clientCallback = CompleteSRVNatMap;
if (m->mDNS_busy != m->mDNS_reentrancy)
LogMsg("ServiceRegistrationGotZoneData: mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
- srs->nta = mDNSNULL;
+ if (!srs->RR_SRV.resrec.rdata)
+ { LogMsg("ServiceRegistrationGotZoneData: ERROR: srs->RR_SRV.resrec.rdata is NULL"); return; }
+
+ srs->srs_nta = mDNSNULL;
// Start off assuming we're going to use a lease
// If we get an error from the server, and the update port as given in the SRV record is 53, then we'll retry without the lease option
srs->RR_SRV.LastAPTime = m->timenow;
srs->RR_SRV.ThisAPInterval = 0;
- LogOperation("ServiceRegistrationGotZoneData My IPv4 %#a%s Server %#a:%d%s for %##s",
+ debugf("ServiceRegistrationGotZoneData My IPv4 %#a%s Server %#a:%d%s for %##s",
&m->AdvertisedV4, mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4) ? " (RFC1918)" : "",
&srs->SRSUpdateServer, mDNSVal16(srs->SRSUpdatePort), mDNSAddrIsRFC1918(&srs->SRSUpdateServer) ? " (RFC1918)" : "",
srs->RR_SRV.resrec.name->c);
+ // If we have non-zero service port (always?)
+ // and a private address, and update server is non-private
+ // and this service is AutoTarget
+ // then initiate a NAT mapping request. On completion it will do SendServiceRegistration() for us
if (!mDNSIPPortIsZero(srs->RR_SRV.resrec.rdata->u.srv.port) &&
mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4) && !mDNSAddrIsRFC1918(&srs->SRSUpdateServer) &&
srs->RR_SRV.AutoTarget == Target_AutoHostAndNATMAP)
{
srs->state = regState_NATMap;
- LogOperation("ServiceRegistrationGotZoneData StartSRVNatMap");
+ debugf("ServiceRegistrationGotZoneData StartSRVNatMap");
StartSRVNatMap(m, srs);
}
else
if (srs->Private)
{
- LogOperation("SendServiceDeregistration TCP %p %s", srs->tcp, ARDisplayString(m, &srs->RR_SRV));
- if (srs->tcp) LogOperation("SendServiceDeregistration: Disposing existing TCP connection for %s", ARDisplayString(m, &srs->RR_SRV));
+ LogInfo("SendServiceDeregistration TCP %p %s", srs->tcp, ARDisplayString(m, &srs->RR_SRV));
+ if (srs->tcp) LogInfo("SendServiceDeregistration: Disposing existing TCP connection for %s", ARDisplayString(m, &srs->RR_SRV));
if (srs->tcp) DisposeTCPConn(srs->tcp);
srs->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &srs->SRSUpdateServer, srs->SRSUpdatePort, mDNSNULL, srs, mDNSNULL);
if (!srs->tcp) srs->RR_SRV.ThisAPInterval = mDNSPlatformOneSecond * 5; // If failed to make TCP connection, try again in ten seconds (5*2)
else
{
err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &srs->SRSUpdateServer, srs->SRSUpdatePort, mDNSNULL, GetAuthInfoForName_internal(m, srs->RR_SRV.resrec.name));
- if (err && err != mStatus_TransientErr) { debugf("ERROR: SendServiceDeregistration - mDNSSendDNSMessage - %ld", err); goto exit; }
+ if (err && err != mStatus_TransientErr) { debugf("ERROR: SendServiceDeregistration - mDNSSendDNSMessage - %d", err); goto exit; }
}
SetRecordRetry(m, &srs->RR_SRV, err);
// The target has changed
domainname *curtarget = &srs->RR_SRV.resrec.rdata->u.srv.target;
- const domainname *const nt = GetServiceTarget(m, srs);
+ const domainname *const nt = GetServiceTarget(m, &srs->RR_SRV);
const domainname *const newtarget = nt ? nt : (domainname*)"";
mDNSBool TargetChanged = (newtarget->c[0] && srs->state == regState_NoTarget) || !SameDomainName(curtarget, newtarget);
mDNSBool HaveZoneData = !mDNSIPv4AddressIsZero(srs->SRSUpdateServer.ip.v4);
// Nat state change if:
// We were behind a NAT, and now we are behind a new NAT, or
- // We're not behind a NAT but our port was previously mapped to a different public port
+ // We're not behind a NAT but our port was previously mapped to a different external port
// We were not behind a NAT and now we are
mDNSIPPort port = srs->RR_SRV.resrec.rdata->u.srv.port;
mDNSBool PortWasMapped = (srs->NATinfo.clientContext && !mDNSSameIPPort(srs->NATinfo.RequestedPort, port)); // I think this is always false -- SC Sept 07
mDNSBool NATChanged = (!WereBehindNAT && NowNeedNATMAP) || (!NowNeedNATMAP && PortWasMapped);
- LogOperation("UpdateSRV %##s newtarget %##s TargetChanged %d HaveZoneData %d port %d NowNeedNATMAP %d WereBehindNAT %d PortWasMapped %d NATChanged %d",
+ debugf("UpdateSRV %##s newtarget %##s TargetChanged %d HaveZoneData %d port %d NowNeedNATMAP %d WereBehindNAT %d PortWasMapped %d NATChanged %d",
srs->RR_SRV.resrec.name->c, newtarget,
TargetChanged, HaveZoneData, mDNSVal16(port), NowNeedNATMAP, WereBehindNAT, PortWasMapped, NATChanged);
if (!HaveZoneData)
{
srs->state = regState_FetchingZoneData;
- if (srs->nta) CancelGetZoneData(m, srs->nta); // Make sure we cancel old one before we start a new one
- srs->nta = StartGetZoneData(m, srs->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, srs);
+ if (srs->srs_nta) CancelGetZoneData(m, srs->srs_nta); // Make sure we cancel old one before we start a new one
+ srs->srs_nta = StartGetZoneData(m, srs->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, srs);
}
else
{
// Called with lock held
mDNSlocal void UpdateSRVRecords(mDNS *m)
{
- LogOperation("UpdateSRVRecords%s", m->SleepState ? " (ignored due to SleepState)" : "");
+ debugf("UpdateSRVRecords%s", m->SleepState ? " (ignored due to SleepState)" : "");
if (m->SleepState) return;
if (CurrentServiceRecordSet)
CurrentServiceRecordSet = CurrentServiceRecordSet->uDNS_next;
UpdateSRV(m, s);
}
+
+ mDNS_DropLockBeforeCallback(); // mDNS_SetFQDN expects to be called without the lock held, so we emulate that here
+ mDNS_SetFQDN(m);
+ mDNS_ReclaimLockAfterCallback();
}
// Forward reference: AdvertiseHostname references HostnameCallback, and HostnameCallback calls AdvertiseHostname
if (h->arv4.resrec.RecordType)
{
if (mDNSSameIPv4Address(h->arv4.resrec.rdata->u.ipv4, n->ExternalAddress)) return; // If address unchanged, do nothing
- LogOperation("Updating hostname %##s IPv4 from %.4a to %.4a (NAT gateway's external address)", h->arv4.resrec.name->c, &h->arv4.resrec.rdata->u.ipv4, &n->ExternalAddress);
+ LogInfo("Updating hostname %##s IPv4 from %.4a to %.4a (NAT gateway's external address)",
+ h->arv4.resrec.name->c, &h->arv4.resrec.rdata->u.ipv4, &n->ExternalAddress);
mDNS_Deregister(m, &h->arv4); // mStatus_MemFree callback will re-register with new address
}
else
{
- LogOperation("Advertising hostname %##s IPv4 %.4a (NAT gateway's external address)", h->arv4.resrec.name->c, &n->ExternalAddress);
+ LogInfo("Advertising hostname %##s IPv4 %.4a (NAT gateway's external address)", h->arv4.resrec.name->c, &n->ExternalAddress);
h->arv4.resrec.RecordType = kDNSRecordTypeKnownUnique;
h->arv4.resrec.rdata->u.ipv4 = n->ExternalAddress;
mDNS_Register(m, &h->arv4);
}
else
{
- LogOperation("Advertising hostname %##s IPv4 %.4a", h->arv4.resrec.name->c, &m->AdvertisedV4.ip.v4);
+ LogInfo("Advertising hostname %##s IPv4 %.4a", h->arv4.resrec.name->c, &m->AdvertisedV4.ip.v4);
h->arv4.resrec.RecordType = kDNSRecordTypeKnownUnique;
mDNS_Register_internal(m, &h->arv4);
}
AssignDomainName(&h->arv6.namestorage, &h->fqdn);
h->arv6.resrec.rdata->u.ipv6 = m->AdvertisedV6.ip.v6;
h->arv6.state = regState_Unregistered;
- LogOperation("Advertising hostname %##s IPv6 %.16a", h->arv6.resrec.name->c, &m->AdvertisedV6.ip.v6);
+ LogInfo("Advertising hostname %##s IPv6 %.16a", h->arv6.resrec.name->c, &m->AdvertisedV6.ip.v6);
mDNS_Register_internal(m, &h->arv6);
}
}
{
// If we're still in the Hostnames list, update to new address
HostnameInfo *i;
- LogOperation("HostnameCallback: Got mStatus_MemFree for %p %p %s", hi, rr, ARDisplayString(m, rr));
+ LogInfo("HostnameCallback: Got mStatus_MemFree for %p %p %s", hi, rr, ARDisplayString(m, rr));
for (i = m->Hostnames; i; i = i->next)
if (rr == &i->arv4 || rr == &i->arv6)
{ mDNS_Lock(m); AdvertiseHostname(m, i); mDNS_Unlock(m); return; }
{
// don't unlink or free - we can retry when we get a new address/router
if (rr->resrec.rrtype == kDNSType_A)
- LogMsg("HostnameCallback: Error %ld for registration of %##s IP %.4a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
+ LogMsg("HostnameCallback: Error %d for registration of %##s IP %.4a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
else
- LogMsg("HostnameCallback: Error %ld for registration of %##s IP %.16a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
+ LogMsg("HostnameCallback: Error %d for registration of %##s IP %.16a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
if (!hi) { mDNSPlatformMemFree(rr); return; }
if (rr->state != regState_Unregistered) LogMsg("Error: HostnameCallback invoked with error code for record not in regState_Unregistered!");
// Deliver success to client
if (!hi) { LogMsg("HostnameCallback invoked with orphaned address record"); return; }
if (rr->resrec.rrtype == kDNSType_A)
- LogOperation("Registered hostname %##s IP %.4a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
+ LogInfo("Registered hostname %##s IP %.4a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
else
- LogOperation("Registered hostname %##s IP %.16a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
+ LogInfo("Registered hostname %##s IP %.16a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
rr->RecordContext = (void *)hi->StatusContext;
if (hi->StatusCallback)
mDNSu8 *ip = m->AdvertisedV4.ip.v4.b;
mStatus err;
- if (m->ReverseMap.ThisQInterval != -1) mDNS_StopQuery_internal(m, q);
-
- m->StaticHostname.c[0] = 0;
+ if (m->ReverseMap.ThisQInterval != -1) return; // already running
if (mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4)) return;
+
mDNSPlatformMemZero(q, sizeof(*q));
// Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
mDNS_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa.", ip[3], ip[2], ip[1], ip[0]);
q->QuestionCallback = FoundStaticHostname;
q->QuestionContext = mDNSNULL;
+ LogInfo("GetStaticHostname: %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
err = mDNS_StartQuery_internal(m, q);
if (err) LogMsg("Error: GetStaticHostname - StartQuery returned error %d", err);
}
{
HostnameInfo **ptr = &m->Hostnames;
- LogOperation("mDNS_AddDynDNSHostName %##s", fqdn);
+ LogInfo("mDNS_AddDynDNSHostName %##s", fqdn);
while (*ptr && !SameDomainName(fqdn, &(*ptr)->fqdn)) ptr = &(*ptr)->next;
if (*ptr) { LogMsg("DynDNSHostName %##s already in list", fqdn->c); return; }
{
HostnameInfo **ptr = &m->Hostnames;
- LogOperation("mDNS_RemoveDynDNSHostName %##s", fqdn);
+ LogInfo("mDNS_RemoveDynDNSHostName %##s", fqdn);
while (*ptr && !SameDomainName(fqdn, &(*ptr)->fqdn)) ptr = &(*ptr)->next;
if (!*ptr) LogMsg("mDNS_RemoveDynDNSHostName: no such domainname %##s", fqdn->c);
// below could free the memory, and we have to make sure we don't touch hi fields after that.
mDNSBool f4 = hi->arv4.resrec.RecordType != kDNSRecordTypeUnregistered && hi->arv4.state != regState_Unregistered;
mDNSBool f6 = hi->arv6.resrec.RecordType != kDNSRecordTypeUnregistered && hi->arv6.state != regState_Unregistered;
- if (f4) LogOperation("mDNS_RemoveDynDNSHostName removing v4 %##s", fqdn);
- if (f6) LogOperation("mDNS_RemoveDynDNSHostName removing v6 %##s", fqdn);
+ if (f4) LogInfo("mDNS_RemoveDynDNSHostName removing v4 %##s", fqdn);
+ if (f6) LogInfo("mDNS_RemoveDynDNSHostName removing v6 %##s", fqdn);
*ptr = (*ptr)->next; // unlink
if (f4) mDNS_Deregister_internal(m, &hi->arv4, mDNS_Dereg_normal);
if (f6) mDNS_Deregister_internal(m, &hi->arv6, mDNS_Dereg_normal);
if (v4Changed || RouterChanged || v6Changed)
{
HostnameInfo *i;
- LogOperation("mDNS_SetPrimaryInterfaceInfo: %s%s%s%#a %#a %#a",
+ LogInfo("mDNS_SetPrimaryInterfaceInfo: %s%s%s%#a %#a %#a",
v4Changed ? "v4Changed " : "",
RouterChanged ? "RouterChanged " : "",
v6Changed ? "v6Changed " : "", v4addr, v6addr, router);
for (i = m->Hostnames; i; i = i->next)
{
- LogOperation("mDNS_SetPrimaryInterfaceInfo updating host name registrations for %##s", i->fqdn.c);
+ LogInfo("mDNS_SetPrimaryInterfaceInfo updating host name registrations for %##s", i->fqdn.c);
if (i->arv4.resrec.RecordType > kDNSRecordTypeDeregistering &&
!mDNSSameIPv4Address(i->arv4.resrec.rdata->u.ipv4, m->AdvertisedV4.ip.v4))
{
- LogOperation("mDNS_SetPrimaryInterfaceInfo deregistering %s", ARDisplayString(m, &i->arv4));
+ LogInfo("mDNS_SetPrimaryInterfaceInfo deregistering %s", ARDisplayString(m, &i->arv4));
mDNS_Deregister_internal(m, &i->arv4, mDNS_Dereg_normal);
}
if (i->arv6.resrec.RecordType > kDNSRecordTypeDeregistering &&
!mDNSSameIPv6Address(i->arv6.resrec.rdata->u.ipv6, m->AdvertisedV6.ip.v6))
{
- LogOperation("mDNS_SetPrimaryInterfaceInfo deregistering %s", ARDisplayString(m, &i->arv6));
+ LogInfo("mDNS_SetPrimaryInterfaceInfo deregistering %s", ARDisplayString(m, &i->arv6));
mDNS_Deregister_internal(m, &i->arv6, mDNS_Dereg_normal);
}
m->retryIntervalGetAddr = NATMAP_INIT_RETRY;
m->retryGetAddr = m->timenow;
m->NextScheduledNATOp = m->timenow;
- ClearUPnPState(m);
+ m->LastNATMapResultCode = NATErr_None;
+#ifdef _LEGACY_NAT_TRAVERSAL_
+ LNT_ClearState(m);
+#endif // _LEGACY_NAT_TRAVERSAL_
}
- UpdateSRVRecords(m);
- GetStaticHostname(m); // look up reverse map record to find any static hostnames for our IP address
+ if (m->ReverseMap.ThisQInterval != -1) mDNS_StopQuery_internal(m, &m->ReverseMap);
+ m->StaticHostname.c[0] = 0;
+
+ UpdateSRVRecords(m); // Will call GetStaticHostname if needed
+
#if APPLE_OSX_mDNSResponder
+ if (RouterChanged) uuid_generate(m->asl_uuid);
UpdateAutoTunnelDomainStatuses(m);
#endif
}
}
else if (rcode == kDNSFlag1_RC_NotAuth)
{
- // TSIG errors should come with FmtErr as per RFC 2845, but BIND 9 sends them with NotAuth so we look here too
+ // TSIG errors should come with FormErr as per RFC 2845, but BIND 9 sends them with NotAuth so we look here too
mStatus tsigerr = ParseTSIGError(m, msg, end, displayname);
if (!tsigerr)
{
}
else return tsigerr;
}
- else if (rcode == kDNSFlag1_RC_FmtErr)
+ else if (rcode == kDNSFlag1_RC_FormErr)
{
mStatus tsigerr = ParseTSIGError(m, msg, end, displayname);
if (!tsigerr)
}
rr->RequireGoodbye = mDNStrue;
- rr->id = mDNS_NewMessageID(m);
- InitializeDNSMessage(&m->omsg.h, rr->id, UpdateReqFlags);
+ rr->updateid = mDNS_NewMessageID(m);
+ InitializeDNSMessage(&m->omsg.h, rr->updateid, UpdateReqFlags);
// set zone
- ptr = putZone(&m->omsg, ptr, end, &rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
+ ptr = putZone(&m->omsg, ptr, end, rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
if (!ptr) { err = mStatus_UnknownErr; goto exit; }
if (rr->state == regState_UpdatePending)
else if (rr->resrec.RecordType != kDNSRecordTypeShared)
{
- ptr = putPrereqNameNotInUse(rr->resrec.name, &m->omsg, ptr, end);
+ // For now don't do this, until we have the logic for intelligent grouping of individual recors into logical service record sets
+ //ptr = putPrereqNameNotInUse(rr->resrec.name, &m->omsg, ptr, end);
if (!ptr) { err = mStatus_UnknownErr; goto exit; }
}
if (rr->Private)
{
- LogOperation("SendRecordRegistration TCP %p %s", rr->tcp, ARDisplayString(m, rr));
- if (rr->tcp) LogOperation("SendRecordRegistration: Disposing existing TCP connection for %s", ARDisplayString(m, rr));
+ LogInfo("SendRecordRegistration TCP %p %s", rr->tcp, ARDisplayString(m, rr));
+ if (rr->tcp) LogInfo("SendRecordRegistration: Disposing existing TCP connection for %s", ARDisplayString(m, rr));
if (rr->tcp) DisposeTCPConn(rr->tcp);
rr->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &rr->UpdateServer, rr->UpdatePort, mDNSNULL, mDNSNULL, rr);
if (!rr->tcp) rr->ThisAPInterval = mDNSPlatformOneSecond * 5; // If failed to make TCP connection, try again in ten seconds (5*2)
else
{
err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &rr->UpdateServer, rr->UpdatePort, mDNSNULL, GetAuthInfoForName_internal(m, rr->resrec.name));
- if (err) debugf("ERROR: SendRecordRegistration - mDNSSendDNSMessage - %ld", err);
+ if (err) debugf("ERROR: SendRecordRegistration - mDNSSendDNSMessage - %d", err);
}
SetRecordRetry(m, rr, err);
if (m->mDNS_busy != m->mDNS_reentrancy+1)
LogMsg("hndlServiceUpdateReply: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
- LogOperation("hndlServiceUpdateReply: err %d state %d %##s", err, srs->state, srs->RR_SRV.resrec.name->c);
+ debugf("hndlServiceUpdateReply: err %d state %d %##s", err, srs->state, srs->RR_SRV.resrec.name->c);
SetRecordRetry(m, &srs->RR_SRV, mStatus_NoError);
else
{
//!!!KRS make sure all structs will still get cleaned up when client calls DeregisterService with this state
- if (err) LogMsg("Error %ld for registration of service %##s", err, srs->RR_SRV.resrec.name->c);
+ if (err) LogMsg("Error %d for registration of service %##s", err, srs->RR_SRV.resrec.name->c);
else srs->state = regState_Registered;
InvokeCallback = mDNStrue;
break;
case regState_Refresh:
if (err)
{
- LogMsg("Error %ld for refresh of service %##s", err, srs->RR_SRV.resrec.name->c);
+ LogMsg("Error %d for refresh of service %##s", err, srs->RR_SRV.resrec.name->c);
InvokeCallback = mDNStrue;
}
else srs->state = regState_Registered;
break;
case regState_DeregPending:
- if (err) LogMsg("Error %ld for deregistration of service %##s", err, srs->RR_SRV.resrec.name->c);
+ if (err) LogMsg("Error %d for deregistration of service %##s", err, srs->RR_SRV.resrec.name->c);
if (srs->SRVChanged)
{
srs->state = regState_NoTarget; // NoTarget will allow us to pick up new target OR nat traversal state
case regState_DeregDeferred:
if (err)
{
- debugf("Error %ld received prior to deferred derigstration of %##s", err, srs->RR_SRV.resrec.name->c);
+ debugf("Error %d received prior to deferred deregistration of %##s", err, srs->RR_SRV.resrec.name->c);
err = mStatus_MemFree;
InvokeCallback = mDNStrue;
srs->state = regState_Unregistered;
case regState_NATMap:
case regState_ExtraQueued:
case regState_NATError:
- LogMsg("hndlServiceUpdateReply called for service %##s in unexpected state %d with error %ld. Unlinking.",
+ LogMsg("hndlServiceUpdateReply called for service %##s in unexpected state %d with error %d. Unlinking.",
srs->RR_SRV.resrec.name->c, srs->state, err);
err = mStatus_UnknownErr;
default: LogMsg("hndlServiceUpdateReply: Unknown state %d for %##s", srs->state, srs->RR_SRV.resrec.name->c);
if ((srs->SRVChanged || srs->SRVUpdateDeferred) && (srs->state == regState_NoTarget || srs->state == regState_Registered))
{
- LogOperation("hndlServiceUpdateReply: SRVChanged %d SRVUpdateDeferred %d state %d", srs->SRVChanged, srs->SRVUpdateDeferred, srs->state);
+ debugf("hndlServiceUpdateReply: SRVChanged %d SRVUpdateDeferred %d state %d", srs->SRVChanged, srs->SRVUpdateDeferred, srs->state);
if (InvokeCallback)
{
srs->ClientCallbackDeferred = mDNStrue;
if (srs->state == regState_Registered && !err)
{
// extra resource record queued for this service - copy zone srs and register
- AssignDomainName(&(*e)->r.zone, &srs->zone);
+ (*e)->r.zone = &srs->zone;
(*e)->r.UpdateServer = srs->SRSUpdateServer;
(*e)->r.UpdatePort = srs->SRSUpdatePort;
(*e)->r.uselease = srs->srs_uselease;
if (m->mDNS_busy != m->mDNS_reentrancy+1)
LogMsg("hndlRecordUpdateReply: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
- LogOperation("hndlRecordUpdateReply: err %d state %d %s", err, rr->state, ARDisplayString(m, rr));
+ LogInfo("hndlRecordUpdateReply: err %d state %d %s", err, rr->state, ARDisplayString(m, rr));
if (m->SleepState) return; // If we just sent a deregister on going to sleep, no further action required
if (rr->state == regState_DeregPending)
{
debugf("Received reply for deregister record %##s type %d", rr->resrec.name->c, rr->resrec.rrtype);
- if (err) LogMsg("ERROR: Deregistration of record %##s type %d failed with error %ld",
+ if (err) LogMsg("ERROR: Deregistration of record %##s type %d failed with error %d",
rr->resrec.name->c, rr->resrec.rrtype, err);
err = mStatus_MemFree;
rr->state = regState_Unregistered;
{
if (err)
{
- LogMsg("Cancelling deferred deregistration record %##s type %d due to registration error %ld",
+ LogMsg("Cancelling deferred deregistration record %##s type %d due to registration error %d",
rr->resrec.name->c, rr->resrec.rrtype, err);
rr->state = regState_Unregistered;
}
SendRecordRegistration(m, rr);
return;
}
- LogMsg("hndlRecordUpdateReply: Registration of record %##s type %d failed with error %ld", rr->resrec.name->c, rr->resrec.rrtype, err);
+ LogMsg("hndlRecordUpdateReply: Registration of record %##s type %d failed with error %d", rr->resrec.name->c, rr->resrec.rrtype, err);
return;
}
}
nat_elapsed = AddrReply->upseconds - m->LastNATupseconds;
our_elapsed = (m->timenow - m->LastNATReplyLocalTime) / mDNSPlatformOneSecond;
- LogOperation("uDNS_ReceiveNATPMPPacket %X upseconds %u nat_elapsed %d our_elapsed %d", AddrReply->opcode, AddrReply->upseconds, nat_elapsed, our_elapsed);
+ debugf("uDNS_ReceiveNATPMPPacket %X upseconds %u nat_elapsed %d our_elapsed %d", AddrReply->opcode, AddrReply->upseconds, nat_elapsed, our_elapsed);
// We compute a conservative estimate of how much the NAT gateways's clock should have advanced
// 1. We subtract 12.5% from our own measured elapsed time, to allow for NAT gateways that have an inacurate clock that runs slowly
m->LastNATupseconds = AddrReply->upseconds;
m->LastNATReplyLocalTime = m->timenow;
- ClearUPnPState(m); // We know this is a NAT-PMP base station, so discard any prior UPnP state
+#ifdef _LEGACY_NAT_TRAVERSAL_
+ LNT_ClearState(m);
+#endif // _LEGACY_NAT_TRAVERSAL_
if (AddrReply->opcode == NATOp_AddrResponse)
{
+#if APPLE_OSX_mDNSResponder
+ static char msgbuf[16];
+ mDNS_snprintf(msgbuf, sizeof(msgbuf), "%d", AddrReply->err);
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.AddressRequest", AddrReply->err ? "failure" : "success", msgbuf, "");
+#endif
if (!AddrReply->err && len < sizeof(NATAddrReply)) { LogMsg("NAT Traversal AddrResponse message too short (%d bytes)", len); return; }
natTraversalHandleAddressReply(m, AddrReply->err, AddrReply->ExtAddr);
}
else if (AddrReply->opcode == NATOp_MapUDPResponse || AddrReply->opcode == NATOp_MapTCPResponse)
{
mDNSu8 Protocol = AddrReply->opcode & 0x7F;
+#if APPLE_OSX_mDNSResponder
+ static char msgbuf[16];
+ mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s - %d", AddrReply->opcode == NATOp_MapUDPResponse ? "UDP" : "TCP", PortMapReply->err);
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.PortMapRequest", PortMapReply->err ? "failure" : "success", msgbuf, "");
+#endif
if (!PortMapReply->err)
{
if (len < sizeof(NATPortMapReply)) { LogMsg("NAT Traversal PortMapReply message too short (%d bytes)", len); return; }
PortMapReply->NATRep_lease = (mDNSu32) ((mDNSu32)pkt[12] << 24 | (mDNSu32)pkt[13] << 16 | (mDNSu32)pkt[14] << 8 | pkt[15]);
}
+ // Since some NAT-PMP server implementations don't return the requested internal port in
+ // the reply, we can't associate this reply with a particular NATTraversalInfo structure.
+ // We globally keep track of the most recent error code for mappings.
+ m->LastNATMapResultCode = PortMapReply->err;
+
for (ptr = m->NATTraversals; ptr; ptr=ptr->next)
if (ptr->Protocol == Protocol && mDNSSameIPPort(ptr->IntPort, PortMapReply->intport))
natTraversalHandlePortMapReply(m, ptr, InterfaceID, PortMapReply->err, PortMapReply->extport, PortMapReply->NATRep_lease);
else { LogMsg("Received NAT Traversal response with version unknown opcode 0x%X", AddrReply->opcode); return; }
// Don't need an SSDP socket if we get a NAT-PMP packet
- if (m->SSDPSocket) { LogOperation("uDNS_ReceiveNATPMPPacket destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
+ if (m->SSDPSocket) { debugf("uDNS_ReceiveNATPMPPacket destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
}
// <rdar://problem/3925163> Shorten DNS-SD queries to avoid NAT bugs
// 3. Find occurrences of this server in our list, and mark them appropriately
for (s = m->DNSServers; s; s = s->next)
- if (mDNSSameAddress(srcaddr, &s->addr) && mDNSSameIPPort(srcport, s->port) && s->teststate != result)
+ {
+ mDNSBool matchaddr = (s->teststate != result && mDNSSameAddress(srcaddr, &s->addr) && mDNSSameIPPort(srcport, s->port));
+ mDNSBool matchid = (s->teststate == DNSServer_Untested && mDNSSameOpaque16(msg->h.id, s->testid));
+ if (matchaddr || matchid)
{
DNSQuestion *q;
s->teststate = result;
- if (result == DNSServer_Passed) LogOperation("DNS Server %#a:%d passed", srcaddr, mDNSVal16(srcport));
- else LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d", srcaddr, mDNSVal16(srcport));
+ if (result == DNSServer_Passed)
+ {
+ LogInfo("DNS Server %#a:%d (%#a:%d) %d passed%s",
+ &s->addr, mDNSVal16(s->port), srcaddr, mDNSVal16(srcport), mDNSVal16(s->testid),
+ matchaddr ? "" : " NOTE: Reply did not come from address to which query was sent");
+ }
+ else
+ {
+ LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d (%#a:%d) %d%s",
+ &s->addr, mDNSVal16(s->port), srcaddr, mDNSVal16(srcport), mDNSVal16(s->testid),
+ matchaddr ? "" : " NOTE: Reply did not come from address to which query was sent");
+ }
// If this server has just changed state from DNSServer_Untested to DNSServer_Passed, then retrigger any waiting questions.
// We use the NoTestQuery() test so that we only retrigger questions that were actually blocked waiting for this test to complete.
m->NextScheduledQuery = m->timenow;
}
}
+ }
return(mDNStrue); // Return mDNStrue to tell uDNS_ReceiveMsg it doesn't need to process this packet further
}
// There may be a race condition here, if the server decides to drop the connection just as we decide to reuse it
// For now it should not be serious because our normal retry logic (as used to handle UDP packet loss)
// should take care of it but later we may want to look at handling this case explicitly
- LogOperation("uDNS_ReceiveMsg: Using existing TCP connection for %##s (%s)", qptr->qname.c, DNSTypeName(qptr->qtype));
+ LogInfo("uDNS_ReceiveMsg: Using existing TCP connection for %##s (%s)", qptr->qname.c, DNSTypeName(qptr->qtype));
mDNS_DropLockBeforeCallback();
tcpCallback(qptr->tcp->sock, qptr->tcp, mDNStrue, mStatus_NoError);
mDNS_ReclaimLockAfterCallback();
mDNSu32 lease = GetPktLease(m, msg, end);
mDNSs32 expire = m->timenow + (mDNSs32)lease * mDNSPlatformOneSecond;
- //rcode = kDNSFlag1_RC_SrvErr; // Simulate server failure (rcode 2)
+ //rcode = kDNSFlag1_RC_ServFail; // Simulate server failure (rcode 2)
if (CurrentServiceRecordSet)
LogMsg("uDNS_ReceiveMsg ERROR CurrentServiceRecordSet already set");
{
AuthRecord *rptr = m->CurrentRecord;
m->CurrentRecord = m->CurrentRecord->next;
- if (mDNSSameOpaque16(rptr->id, msg->h.id))
+ if (AuthRecord_uDNS(rptr) && mDNSSameOpaque16(rptr->updateid, msg->h.id))
{
err = checkUpdateResult(m, rptr->resrec.name, rcode, msg, end);
if (!err && rptr->uselease && lease)
llq.llqlease = q->ReqLease;
InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
- end = putLLQ(&m->omsg, m->omsg.data, q, &llq, mDNStrue);
+ end = putLLQ(&m->omsg, m->omsg.data, q, &llq);
if (!end) { LogMsg("sendLLQRefresh: putLLQ failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
// Note that we (conditionally) add HINFO and TSIG here, since the question might be going away,
if (q->AuthInfo && !q->tcp)
{
- LogOperation("sendLLQRefresh setting up new TLS session %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("sendLLQRefresh setting up new TLS session %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->tcp = MakeTCPConn(m, &m->omsg, end, kTCPSocketFlags_UseTLS, &q->servAddr, q->servPort, q, mDNSNULL, mDNSNULL);
}
else
q->servPort = zoneInfo->Port;
q->AuthInfo = zoneInfo->ZonePrivate ? GetAuthInfoForName_internal(m, &q->qname) : mDNSNULL;
q->ntries = 0;
- LogOperation("LLQGotZoneData %#a:%d", &q->servAddr, mDNSVal16(q->servPort));
+ debugf("LLQGotZoneData %#a:%d", &q->servAddr, mDNSVal16(q->servPort));
startLLQHandshake(m, q);
}
else
+ {
StartLLQPolling(m,q);
+ if (err == mStatus_NoSuchNameErr)
+ {
+ // this actually failed, so mark it by setting address to all ones
+ q->servAddr.type = mDNSAddrType_IPv4;
+ q->servAddr.ip.v4 = onesIPv4Addr;
+ }
+ }
mDNS_Unlock(m);
}
{
DNSQuestion *q = (DNSQuestion *) zoneInfo->ZoneDataContext;
- LogOperation("PrivateQueryGotZoneData %##s (%s) err %d Zone %##s Private %d", q->qname.c, DNSTypeName(q->qtype), err, zoneInfo->ZoneName.c, zoneInfo->ZonePrivate);
+ LogInfo("PrivateQueryGotZoneData %##s (%s) err %d Zone %##s Private %d", q->qname.c, DNSTypeName(q->qtype), err, zoneInfo->ZoneName.c, zoneInfo->ZonePrivate);
// If we get here it means that the GetZoneData operation has completed, and is is about to cancel
// its question and free the ZoneData memory. We no longer need to hold onto our pointer (which
if (err || !zoneInfo || mDNSAddressIsZero(&zoneInfo->Addr) || mDNSIPPortIsZero(zoneInfo->Port))
{
- LogOperation("ERROR: PrivateQueryGotZoneData %##s (%s) invoked with error code %ld %p %#a:%d",
+ LogInfo("ERROR: PrivateQueryGotZoneData %##s (%s) invoked with error code %d %p %#a:%d",
q->qname.c, DNSTypeName(q->qtype), err, zoneInfo,
zoneInfo ? &zoneInfo->Addr : mDNSNULL,
zoneInfo ? mDNSVal16(zoneInfo->Port) : 0);
{
AuthRecord *newRR = (AuthRecord*)zoneData->ZoneDataContext;
AuthRecord *ptr;
+ int c1, c2;
if (m->mDNS_busy != m->mDNS_reentrancy)
LogMsg("RecordRegistrationGotZoneData: mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
// check error/result
if (err)
{
- if (err != mStatus_NoSuchNameErr) LogMsg("RecordRegistrationGotZoneData: error %ld", err);
+ if (err != mStatus_NoSuchNameErr) LogMsg("RecordRegistrationGotZoneData: error %d", err);
return;
}
// organizations use their own private pseudo-TLD, like ".home", etc, and we don't want to block that.
if (zoneData->ZoneName.c[0] == 0)
{
- LogOperation("RecordRegistrationGotZoneData: No name server found claiming responsibility for \"%##s\"!", newRR->resrec.name->c);
+ LogInfo("RecordRegistrationGotZoneData: No name server found claiming responsibility for \"%##s\"!", newRR->resrec.name->c);
return;
}
// Store discovered zone data
- AssignDomainName(&newRR->zone, &zoneData->ZoneName);
+ c1 = CountLabels(newRR->resrec.name);
+ c2 = CountLabels(&zoneData->ZoneName);
+ if (c2 > c1)
+ {
+ LogMsg("RecordRegistrationGotZoneData: Zone \"%##s\" is longer than \"%##s\"", zoneData->ZoneName.c, newRR->resrec.name->c);
+ return;
+ }
+ newRR->zone = SkipLeadingLabels(newRR->resrec.name, c1-c2);
+ if (!SameDomainName(newRR->zone, &zoneData->ZoneName))
+ {
+ LogMsg("RecordRegistrationGotZoneData: Zone \"%##s\" does not match \"%##s\" for \"%##s\"", newRR->zone->c, zoneData->ZoneName.c, newRR->resrec.name->c);
+ return;
+ }
newRR->UpdateServer = zoneData->Addr;
newRR->UpdatePort = zoneData->Port;
newRR->Private = zoneData->ZonePrivate;
if (mDNSIPPortIsZero(zoneData->Port) || mDNSAddressIsZero(&zoneData->Addr))
{
- LogOperation("RecordRegistrationGotZoneData: No _dns-update._udp service found for \"%##s\"!", newRR->resrec.name->c);
+ LogInfo("RecordRegistrationGotZoneData: No _dns-update._udp service found for \"%##s\"!", newRR->resrec.name->c);
return;
}
return;
}
- InitializeDNSMessage(&m->omsg.h, rr->id, UpdateReqFlags);
+ InitializeDNSMessage(&m->omsg.h, rr->updateid, UpdateReqFlags);
- ptr = putZone(&m->omsg, ptr, end, &rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
+ ptr = putZone(&m->omsg, ptr, end, rr->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
if (ptr) ptr = putDeletionRecord(&m->omsg, ptr, &rr->resrec);
if (!ptr)
{
rr->expire = 0; // Indicate that we have no active registration any more
if (rr->Private)
{
- LogOperation("SendRecordDeregistration TCP %p %s", rr->tcp, ARDisplayString(m, rr));
- if (rr->tcp) LogOperation("SendRecordDeregistration: Disposing existing TCP connection for %s", ARDisplayString(m, rr));
+ LogInfo("SendRecordDeregistration TCP %p %s", rr->tcp, ARDisplayString(m, rr));
+ if (rr->tcp) LogInfo("SendRecordDeregistration: Disposing existing TCP connection for %s", ARDisplayString(m, rr));
if (rr->tcp) DisposeTCPConn(rr->tcp);
rr->tcp = MakeTCPConn(m, &m->omsg, ptr, kTCPSocketFlags_UseTLS, &rr->UpdateServer, rr->UpdatePort, mDNSNULL, mDNSNULL, rr);
if (!rr->tcp) rr->ThisAPInterval = mDNSPlatformOneSecond * 5; // If failed to make TCP connection, try again in ten seconds (5*2)
else
{
mStatus err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &rr->UpdateServer, rr->UpdatePort, mDNSNULL, GetAuthInfoForName_internal(m, rr->resrec.name));
- if (err) debugf("ERROR: SendRecordDeregistration - mDNSSendDNSMessage - %ld", err);
+ if (err) debugf("ERROR: SendRecordDeregistration - mDNSSendDNSMessage - %d", err);
if (rr->state == regState_DeregPending) CompleteDeregistration(m, rr); // Don't touch rr after this
}
}
// don't re-register with a new target following deregistration
srs->SRVChanged = srs->SRVUpdateDeferred = mDNSfalse;
- if (srs->nta) { CancelGetZoneData(m, srs->nta); srs->nta = mDNSNULL; }
+ if (srs->srs_nta) { CancelGetZoneData(m, srs->srs_nta); srs->srs_nta = mDNSNULL; }
if (srs->NATinfo.clientContext)
{
if (q->unansweredQueries >= MAX_UCAST_UNANSWERED_QUERIES)
{
DNSServer *orig = q->qDNSServer;
-
-#if LogAllOperations || MDNS_DEBUGMSGS
- char buffer[1024];
-
- mDNS_snprintf(buffer, sizeof(buffer), orig ? "%#a:%d (%##s)" : "null", &orig->addr, mDNSVal16(orig->port), orig->domain.c);
- LogOperation("Sent %d unanswered queries for %##s (%s) to %s", q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype), buffer);
-#endif
+ if (orig) LogInfo("Sent %d unanswered queries for %##s (%s) to %#a:%d (%##s)", q->unansweredQueries, q->qname.c, DNSTypeName(q->qtype), &orig->addr, mDNSVal16(orig->port), orig->domain.c);
PushDNSServerToEnd(m, q);
- q->qDNSServer = GetServerForName(m, &q->qname);
-
- if (q->qDNSServer != orig)
- {
-#if LogAllOperations || MDNS_DEBUGMSGS
- mDNS_snprintf(buffer, sizeof(buffer), q->qDNSServer ? "%#a:%d (%##s)" : "null", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qDNSServer->domain.c);
- LogOperation("Server for %##s (%s) changed to %s", q->qname.c, DNSTypeName(q->qtype), buffer);
-#endif
- q->ThisQInterval = q->ThisQInterval / QuestionIntervalStep; // Decrease interval one step so we don't quickly bounce between servers for queries that will not be answered.
- }
-
q->unansweredQueries = 0;
}
}
else if (m->timenow - q->qDNSServer->lasttest >= INIT_UCAST_POLL_INTERVAL) // Make sure at least three seconds has elapsed since last test query
{
- LogOperation("Sending DNS test query to %#a:%d", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port));
+ LogInfo("Sending DNS test query to %#a:%d", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port));
q->ThisQInterval = INIT_UCAST_POLL_INTERVAL / QuestionIntervalStep;
q->qDNSServer->lasttest = m->timenow;
end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, DNSRelayTestQuestion, kDNSType_PTR, kDNSClass_IN);
+ q->qDNSServer->testid = m->omsg.h.id;
}
if (end > m->omsg.data && (q->qDNSServer->teststate != DNSServer_Failed || NoTestQuery(q)))
}
else
{
- err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL);
+ if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ if (!q->LocalSocket) err = mStatus_NoMemoryErr; // If failed to make socket (should be very rare), we'll try again next time
+ else err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL);
m->SuppressStdPort53Queries = NonZeroTime(m->timenow + (mDNSPlatformOneSecond+99)/100);
}
}
- if (err) debugf("ERROR: uDNS_idle - mDNSSendDNSMessage - %ld", err); // surpress syslog messages if we have no network
+ if (err) debugf("ERROR: uDNS_idle - mDNSSendDNSMessage - %d", err); // surpress syslog messages if we have no network
else
{
q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep; // Only increase interval if send succeeded
q->unansweredQueries++;
if (q->ThisQInterval > MAX_UCAST_POLL_INTERVAL)
q->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
- LogOperation("Increased ThisQInterval to %d for %##s (%s)", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype));
+ debugf("Increased ThisQInterval to %d for %##s (%s)", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype));
}
q->LastQTime = m->timenow;
SetNextQueryTime(m, q);
for (rr = cg->members; rr; rr=rr->next)
if (SameNameRecordAnswersQuestion(&rr->resrec, q)) mDNS_PurgeCacheResourceRecord(m, rr);
- if (!q->qDNSServer) LogOperation("uDNS_CheckCurrentQuestion no DNS server for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ if (!q->qDNSServer) debugf("uDNS_CheckCurrentQuestion no DNS server for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
else LogMsg("uDNS_CheckCurrentQuestion DNS server %#a:%d for %##s is disabled", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port), q->qname.c);
- MakeNegativeCacheRecord(m, &q->qname, q->qnamehash, q->qtype, q->qclass, 60);
+ MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, mDNSInterface_Any);
// Inactivate this question until the next change of DNS servers (do this before AnswerCurrentQuestionWithResourceRecord)
q->ThisQInterval = 0;
q->unansweredQueries = 0;
{
if (m->NATMcastRecvskt == mDNSNULL) // If we are behind a NAT and the socket hasn't been opened yet, open it
{
+ // we need to log a message if we can't get our socket, but only the first time (after success)
+ static mDNSBool needLog = mDNStrue;
m->NATMcastRecvskt = mDNSPlatformUDPSocket(m, NATPMPAnnouncementPort);
- m->NATMcastRecvsk2 = mDNSPlatformUDPSocket(m, NATPMPPort); // For backwards compatibility with older base stations that announce on 5351
- if (!m->NATMcastRecvskt) LogMsg("CheckNATMappings: Failed to allocate port 5350 UDP multicast socket for NAT-PMP announcements");
- if (!m->NATMcastRecvsk2) LogOperation("CheckNATMappings: Failed to allocate port 5351 UDP multicast socket for NAT-PMP announcements");
+ if (!m->NATMcastRecvskt)
+ {
+ if (needLog)
+ {
+ LogMsg("CheckNATMappings: Failed to allocate port 5350 UDP multicast socket for NAT-PMP announcements");
+ needLog = mDNSfalse;
+ }
+ }
+ else
+ needLog = mDNStrue;
}
}
else // else, we don't want to listen for announcements, so close them if they're open
{
if (m->NATMcastRecvskt) { mDNSPlatformUDPClose(m->NATMcastRecvskt); m->NATMcastRecvskt = mDNSNULL; }
- if (m->NATMcastRecvsk2) { mDNSPlatformUDPClose(m->NATMcastRecvsk2); m->NATMcastRecvsk2 = mDNSNULL; }
- if (m->SSDPSocket) { LogOperation("CheckNATMappings destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
+ if (m->SSDPSocket) { debugf("CheckNATMappings destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
}
if (m->NATTraversals)
{
//LogMsg("NAT callback %d %d %d", cur->Protocol, cur->ExpiryTime, cur->retryInterval);
if (cur->Protocol && mDNSIPPortIsZero(ExternalPort) && !mDNSIPv4AddressIsZero(m->Router.ip.v4))
- LogMsg("Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %d error %d",
- cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), EffectiveResult);
+ {
+ if (!EffectiveResult)
+ LogInfo("Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %5d interval %d error %d",
+ cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), cur->retryInterval, EffectiveResult);
+ else
+ LogMsg("Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %5d interval %d error %d",
+ cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), cur->retryInterval, EffectiveResult);
+ }
cur->ExternalAddress = m->ExternalAddress;
cur->ExternalPort = ExternalPort;
if (srs->tcp) { DisposeTCPConn(srs->tcp); srs->tcp = mDNSNULL; }
if (srs->state == regState_FetchingZoneData)
{
- if (srs->nta) CancelGetZoneData(m, srs->nta);
- srs->nta = StartGetZoneData(m, srs->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, srs);
+ if (srs->srs_nta) CancelGetZoneData(m, srs->srs_nta);
+ srs->srs_nta = StartGetZoneData(m, srs->RR_SRV.resrec.name, ZoneServiceUpdate, ServiceRegistrationGotZoneData, srs);
SetRecordRetry(m, &srs->RR_SRV, mStatus_NoError);
}
else if (srs->state == regState_DeregPending) SendServiceDeregistration(m, srs);
ServiceRecordSet *srs = m->ServiceRegistrations;
while (srs)
{
- LogOperation("SleepServiceRegistrations: state %d %s", srs->state, ARDisplayString(m, &srs->RR_SRV));
- if (srs->nta) { CancelGetZoneData(m, srs->nta); srs->nta = mDNSNULL; }
+ LogInfo("SleepServiceRegistrations: state %d %s", srs->state, ARDisplayString(m, &srs->RR_SRV));
+ if (srs->srs_nta) { CancelGetZoneData(m, srs->srs_nta); srs->srs_nta = mDNSNULL; }
if (srs->NATinfo.clientContext)
{
{
// If domain is already in list, and marked for deletion, change it to "leave alone"
if ((*p)->flag == -1) (*p)->flag = 0;
- LogOperation("mDNS_AddSearchDomain already in list %##s", domain->c);
+ LogInfo("mDNS_AddSearchDomain already in list %##s", domain->c);
return;
}
AssignDomainName(&(*p)->domain, domain);
(*p)->flag = 1; // add
(*p)->next = mDNSNULL;
- LogOperation("mDNS_AddSearchDomain created new %##s", domain->c);
+ LogInfo("mDNS_AddSearchDomain created new %##s", domain->c);
}
mDNSlocal void FreeARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
{
SearchListElem *slElem = question->QuestionContext;
mStatus err;
+ const char *name;
if (answer->rrtype != kDNSType_PTR) return;
if (answer->RecordType == kDNSRecordTypePacketNegative) return;
+ if (answer->InterfaceID == mDNSInterface_LocalOnly) return;
+
+ if (question == &slElem->BrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowse];
+ else if (question == &slElem->DefBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseDefault];
+ else if (question == &slElem->AutomaticBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseAutomatic];
+ else if (question == &slElem->RegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistration];
+ else if (question == &slElem->DefRegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistrationDefault];
+ else { LogMsg("FoundDomain - unknown question"); return; }
+
+ LogInfo("FoundDomain: %p %s %s Q %##s A %s", answer->InterfaceID, AddRecord ? "Add" : "Rmv", name, question->qname.c, RRDisplayString(m, answer));
if (AddRecord)
{
- const char *name;
ARListElem *arElem = mDNSPlatformMemAllocate(sizeof(ARListElem));
- if (!arElem) { LogMsg("ERROR: malloc"); return; }
+ if (!arElem) { LogMsg("ERROR: FoundDomain out of memory"); return; }
mDNS_SetupResourceRecord(&arElem->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, FreeARElemCallback, arElem);
- if (question == &slElem->BrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowse];
- else if (question == &slElem->DefBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseDefault];
- else if (question == &slElem->AutomaticBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseAutomatic];
- else if (question == &slElem->RegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistration];
- else if (question == &slElem->DefRegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistrationDefault];
- else { LogMsg("FoundDomain - unknown question"); mDNSPlatformMemFree(arElem); return; }
-
MakeDomainNameFromDNSNameString(&arElem->ar.namestorage, name);
AppendDNSNameString (&arElem->ar.namestorage, "local");
AssignDomainName(&arElem->ar.resrec.rdata->u.name, &answer->rdata->u.name);
+ LogInfo("FoundDomain: Registering %s", ARDisplayString(m, &arElem->ar));
err = mDNS_Register(m, &arElem->ar);
if (err) { LogMsg("ERROR: FoundDomain - mDNS_Register returned %d", err); mDNSPlatformMemFree(arElem); return; }
arElem->next = slElem->AuthRecs;
{
ARListElem *dereg = *ptr;
*ptr = (*ptr)->next;
- debugf("Deregistering PTR %##s -> %##s", dereg->ar.resrec.name->c, dereg->ar.resrec.rdata->u.name.c);
+ LogInfo("FoundDomain: Deregistering %s", ARDisplayString(m, &dereg->ar));
err = mDNS_Deregister(m, &dereg->ar);
if (err) LogMsg("ERROR: FoundDomain - mDNS_Deregister returned %d", err);
// Memory will be freed in the FreeARElemCallback
while (*p)
{
ptr = *p;
- debugf("RegisterSearchDomains %d %p %##s", ptr->flag, ptr->AuthRecs, ptr->domain.c);
+ LogInfo("RegisterSearchDomains %d %p %##s", ptr->flag, ptr->AuthRecs, ptr->domain.c);
if (ptr->flag == -1) // remove
{
ARListElem *arList = ptr->AuthRecs;
ptr->AuthRecs = mDNSNULL;
*p = ptr->next;
- mDNS_StopGetDomains(m, &ptr->BrowseQ);
- mDNS_StopGetDomains(m, &ptr->RegisterQ);
- mDNS_StopGetDomains(m, &ptr->DefBrowseQ);
- mDNS_StopGetDomains(m, &ptr->DefRegisterQ);
- mDNS_StopGetDomains(m, &ptr->AutomaticBrowseQ);
+ // If the user has "local" in their DNS searchlist, we ignore that for the purposes of domain enumeration queries
+ if (!SameDomainName(&ptr->domain, &localdomain))
+ {
+ mDNS_StopGetDomains(m, &ptr->BrowseQ);
+ mDNS_StopGetDomains(m, &ptr->RegisterQ);
+ mDNS_StopGetDomains(m, &ptr->DefBrowseQ);
+ mDNS_StopGetDomains(m, &ptr->DefRegisterQ);
+ mDNS_StopGetDomains(m, &ptr->AutomaticBrowseQ);
+ }
mDNSPlatformMemFree(ptr);
// deregister records generated from answers to the query
if (ptr->flag == 1) // add
{
- mStatus err1, err2, err3, err4, err5;
- err1 = mDNS_GetDomains(m, &ptr->BrowseQ, mDNS_DomainTypeBrowse, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
- err2 = mDNS_GetDomains(m, &ptr->DefBrowseQ, mDNS_DomainTypeBrowseDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
- err3 = mDNS_GetDomains(m, &ptr->RegisterQ, mDNS_DomainTypeRegistration, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
- err4 = mDNS_GetDomains(m, &ptr->DefRegisterQ, mDNS_DomainTypeRegistrationDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
- err5 = mDNS_GetDomains(m, &ptr->AutomaticBrowseQ, mDNS_DomainTypeBrowseAutomatic, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
- if (err1 || err2 || err3 || err4 || err5)
- LogMsg("GetDomains for domain %##s returned error(s):\n"
- "%d (mDNS_DomainTypeBrowse)\n"
- "%d (mDNS_DomainTypeBrowseDefault)\n"
- "%d (mDNS_DomainTypeRegistration)\n"
- "%d (mDNS_DomainTypeRegistrationDefault)"
- "%d (mDNS_DomainTypeBrowseAutomatic)\n",
- ptr->domain.c, err1, err2, err3, err4, err5);
+ // If the user has "local" in their DNS searchlist, we ignore that for the purposes of domain enumeration queries
+ if (!SameDomainName(&ptr->domain, &localdomain))
+ {
+ mStatus err1, err2, err3, err4, err5;
+ err1 = mDNS_GetDomains(m, &ptr->BrowseQ, mDNS_DomainTypeBrowse, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
+ err2 = mDNS_GetDomains(m, &ptr->DefBrowseQ, mDNS_DomainTypeBrowseDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
+ err3 = mDNS_GetDomains(m, &ptr->RegisterQ, mDNS_DomainTypeRegistration, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
+ err4 = mDNS_GetDomains(m, &ptr->DefRegisterQ, mDNS_DomainTypeRegistrationDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
+ err5 = mDNS_GetDomains(m, &ptr->AutomaticBrowseQ, mDNS_DomainTypeBrowseAutomatic, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
+ if (err1 || err2 || err3 || err4 || err5)
+ LogMsg("GetDomains for domain %##s returned error(s):\n"
+ "%d (mDNS_DomainTypeBrowse)\n"
+ "%d (mDNS_DomainTypeBrowseDefault)\n"
+ "%d (mDNS_DomainTypeRegistration)\n"
+ "%d (mDNS_DomainTypeRegistrationDefault)"
+ "%d (mDNS_DomainTypeBrowseAutomatic)\n",
+ ptr->domain.c, err1, err2, err3, err4, err5);
+ }
ptr->flag = 0;
}
// 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_tcpInfo_t [(sizeof(tcpInfo_t) <= 9056) ? 1 : -1];
- char sizecheck_SearchListElem[(sizeof(SearchListElem) <= 3880) ? 1 : -1];
+ char sizecheck_SearchListElem[(sizeof(SearchListElem) <= 3920) ? 1 : -1];
};
Change History (most recent first):
$Log: uDNS.h,v $
+Revision 1.93 2008/09/24 23:48:05 cheshire
+Don't need to pass whole ServiceRecordSet reference to GetServiceTarget;
+it only needs to access the embedded SRV member of the set
+
Revision 1.92 2008/06/19 23:42:03 mcguire
<rdar://problem/4206534> Use all configured DNS servers
extern mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr);
extern void ServiceRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *result);
-extern const domainname *GetServiceTarget(mDNS *m, ServiceRecordSet *srs);
+extern const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr);
extern mStatus uDNS_DeregisterService(mDNS *const m, ServiceRecordSet *srs);
extern void uDNS_CheckCurrentQuestion(mDNS *const m);
Change History (most recent first):
$Log: Mac\040OS\040Test\040Responder.c,v $
+Revision 1.26 2008/11/04 19:43:35 cheshire
+Updated comment about MAX_ESCAPED_DOMAIN_NAME size (should be 1009, not 1005)
+
Revision 1.25 2006/08/14 23:24:29 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
Revision 1.18 2003/11/14 21:27:08 cheshire
<rdar://problem/3484766>: Security: Crashing bug in mDNSResponder
-Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1005) instead of 256-byte buffers.
+Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1009) instead of 256-byte buffers.
Revision 1.17 2003/08/14 02:19:54 cheshire
<rdar://problem/3375491> Split generic ResourceRecord type into two separate types: AuthRecord and CacheRecord
Change History (most recent first):
$Log: Mac\040OS\040Test\040Searcher.c,v $
+Revision 1.24 2008/11/04 19:43:35 cheshire
+Updated comment about MAX_ESCAPED_DOMAIN_NAME size (should be 1009, not 1005)
+
Revision 1.23 2007/07/27 19:30:40 cheshire
Changed mDNSQuestionCallback parameter from mDNSBool to QC_result,
to properly reflect tri-state nature of the possible responses
Revision 1.14 2003/11/14 21:27:09 cheshire
<rdar://problem/3484766>: Security: Crashing bug in mDNSResponder
-Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1005) instead of 256-byte buffers.
+Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1009) instead of 256-byte buffers.
Revision 1.13 2003/08/14 02:19:54 cheshire
<rdar://problem/3375491> Split generic ResourceRecord type into two separate types: AuthRecord and CacheRecord
if (interface) {
int len = ((struct sockaddr *)interface)->sa_len;
interface_storage = (struct sockaddr *)malloc(len);
- bcopy(interface, interface_storage,len);
+ memcpy(interface_storage, interface, len);
}
if (address) {
int len = ((struct sockaddr *)address)->sa_len;
address_storage = (struct sockaddr *)malloc(len);
- bcopy(address, address_storage, len);
+ memcpy(address_storage, address, len);
}
pthread_mutex_lock(&a_requests_lock);
<string>/usr/sbin/dnsextd</string>
<string>-launchd</string>
</array>
- <key>ServiceIPC</key>
- <false/>
</dict>
</plist>
<string>com.apple.mDNSResponderHelper</string>
<key>OnDemand</key>
<true/>
- <key>HopefullyExitsLast</key>
- <true/>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/mDNSResponderHelper</string>
<key>com.apple.mDNSResponderHelper</key>
<true/>
</dict>
- <key>ServiceIPC</key>
+ <key>EnableTransactions</key>
<true/>
</dict>
</plist>
<string>com.apple.mDNSResponder</string>
<key>OnDemand</key>
<false/>
- <key>HopefullyExitsFirst</key>
- <true/>
<key>UserName</key>
<string>_mdnsresponder</string>
<key>GroupName</key>
<integer>438</integer>
</dict>
</dict>
- <key>ServiceIPC</key>
+ <key>EnableTransactions</key>
<true/>
</dict>
</plist>
Change History (most recent first):
$Log: LegacyNATTraversal.c,v $
-Revision 1.48.2.1 2008/09/30 18:03:03 mcguire
+Revision 1.65 2009/07/03 03:16:07 jessic2
+<rdar://problem/7026146> BTMM: UPnP works in Leopard but doesn't work in SnowLeopard (URLBase is empty) Made changes to support the case where the URLBase tag exists but there isn't a valid URL
+
+Revision 1.64 2009/06/25 21:07:44 herscher
+<rdar://problem/4147784> B4W should support UPnP
+
+Revision 1.63 2009/03/26 03:59:00 jessic2
+Changes for <rdar://problem/6492552&6492593&6492609&6492613&6492628&6492640&6492699>
+
+Revision 1.62 2009/02/13 06:31:09 cheshire
+Converted LogOperation messages to LogInfo
+
+Revision 1.61 2009/01/23 19:25:43 mcguire
+<rdar://problem/6514439> UPnP: Should not use NATErr_Refused when too many conflict retries
+
+Revision 1.60 2009/01/23 00:38:36 mcguire
+<rdar://problem/5570906> BTMM: Doesn't work with Linksys WRT54GS firmware 4.71.1
+
+Revision 1.59 2009/01/22 20:32:17 mcguire
+<rdar://problem/6446934> BTMM: pref pane reports enabled but negotiation failed
+Make sure we push the pointer out past the LF if we read it.
+
+Revision 1.58 2009/01/22 01:15:58 mcguire
+<rdar://problem/6446934> BTMM: pref pane reports enabled but negotiation failed
+
+Revision 1.57 2008/12/19 21:09:22 mcguire
+<rdar://problem/6431147> UPnP: error messages when canceling seemingly unrelated browse
+
+Revision 1.56 2008/12/06 01:42:57 mcguire
+<rdar://problem/6418958> Need to exponentially back-off after failure to get public address
+
+Revision 1.55 2008/12/01 19:43:48 mcguire
+<rdar://problem/6404766> UPnP: Handle errorCode 718 as a conflict when requesting a port mapping
+
+Revision 1.54 2008/11/26 20:57:37 cheshire
+For consistency with other similar macros, renamed mdnsIsDigit/mdnsIsLetter/mdnsValidHostChar
+to mDNSIsDigit/mDNSIsLetter/mDNSValidHostChar
+
+Revision 1.53 2008/11/26 20:34:04 cheshire
+Changed "destroying SSDPSocket" LogOperation debugging messages to debugf
+
+Revision 1.52 2008/11/26 19:54:03 cheshire
+Changed some "LogOperation" debugging messages to "debugf"
+
+Revision 1.51 2008/11/20 02:23:38 mcguire
+<rdar://problem/6041208> need to handle URLBase
+
+Revision 1.50 2008/09/20 00:34:22 mcguire
<rdar://problem/6129039> BTMM: Add support for WANPPPConnection
+Revision 1.49 2008/08/07 21:51:13 mcguire
+<rdar://problem/5904423> UPnP: Possible memory corruption bug
+<rdar://problem/5930173> UPnP: Combine URL parsing code
+
Revision 1.48 2008/07/24 20:23:04 cheshire
<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
#include "stdlib.h" // For strtol()
#include "string.h" // For strlcpy(), For strncpy(), strncasecmp()
-#include <arpa/inet.h> // For inet_pton()
+
+#if defined( WIN32 )
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+# define mDNSASLLog( UUID, SUBDOMAIN, RESULT, SIGNATURE, FORMAT, ... ) ;
+
+static 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( 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;
+ }
+#else
+# include <arpa/inet.h> // For inet_pton()
+#endif
#include "mDNSEmbeddedAPI.h"
#include "uDNS.h" // For natTraversalHandleAddressReply() etc.
#define RequestedPortNum(n) (mDNSVal16(mDNSIPPortIsZero((n)->RequestedPort) ? (n)->IntPort : (n)->RequestedPort) + (n)->tcpInfo.retries)
+// Note that this function assumes src is already NULL terminated
+mDNSlocal void AllocAndCopy(mDNSu8** dst, mDNSu8* src)
+ {
+ if (src == mDNSNULL) return;
+ if ((*dst = (mDNSu8 *) mDNSPlatformMemAllocate(strlen((char*)src) + 1)) == mDNSNULL) { LogMsg("AllocAndCopy: can't allocate string"); return; }
+ strcpy((char *)*dst, (char*)src);
+ }
+
+// This function does a simple parse of an HTTP URL that may include a hostname, port, and path
+// If found in the URL, addressAndPort and path out params will point to newly allocated space (and will leak if they were previously pointing at allocated space)
+mDNSlocal mStatus ParseHttpUrl(char* ptr, char* end, mDNSu8** addressAndPort, mDNSIPPort* port, mDNSu8** path)
+ {
+ // if the data begins with "http://", we assume there is a hostname and possibly a port number
+ if (end - ptr >= 7 && strncasecmp(ptr, "http://", 7) == 0)
+ {
+ int i;
+ char* stop = end;
+ char* addrPtr = mDNSNULL;
+
+ ptr += 7; //skip over "http://"
+ if (ptr >= end) { LogInfo("ParseHttpUrl: past end of buffer parsing host:port"); return mStatus_BadParamErr; }
+
+ // find the end of the host:port
+ addrPtr = ptr;
+ for (i = 0; addrPtr && addrPtr != end; i++, addrPtr++) if (*addrPtr == '/') break;
+
+ // allocate the buffer (len i+1 so we have space to terminate the string)
+ if ((*addressAndPort = (mDNSu8 *) mDNSPlatformMemAllocate(i+1)) == mDNSNULL) { LogMsg("ParseHttpUrl: can't allocate address string"); return mStatus_NoMemoryErr; }
+ strncpy((char *)*addressAndPort, ptr, i);
+ (*addressAndPort)[i] = '\0';
+
+ // find the port number in the string, by looking backwards for the ':'
+ stop = ptr; // can't go back farther than the original start
+ ptr = addrPtr; // move ptr to the path part
+
+ for (addrPtr--;addrPtr>stop;addrPtr--)
+ {
+ if (*addrPtr == ':')
+ {
+ int tmpport;
+ addrPtr++; // skip over ':'
+ tmpport = (int)strtol(addrPtr, mDNSNULL, 10);
+ *port = mDNSOpaque16fromIntVal(tmpport); // store it properly converted
+ break;
+ }
+ }
+ }
+
+ // ptr should now point to the first character we haven't yet processed
+ // everything that remains is the path
+ if (path && ptr < end)
+ {
+ if ((*path = (mDNSu8 *)mDNSPlatformMemAllocate(end - ptr + 1)) == mDNSNULL) { LogMsg("ParseHttpUrl: can't mDNSPlatformMemAllocate path"); return mStatus_NoMemoryErr; }
+ strncpy((char *)*path, ptr, end - ptr);
+ (*path)[end - ptr] = '\0';
+ }
+
+ return mStatus_NoError;
+ }
+
+enum
+ {
+ HTTPCode_NeedMoreData = -1, // No code found in stream
+ HTTPCode_Other = -2, // Valid code other than those below found in stream
+ HTTPCode_Bad = -3,
+ HTTPCode_200 = 200,
+ HTTPCode_404 = 404,
+ HTTPCode_500 = 500,
+ };
+
+mDNSlocal mDNSs16 ParseHTTPResponseCode(mDNSu8** data, mDNSu8* end)
+ {
+ mDNSu8* ptr = *data;
+ char * code;
+
+ if (end - ptr < 5) return HTTPCode_NeedMoreData;
+ if (strncasecmp((char*)ptr, "HTTP/", 5) != 0) return HTTPCode_Bad;
+ ptr += 5;
+ // should we care about the HTTP protocol version?
+
+ // look for first space, which must come before first LF
+ while (ptr && ptr != end)
+ {
+ if (*ptr == '\n') return HTTPCode_Bad;
+ if (*ptr == ' ') break;
+ ptr++;
+ }
+ if (ptr == end) return HTTPCode_NeedMoreData;
+ ptr++;
+
+ if (end - ptr < 3) return HTTPCode_NeedMoreData;
+
+ code = (char*)ptr;
+ ptr += 3;
+ while (ptr && ptr != end)
+ {
+ if (*ptr == '\n') break;
+ ptr++;
+ }
+ if (ptr == end) return HTTPCode_NeedMoreData;
+ *data = ++ptr;
+
+ if (memcmp(code, "200", 3) == 0) return HTTPCode_200;
+ if (memcmp(code, "404", 3) == 0) return HTTPCode_404;
+ if (memcmp(code, "500", 3) == 0) return HTTPCode_500;
+
+ LogInfo("ParseHTTPResponseCode found unexpected result code: %c%c%c", code[0], code[1], code[2]);
+ return HTTPCode_Other;
+ }
+
// This function parses the xml body of the device description response from the router. Basically, we look to make sure this is a response
// referencing a service we care about (WANIPConnection or WANPPPConnection), look for the "controlURL" header immediately following, and copy the addressing and URL info we need
mDNSlocal void handleLNTDeviceDescriptionResponse(tcpLNTInfo *tcpInfo)
char *ptr = (char *)tcpInfo->Reply;
char *end = (char *)tcpInfo->Reply + tcpInfo->nread;
char *stop = mDNSNULL;
+ mDNSs16 http_result;
+
+ if (!mDNSIPPortIsZero(m->UPnPSOAPPort)) return; // already have the info we need
+
+ http_result = ParseHTTPResponseCode((mDNSu8**)&ptr, (mDNSu8*)end); // Note: modifies ptr
+ if (http_result == HTTPCode_404) LNT_ClearState(m);
+ if (http_result != HTTPCode_200)
+ {
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "noop", "HTTP Result", "HTTP code: %d", http_result);
+ return;
+ }
// Always reset our flag to use WANIPConnection. We'll use WANPPPConnection if we find it and don't find WANIPConnection.
m->UPnPWANPPPConnection = mDNSfalse;
// find either service we care about
- while (ptr && ptr != end)
+ while (ptr && ptr < end)
{
if (*ptr == 'W' && (strncasecmp(ptr, "WANIPConnection:1", 17) == 0)) break;
ptr++;
if (ptr == end)
{
ptr = (char *)tcpInfo->Reply;
- while (ptr && ptr != end)
+ while (ptr && ptr < end)
{
if (*ptr == 'W' && (strncasecmp(ptr, "WANPPPConnection:1", 18) == 0))
{
ptr++;
}
}
- if (ptr == mDNSNULL || ptr == end) { LogOperation("handleLNTDeviceDescriptionResponse: didn't find WANIPConnection:1 or WANPPPConnection:1 string"); return; }
+ if (ptr == mDNSNULL || ptr == end) { LogInfo("handleLNTDeviceDescriptionResponse: didn't find WANIPConnection:1 or WANPPPConnection:1 string"); return; }
// find "controlURL", starting from where we left off
- while (ptr && ptr != end)
+ while (ptr && ptr < end)
{
if (*ptr == 'c' && (strncasecmp(ptr, "controlURL", 10) == 0)) break; // find the first 'c'; is this controlURL? if not, keep looking
ptr++;
}
- if (ptr == mDNSNULL || ptr == end) { LogOperation("handleLNTDeviceDescriptionResponse: didn't find controlURL string"); return; }
+ if (ptr == mDNSNULL || ptr == end) { LogInfo("handleLNTDeviceDescriptionResponse: didn't find controlURL string"); return; }
ptr += 11; // skip over "controlURL>"
- if (ptr >= end) { LogOperation("handleLNTDeviceDescriptionResponse: past end of buffer and no body!"); return; } // check ptr again in case we skipped over the end of the buffer
+ if (ptr >= end) { LogInfo("handleLNTDeviceDescriptionResponse: past end of buffer and no body!"); return; } // check ptr again in case we skipped over the end of the buffer
// find the end of the controlURL element
- for (stop = ptr; stop != end; stop++) { if (*stop == '<') { end = stop; break; } }
+ for (stop = ptr; stop < end; stop++) { if (*stop == '<') { end = stop; break; } }
// fill in default port
m->UPnPSOAPPort = m->UPnPRouterPort;
- // is there an address string "http://"?
- if (strncasecmp(ptr, "http://", 7) == 0)
+ // free string pointers and set to NULL
+ if (m->UPnPSOAPAddressString != mDNSNULL)
{
- int i;
- char *addrPtr = mDNSNULL;
-
- ptr += 7; //skip over "http://"
- if (ptr >= end) { LogOperation("handleLNTDeviceDescriptionResponse: past end of buffer and no URL!"); return; }
- addrPtr = ptr;
- for (i = 0; addrPtr && addrPtr != end; i++, addrPtr++) if (*addrPtr == '/') break; // first find the beginning of the URL and count the chars
- if (addrPtr == mDNSNULL || addrPtr == end) { LogOperation("handleLNTDeviceDescriptionResponse: didn't find SOAP address string"); return; }
+ mDNSPlatformMemFree(m->UPnPSOAPAddressString);
+ m->UPnPSOAPAddressString = mDNSNULL;
+ }
+ if (m->UPnPSOAPURL != mDNSNULL)
+ {
+ mDNSPlatformMemFree(m->UPnPSOAPURL);
+ m->UPnPSOAPURL = mDNSNULL;
+ }
+
+ if (ParseHttpUrl(ptr, end, &m->UPnPSOAPAddressString, &m->UPnPSOAPPort, &m->UPnPSOAPURL) != mStatus_NoError) return;
+ // the SOAPURL should look something like "/uuid:0013-108c-4b3f0000f3dc"
- // allocate the buffer (len i+1 so we have space to terminate the string)
- if (m->UPnPSOAPAddressString != mDNSNULL) mDNSPlatformMemFree(m->UPnPSOAPAddressString);
- if ((m->UPnPSOAPAddressString = (mDNSu8 *) mDNSPlatformMemAllocate(i+1)) == mDNSNULL) { LogMsg("can't allocate SOAP address string"); return; }
-
- strncpy((char *)m->UPnPSOAPAddressString, ptr, i); // copy the address string
- m->UPnPSOAPAddressString[i] = '\0'; // terminate the string
-
- stop = ptr; // remember where to stop (just after "http://")
- ptr = addrPtr; // move ptr past the rest of what we just processed
-
- // find the port number in the string
- for (addrPtr--;addrPtr>stop;addrPtr--)
+ if (m->UPnPSOAPAddressString == mDNSNULL)
+ {
+ ptr = (char *)tcpInfo->Reply;
+ while (ptr && ptr < end)
{
- if (*addrPtr == ':')
+ if (*ptr == 'U' && (strncasecmp(ptr, "URLBase", 7) == 0)) break;
+ ptr++;
+ }
+
+ if (ptr < end) // found URLBase
+ {
+ LogInfo("handleLNTDeviceDescriptionResponse: found URLBase");
+ ptr += 8; // skip over "URLBase>"
+ // find the end of the URLBase element
+ for (stop = ptr; stop < end; stop++) { if (*stop == '<') { end = stop; break; } }
+ if (ParseHttpUrl(ptr, end, &m->UPnPSOAPAddressString, &m->UPnPSOAPPort, mDNSNULL) != mStatus_NoError)
{
- int port;
- addrPtr++; // skip over ':'
- port = (int)strtol(addrPtr, mDNSNULL, 10);
- m->UPnPSOAPPort = mDNSOpaque16fromIntVal(port); // store it properly converted
- break;
+ LogInfo("handleLNTDeviceDescriptionResponse: failed to parse URLBase");
}
}
- }
-
- if (m->UPnPSOAPAddressString == mDNSNULL) m->UPnPSOAPAddressString = m->UPnPRouterAddressString; // just copy the pointer, don't allocate more memory
- LogOperation("handleLNTDeviceDescriptionResponse: SOAP address string [%s]", m->UPnPSOAPAddressString);
-
- // ptr should now point to the first character we haven't yet processed
- if (ptr != end)
- {
- // allocate the buffer
- if (m->UPnPSOAPURL != mDNSNULL) mDNSPlatformMemFree(m->UPnPSOAPURL);
- if ((m->UPnPSOAPURL = (mDNSu8 *)mDNSPlatformMemAllocate(end - ptr + 1)) == mDNSNULL) { LogMsg("can't mDNSPlatformMemAllocate SOAP URL"); return; }
- // now copy
- strncpy((char *)m->UPnPSOAPURL, ptr, end - ptr); // this URL looks something like "/uuid:0013-108c-4b3f0000f3dc"
- m->UPnPSOAPURL[end - ptr] = '\0'; // terminate the string
+ // if all else fails, use the router address string
+ if (m->UPnPSOAPAddressString == mDNSNULL) AllocAndCopy(&m->UPnPSOAPAddressString, m->UPnPRouterAddressString);
}
+ if (m->UPnPSOAPAddressString == mDNSNULL) LogMsg("handleLNTDeviceDescriptionResponse: UPnPSOAPAddressString is NULL");
+ else LogInfo("handleLNTDeviceDescriptionResponse: SOAP address string [%s]", m->UPnPSOAPAddressString);
- // if we get to the end and haven't found the URL fill in the defaults
- if (m->UPnPSOAPURL == mDNSNULL) m->UPnPSOAPURL = m->UPnPRouterURL; // just copy the pointer, don't allocate more memory
-
- LogOperation("handleLNTDeviceDescriptionResponse: SOAP URL [%s] port %d", m->UPnPSOAPURL, mDNSVal16(m->UPnPSOAPPort));
+ if (m->UPnPSOAPURL == mDNSNULL) AllocAndCopy(&m->UPnPSOAPURL, m->UPnPRouterURL);
+ if (m->UPnPSOAPURL == mDNSNULL) LogMsg("handleLNTDeviceDescriptionResponse: UPnPSOAPURL is NULL");
+ else LogInfo("handleLNTDeviceDescriptionResponse: SOAP URL [%s]", m->UPnPSOAPURL);
}
mDNSlocal void handleLNTGetExternalAddressResponse(tcpLNTInfo *tcpInfo)
mDNS *m = tcpInfo->m;
mDNSu16 err = NATErr_None;
mDNSv4Addr ExtAddr;
- char *ptr = (char *)tcpInfo->Reply;
- char *end = (char *)tcpInfo->Reply + tcpInfo->nread;
- char *addrend;
+ mDNSu8 *ptr = (mDNSu8*)tcpInfo->Reply;
+ mDNSu8 *end = (mDNSu8*)tcpInfo->Reply + tcpInfo->nread;
+ mDNSu8 *addrend;
static char tagname[20] = "NewExternalIPAddress"; // Array NOT including a terminating nul
-// LogOperation("handleLNTGetExternalAddressResponse: %s", ptr);
+// LogInfo("handleLNTGetExternalAddressResponse: %s", ptr);
- while (ptr < end && strncasecmp(ptr, tagname, sizeof(tagname))) ptr++;
+ mDNSs16 http_result = ParseHTTPResponseCode(&ptr, end); // Note: modifies ptr
+ if (http_result == HTTPCode_404) LNT_ClearState(m);
+ if (http_result != HTTPCode_200)
+ {
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.AddressRequest", "noop", "HTTP Result", "HTTP code: %d", http_result);
+ return;
+ }
+
+
+ while (ptr < end && strncasecmp((char*)ptr, tagname, sizeof(tagname))) ptr++;
ptr += sizeof(tagname); // Skip over "NewExternalIPAddress"
while (ptr < end && *ptr != '>') ptr++;
ptr += 1; // Skip over ">"
// Find the end of the address and terminate the string so inet_pton() can convert it
addrend = ptr;
- while (addrend < end && (mdnsIsDigit(*addrend) || *addrend == '.')) addrend++;
+ while (addrend < end && (mDNSIsDigit(*addrend) || *addrend == '.')) addrend++;
if (addrend >= end) return;
*addrend = 0;
- if (inet_pton(AF_INET, ptr, &ExtAddr) <= 0)
- { LogMsg("handleLNTGetExternalAddressResponse: Router returned bad address %s", ptr); err = NATErr_NetFail; }
- if (!err) LogOperation("handleLNTGetExternalAddressResponse: External IP address is %.4a", &ExtAddr);
+ if (inet_pton(AF_INET, (char*)ptr, &ExtAddr) <= 0)
+ {
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.AddressRequest", "noop", "inet_pton", "");
+ LogMsg("handleLNTGetExternalAddressResponse: Router returned bad address %s", ptr);
+ err = NATErr_NetFail;
+ ExtAddr = zerov4Addr;
+ }
+ if (!err) LogInfo("handleLNTGetExternalAddressResponse: External IP address is %.4a", &ExtAddr);
natTraversalHandleAddressReply(m, err, ExtAddr);
}
{
mDNS *m = tcpInfo->m;
mDNSIPPort extport = zeroIPPort;
- char *ptr = (char *)tcpInfo->Reply;
- char *end = (char *)tcpInfo->Reply + tcpInfo->nread;
+ mDNSu8 *ptr = (mDNSu8*)tcpInfo->Reply;
+ mDNSu8 *end = (mDNSu8*)tcpInfo->Reply + tcpInfo->nread;
NATTraversalInfo *natInfo;
+ mDNSs16 http_result;
for (natInfo = m->NATTraversals; natInfo; natInfo=natInfo->next) { if (natInfo == tcpInfo->parentNATInfo) break; }
- if (!natInfo) { LogOperation("handleLNTPortMappingResponse: can't find matching tcpInfo in NATTraversals!"); return; }
+ if (!natInfo) { LogInfo("handleLNTPortMappingResponse: can't find matching tcpInfo in NATTraversals!"); return; }
- // start from the beginning of the HTTP header; find "200 OK" status message; if the first characters after the
- // space are not "200" then this is an error message or invalid in some other way
- // if the error is "500" this is an internal server error
- while (ptr && ptr != end)
+ http_result = ParseHTTPResponseCode(&ptr, end); // Note: modifies ptr
+ if (http_result == HTTPCode_200)
+ {
+ LogInfo("handleLNTPortMappingResponse: got a valid response, sending reply to natTraversalHandlePortMapReply(internal %d external %d retries %d)",
+ mDNSVal16(natInfo->IntPort), RequestedPortNum(natInfo), tcpInfo->retries);
+
+ // Make sure to compute extport *before* we zero tcpInfo->retries
+ extport = mDNSOpaque16fromIntVal(RequestedPortNum(natInfo));
+ tcpInfo->retries = 0;
+ natTraversalHandlePortMapReply(m, natInfo, m->UPnPInterfaceID, mStatus_NoError, extport, NATMAP_DEFAULT_LEASE);
+ }
+ else if (http_result == HTTPCode_500)
{
- if (*ptr == ' ')
+ while (ptr && ptr != end)
{
- ptr++;
- if (ptr == end) { LogOperation("handleLNTPortMappingResponse: past end of buffer!"); return; }
- if (strncasecmp(ptr, "200", 3) == 0) break;
- else if (strncasecmp(ptr, "500", 3) == 0)
+ if (((*ptr == 'c' || *ptr == 'C') && end - ptr >= 8 && strncasecmp((char*)ptr, "Conflict", 8) == 0) || (*ptr == '>' && end - ptr >= 15 && strncasecmp((char*)ptr, ">718</errorCode", 15) == 0))
{
- // now check to see if this was a port mapping conflict
- while (ptr && ptr != end)
+ if (tcpInfo->retries < 100)
+ {
+ tcpInfo->retries++; SendPortMapRequest(tcpInfo->m, natInfo);
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", "noop", "Conflict", "Retry %d", tcpInfo->retries);
+ }
+ else
{
- if ((*ptr == 'c' || *ptr == 'C') && strncasecmp(ptr, "Conflict", 8) == 0)
- {
- if (tcpInfo->retries < 100)
- { tcpInfo->retries++; SendPortMapRequest(tcpInfo->m, natInfo); }
- else
- {
- LogMsg("handleLNTPortMappingResponse too many conflict retries %d %d", mDNSVal16(natInfo->IntPort), mDNSVal16(natInfo->RequestedPort));
- natTraversalHandlePortMapReply(m, natInfo, m->UPnPInterfaceID, NATErr_Refused, zeroIPPort, 0);
- }
- return;
- }
- ptr++;
+ LogMsg("handleLNTPortMappingResponse too many conflict retries %d %d", mDNSVal16(natInfo->IntPort), mDNSVal16(natInfo->RequestedPort));
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", "noop", "Conflict - too many retries", "Retries: %d", tcpInfo->retries);
+ natTraversalHandlePortMapReply(m, natInfo, m->UPnPInterfaceID, NATErr_Res, zeroIPPort, 0);
}
- break; // out of HTTP status search
+ return;
}
+ ptr++;
}
- ptr++;
}
- if (ptr == mDNSNULL || ptr == end) return;
-
- LogOperation("handleLNTPortMappingResponse: got a valid response, sending reply to natTraversalHandlePortMapReply(internal %d external %d retries %d)",
- mDNSVal16(natInfo->IntPort), RequestedPortNum(natInfo), tcpInfo->retries);
-
- // Make sure to compute extport *before* we zero tcpInfo->retries
- extport = mDNSOpaque16fromIntVal(RequestedPortNum(natInfo));
- tcpInfo->retries = 0;
- natTraversalHandlePortMapReply(m, natInfo, m->UPnPInterfaceID, mStatus_NoError, extport, NATMAP_DEFAULT_LEASE);
+ else if (http_result == HTTPCode_Bad) LogMsg("handleLNTPortMappingResponse got data that was not a valid HTTP response");
+ else if (http_result == HTTPCode_Other) LogMsg("handleLNTPortMappingResponse got unexpected response code");
+ else if (http_result == HTTPCode_404) LNT_ClearState(m);
+ if (http_result != HTTPCode_200 && http_result != HTTPCode_500)
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", "noop", "HTTP Result", "HTTP code: %d", http_result);
}
mDNSlocal void DisposeInfoFromUnmapList(mDNS *m, tcpLNTInfo *tcpInfo)
long n = 0;
long nsent = 0;
- if (tcpInfo == mDNSNULL) { LogOperation("tcpConnectionCallback: no tcpInfo context"); status = mStatus_Invalid; goto exit; }
+ if (tcpInfo == mDNSNULL) { LogInfo("tcpConnectionCallback: no tcpInfo context"); status = mStatus_Invalid; goto exit; }
// The handlers below expect to be called with the lock held
mDNS_Lock(tcpInfo->m);
- if (err) { LogOperation("tcpConnectionCallback: received error"); goto exit; }
+ if (err) { LogInfo("tcpConnectionCallback: received error"); goto exit; }
if (ConnectionEstablished) // connection is established - send the message
{
- LogOperation("tcpConnectionCallback: connection established, sending message");
+ LogInfo("tcpConnectionCallback: connection established, sending message");
nsent = mDNSPlatformWriteTCP(sock, (char *)tcpInfo->Request, tcpInfo->requestLen);
if (nsent != (long)tcpInfo->requestLen) { LogMsg("tcpConnectionCallback: error writing"); status = mStatus_UnknownErr; goto exit; }
}
else
{
n = mDNSPlatformReadTCP(sock, (char *)tcpInfo->Reply + tcpInfo->nread, tcpInfo->replyLen - tcpInfo->nread, &closed);
- LogOperation("tcpConnectionCallback: mDNSPlatformReadTCP read %d bytes", n);
+ LogInfo("tcpConnectionCallback: mDNSPlatformReadTCP read %d bytes", n);
- if (n < 0) { LogOperation("tcpConnectionCallback - read returned %d", n); status = mStatus_ConnFailed; goto exit; }
- else if (closed) { LogOperation("tcpConnectionCallback: socket closed by remote end %d", tcpInfo->nread); status = mStatus_ConnFailed; goto exit; }
+ if (n < 0) { LogInfo("tcpConnectionCallback - read returned %d", n); status = mStatus_ConnFailed; goto exit; }
+ else if (closed) { LogInfo("tcpConnectionCallback: socket closed by remote end %d", tcpInfo->nread); status = mStatus_ConnFailed; goto exit; }
tcpInfo->nread += n;
- LogOperation("tcpConnectionCallback tcpInfo->nread %d", tcpInfo->nread);
+ LogInfo("tcpConnectionCallback tcpInfo->nread %d", tcpInfo->nread);
if (tcpInfo->nread > LNT_MAXBUFSIZE)
{
- LogOperation("result truncated...");
+ LogInfo("result truncated...");
tcpInfo->nread = LNT_MAXBUFSIZE;
}
exit:
if (err || status)
{
+ mDNS *m = tcpInfo->m;
+ switch (tcpInfo->op)
+ {
+ case LNTDiscoveryOp: if (m->UPnPSOAPAddressString == mDNSNULL)
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "failure", "SOAP Address", "");
+ if (m->UPnPSOAPURL == mDNSNULL)
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "failure", "SOAP path", "");
+ if (m->UPnPSOAPAddressString && m->UPnPSOAPURL)
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "success", "success", "");
+ break;
+ case LNTExternalAddrOp: mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.AddressRequest", mDNSIPv4AddressIsZero(m->ExternalAddress) ? "failure" : "success", mDNSIPv4AddressIsZero(m->ExternalAddress) ? "failure" : "success", "");
+ break;
+ case LNTPortMapOp: if (tcpInfo->parentNATInfo)
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", (tcpInfo->parentNATInfo->Result) ? "failure" : "success",
+ (tcpInfo->parentNATInfo->Result) ? "failure" : "success", "Result: %d", tcpInfo->parentNATInfo->Result);
+ break;
+ case LNTPortMapDeleteOp: break;
+ default: break;
+ }
+
mDNSPlatformTCPCloseConnection(tcpInfo->sock);
tcpInfo->sock = mDNSNULL;
if (tcpInfo->Request) { mDNSPlatformMemFree(tcpInfo->Request); tcpInfo->Request = mDNSNULL; }
info->nread = 0;
info->replyLen = LNT_MAXBUFSIZE;
if (info->Reply != mDNSNULL) mDNSPlatformMemZero(info->Reply, LNT_MAXBUFSIZE); // reuse previously allocated buffer
- else if ((info->Reply = (mDNSs8 *) mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogOperation("can't allocate reply buffer"); return (mStatus_NoMemoryErr); }
+ else if ((info->Reply = (mDNSs8 *) mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogInfo("can't allocate reply buffer"); return (mStatus_NoMemoryErr); }
- if (info->sock) { LogOperation("MakeTCPConnection: closing previous open connection"); mDNSPlatformTCPCloseConnection(info->sock); info->sock = mDNSNULL; }
+ if (info->sock) { LogInfo("MakeTCPConnection: closing previous open connection"); mDNSPlatformTCPCloseConnection(info->sock); info->sock = mDNSNULL; }
info->sock = mDNSPlatformTCPSocket(m, kTCPSocketFlags_Zero, &srcport);
if (!info->sock) { LogMsg("LNT MakeTCPConnection: unable to create TCP socket"); mDNSPlatformMemFree(info->Reply); info->Reply = mDNSNULL; return(mStatus_NoMemoryErr); }
- LogOperation("MakeTCPConnection: connecting to %#a:%d", &info->Address, mDNSVal16(info->Port));
+ LogInfo("MakeTCPConnection: connecting to %#a:%d", &info->Address, mDNSVal16(info->Port));
err = mDNSPlatformTCPConnect(info->sock, Addr, Port, 0, tcpConnectionCallback, info);
if (err == mStatus_ConnPending) err = mStatus_NoError;
else
{
// Don't need to log this in customer builds -- it happens quite often during sleep, wake, configuration changes, etc.
- LogOperation("LNT MakeTCPConnection: connection failed");
+ LogInfo("LNT MakeTCPConnection: connection failed");
mDNSPlatformTCPCloseConnection(info->sock); // Dispose the socket we created with mDNSPlatformTCPSocket() above
info->sock = mDNSNULL;
mDNSPlatformMemFree(info->Reply);
char *body = (char *)&m->omsg; // Typically requires 1110-1122 bytes; m->omsg is 8952 bytes, which is plenty
int bodyLen;
- if (m->UPnPSOAPURL == mDNSNULL || m->UPnPSOAPAddressString == mDNSNULL) // if no SOAP URL or address exists get out here
- { LogOperation("SendSOAPMsgControlAction: no SOAP URL or address string"); return mStatus_Invalid; }
+ if (mDNSIPPortIsZero(m->UPnPSOAPPort) || m->UPnPSOAPURL == mDNSNULL || m->UPnPSOAPAddressString == mDNSNULL) // if no SOAP URL or address exists get out here
+ { LogInfo("SendSOAPMsgControlAction: no SOAP port, URL or address string"); return mStatus_Invalid; }
// Create body
bodyLen = mDNS_snprintf (body, sizeof(m->omsg), body1, Action, m->UPnPWANPPPConnection ? "PPP" : "IP");
}
else
{
- natTraversalHandlePortMapReply(m, n, m->UPnPInterfaceID, NATErr_Refused, zeroIPPort, 0);
+ natTraversalHandlePortMapReply(m, n, m->UPnPInterfaceID, NATErr_Res, zeroIPPort, 0);
return mStatus_NoError;
}
}
propArgs[7].type = "ui4";
propArgs[7].value = "0";
- LogOperation("SendPortMapRequest: internal %u external %u", mDNSVal16(n->IntPort), ReqPortNum);
+ LogInfo("SendPortMapRequest: internal %u external %u", mDNSVal16(n->IntPort), ReqPortNum);
return SendSOAPMsgControlAction(m, &n->tcpInfo, "AddPortMapping", 8, propArgs, LNTPortMapOp);
}
mDNSexport mStatus LNT_MapPort(mDNS *m, NATTraversalInfo *n)
{
- LogOperation("LNT_MapPort");
+ LogInfo("LNT_MapPort");
if (n->tcpInfo.sock) return(mStatus_NoError); // If we already have a connection up don't make another request for the same thing
n->tcpInfo.parentNATInfo = n;
n->tcpInfo.retries = 0;
mStatus err;
// If no NAT gateway to talk to, no need to do all this work for nothing
- if (!m->UPnPSOAPURL || !m->UPnPSOAPAddressString) return mStatus_NoError;
+ if (mDNSIPPortIsZero(m->UPnPSOAPPort) || !m->UPnPSOAPURL || !m->UPnPSOAPAddressString) return mStatus_NoError;
mDNS_snprintf(externalPort, sizeof(externalPort), "%u", mDNSVal16(mDNSIPPortIsZero(n->RequestedPort) ? n->IntPort : n->RequestedPort));
n->tcpInfo.parentNATInfo = n;
// clean up previous port mapping requests and allocations
- if (n->tcpInfo.sock) LogOperation("LNT_UnmapPort: closing previous open connection");
+ if (n->tcpInfo.sock) LogInfo("LNT_UnmapPort: closing previous open connection");
if (n->tcpInfo.sock ) { mDNSPlatformTCPCloseConnection(n->tcpInfo.sock); n->tcpInfo.sock = mDNSNULL; }
if (n->tcpInfo.Request) { mDNSPlatformMemFree(n->tcpInfo.Request); n->tcpInfo.Request = mDNSNULL; }
if (n->tcpInfo.Reply ) { mDNSPlatformMemFree(n->tcpInfo.Reply); n->tcpInfo.Reply = mDNSNULL; }
// make a copy of the tcpInfo that we can clean up later (the one passed in will be destroyed by the client as soon as this returns)
if ((info = mDNSPlatformMemAllocate(sizeof(tcpLNTInfo))) == mDNSNULL)
- { LogOperation("LNT_UnmapPort: can't allocate tcpInfo"); return(mStatus_NoMemoryErr); }
+ { LogInfo("LNT_UnmapPort: can't allocate tcpInfo"); return(mStatus_NoMemoryErr); }
*info = n->tcpInfo;
while (*infoPtr) infoPtr = &(*infoPtr)->next; // find the end of the list
"Connection: close\r\n"
"\r\n";
- if (m->UPnPRouterURL == mDNSNULL || m->UPnPRouterAddressString == mDNSNULL) { LogOperation("GetDeviceDescription: no router URL or address string!"); return (mStatus_Invalid); }
+ if (!mDNSIPPortIsZero(m->UPnPSOAPPort)) return mStatus_NoError; // already have the info we need
+
+ if (m->UPnPRouterURL == mDNSNULL || m->UPnPRouterAddressString == mDNSNULL) { LogInfo("GetDeviceDescription: no router URL or address string!"); return (mStatus_Invalid); }
// build message
if (info->Request != mDNSNULL) mDNSPlatformMemZero(info->Request, LNT_MAXBUFSIZE); // reuse previously allocated buffer
- else if ((info->Request = (mDNSs8 *) mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogOperation("can't allocate send buffer for discovery"); return (mStatus_NoMemoryErr); }
+ else if ((info->Request = (mDNSs8 *) mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogInfo("can't allocate send buffer for discovery"); return (mStatus_NoMemoryErr); }
info->requestLen = mDNS_snprintf((char *)info->Request, LNT_MAXBUFSIZE, szSSDPMsgDescribeDeviceFMT, m->UPnPRouterURL, m->UPnPRouterAddressString);
- LogOperation("Describe Device: [%s]", info->Request);
+ LogInfo("Describe Device: [%s]", info->Request);
return MakeTCPConnection(m, info, &m->Router, m->UPnPRouterPort, LNTDiscoveryOp);
}
{
char *ptr = (char *)data;
char *end = (char *)data + len;
+ char *stop = ptr;
+
+ if (!mDNSIPPortIsZero(m->UPnPRouterPort)) return; // already have the info we need
// The formatting of the HTTP header is not always the same when it comes to the placement of
// the service and location strings, so we just look for each of them from the beginning for every response
ptr = (char *)data;
while (ptr && ptr != end)
{
- if (*ptr == 'L' && (strncasecmp(ptr, "Location", 8) == 0)) break; // find the first 'L'; is this Location? if not, keep looking
+ if (*ptr == 'L' && (strncasecmp(ptr, "Location:", 9) == 0)) break; // find the first 'L'; is this Location? if not, keep looking
ptr++;
}
- if (ptr == mDNSNULL || ptr == end) return; // not a message we care about
+ if (ptr == mDNSNULL || ptr == end)
+ {
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Location", "");
+ return; // not a message we care about
+ }
+ ptr += 9; //Skip over 'Location:'
+ while (*ptr == ' ' && ptr < end) ptr++; // skip over spaces
+ if (ptr >= end) return;
- // find "http://", starting from where we left off
- while (ptr && ptr != end)
+ // find the end of the line
+ for (stop = ptr; stop != end; stop++) { if (*stop == '\r') { end = stop; break; } }
+
+ // fill in default port
+ m->UPnPRouterPort = mDNSOpaque16fromIntVal(80);
+
+ // free string pointers and set to NULL
+ if (m->UPnPRouterAddressString != mDNSNULL)
{
- if (*ptr == 'h' && (strncasecmp(ptr, "http://", 7) == 0)) // find the first 'h'; is this a URL? if not, keep looking
- {
- int i;
- char *addrPtr = mDNSNULL;
-
- ptr += 7; //skip over "http://"
- if (ptr >= end) { LogOperation("LNT_ConfigureRouterInfo: past end of buffer and no URL!"); return; }
- addrPtr = ptr;
- for (i = 0; addrPtr && addrPtr != end; i++, addrPtr++) if (*addrPtr == '/') break; // first find the beginning of the URL and count the chars
- if (addrPtr == mDNSNULL || addrPtr == end) return; // not a valid message
+ mDNSPlatformMemFree(m->UPnPRouterAddressString);
+ m->UPnPRouterAddressString = mDNSNULL;
+ }
+ if (m->UPnPRouterURL != mDNSNULL)
+ {
+ mDNSPlatformMemFree(m->UPnPRouterURL);
+ m->UPnPRouterURL = mDNSNULL;
+ }
- // allocate the buffer (len i+1 so we have space to terminate the string)
- if (m->UPnPRouterAddressString != mDNSNULL) mDNSPlatformMemFree(m->UPnPRouterAddressString);
- if ((m->UPnPRouterAddressString = (mDNSu8 *) mDNSPlatformMemAllocate(i+1)) == mDNSNULL) { LogMsg("can't mDNSPlatformMemAllocate router address string"); return; }
-
- strncpy((char *)m->UPnPRouterAddressString, ptr, i); // copy the address string
- m->UPnPRouterAddressString[i] = '\0'; // terminate the string
- LogOperation("LNT_ConfigureRouterInfo: router address string [%s]", m->UPnPRouterAddressString);
- break;
- }
- ptr++; // continue
+ // the Router URL should look something like "/dyndev/uuid:0013-108c-4b3f0000f3dc"
+ if (ParseHttpUrl(ptr, end, &m->UPnPRouterAddressString, &m->UPnPRouterPort, &m->UPnPRouterURL) != mStatus_NoError)
+ {
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Parse URL", "");
+ return;
}
- // find port and router URL, starting after the "http://" if it was there
- while (ptr && ptr != end)
+ m->UPnPInterfaceID = InterfaceID;
+
+ if (m->UPnPRouterAddressString == mDNSNULL)
{
- if (*ptr == ':') // found the port number
- {
- int port;
- ptr++; // skip over ':'
- if (ptr == end) { LogOperation("LNT_ConfigureRouterInfo: reached end of buffer and no address!"); return; }
- port = (int)strtol(ptr, (char **)mDNSNULL, 10); // get the port
- m->UPnPRouterPort = mDNSOpaque16fromIntVal(port); // store it properly converted
- }
- else if (*ptr == '/') // found router URL
- {
- int j;
- char *urlPtr;
- m->UPnPInterfaceID = InterfaceID;
- if (mDNSIPPortIsZero(m->UPnPRouterPort)) m->UPnPRouterPort = mDNSOpaque16fromIntVal(80); // fill in default port if we didn't find one before
-
- urlPtr = ptr;
- for (j = 0; urlPtr && urlPtr != end; j++, urlPtr++) if (*urlPtr == '\r') break; // first find the end of the line and count the chars
- if (urlPtr == mDNSNULL || urlPtr == end) return; // not a valid message
-
- // allocate the buffer (len j+1 so we have space to terminate the string)
- if (m->UPnPRouterURL != mDNSNULL) mDNSPlatformMemFree(m->UPnPRouterURL);
- if ((m->UPnPRouterURL = (mDNSu8 *) mDNSPlatformMemAllocate(j+1)) == mDNSNULL) { LogMsg("can't allocate router URL"); return; }
-
- // now copy everything to the end of the line
- strncpy((char *)m->UPnPRouterURL, ptr, j); // this URL looks something like "/dyndev/uuid:0013-108c-4b3f0000f3dc"
- m->UPnPRouterURL[j] = '\0'; // terminate the string
- break; // we've got everything we need, so get out here
- }
- ptr++; // continue
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Router address", "");
+ LogMsg("LNT_ConfigureRouterInfo: UPnPRouterAddressString is NULL");
}
+ else LogInfo("LNT_ConfigureRouterInfo: Router address string [%s]", m->UPnPRouterAddressString);
+
+ if (m->UPnPRouterURL == mDNSNULL)
+ {
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Router path", "");
+ LogMsg("LNT_ConfigureRouterInfo: UPnPRouterURL is NULL");
+ }
+ else LogInfo("LNT_ConfigureRouterInfo: Router URL [%s]", m->UPnPRouterURL);
+
+ LogInfo("LNT_ConfigureRouterInfo: Router port %d", mDNSVal16(m->UPnPRouterPort));
+ LogInfo("LNT_ConfigureRouterInfo: Router interface %d", m->UPnPInterfaceID);
- if (ptr == mDNSNULL || ptr == end) return; // not a valid message
- LogOperation("Router port %d, URL set to [%s]...", mDNSVal16(m->UPnPRouterPort), m->UPnPRouterURL);
-
// Don't need the SSDP socket anymore
- if (m->SSDPSocket) { LogOperation("LNT_ConfigureRouterInfo destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
+ if (m->SSDPSocket) { debugf("LNT_ConfigureRouterInfo destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "success", "success", "");
// now send message to get the device description
GetDeviceDescription(m, &m->tcpDeviceInfo);
}
mDNSu8* buf = (mDNSu8*)&m->omsg; //m->omsg is 8952 bytes, which is plenty
unsigned int bufLen;
+
+ if (!mDNSIPPortIsZero(m->UPnPRouterPort))
+ {
+ if (m->SSDPSocket) { debugf("LNT_SendDiscoveryMsg destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
+ if (mDNSIPPortIsZero(m->UPnPSOAPPort) && !m->tcpDeviceInfo.sock) GetDeviceDescription(m, &m->tcpDeviceInfo);
+ return;
+ }
// Always query for WANIPConnection in the first SSDP packet
if (m->retryIntervalGetAddr <= NATMAP_INIT_RETRY) m->SSDPWANPPPConnection = mDNSfalse;
// Create message
bufLen = mDNS_snprintf((char*)buf, sizeof(m->omsg), msg, m->SSDPWANPPPConnection ? "PPP" : "IP");
- LogOperation("LNT_SendDiscoveryMsg Router %.4a Current External Address %.4a", &m->Router.ip.v4, &m->ExternalAddress);
+ debugf("LNT_SendDiscoveryMsg Router %.4a Current External Address %.4a", &m->Router.ip.v4, &m->ExternalAddress);
- if (!mDNSIPv4AddressIsZero(m->Router.ip.v4) && mDNSIPv4AddressIsZero(m->ExternalAddress))
+ if (!mDNSIPv4AddressIsZero(m->Router.ip.v4))
{
- if (!m->SSDPSocket) { m->SSDPSocket = mDNSPlatformUDPSocket(m, zeroIPPort); LogOperation("LNT_SendDiscoveryMsg created SSDPSocket %p", &m->SSDPSocket); }
+ if (!m->SSDPSocket) { m->SSDPSocket = mDNSPlatformUDPSocket(m, zeroIPPort); debugf("LNT_SendDiscoveryMsg created SSDPSocket %p", &m->SSDPSocket); }
mDNSPlatformSendUDP(m, buf, buf + bufLen, 0, m->SSDPSocket, &m->Router, SSDPPort);
mDNSPlatformSendUDP(m, buf, buf + bufLen, 0, m->SSDPSocket, &multicastDest, SSDPPort);
}
m->SSDPWANPPPConnection = !m->SSDPWANPPPConnection;
}
+mDNSexport void LNT_ClearState(mDNS *const m)
+ {
+ if (m->tcpAddrInfo.sock) { mDNSPlatformTCPCloseConnection(m->tcpAddrInfo.sock); m->tcpAddrInfo.sock = mDNSNULL; }
+ if (m->tcpDeviceInfo.sock) { mDNSPlatformTCPCloseConnection(m->tcpDeviceInfo.sock); m->tcpDeviceInfo.sock = mDNSNULL; }
+ m->UPnPSOAPPort = m->UPnPRouterPort = zeroIPPort; // Reset UPnP ports
+ }
+
#endif /* _LEGACY_NAT_TRAVERSAL_ */
Change History (most recent first):
$Log: ConfigurationAuthority.c,v $
+Revision 1.3 2008/06/26 17:34:18 mkrochma
+<rdar://problem/6030630> Pref pane destroying shared "system.preferences" authorization right
+
Revision 1.2 2005/08/07 22:48:05 mkrochma
<rdar://problem/4204003> Bonjour Pref Pane returns -927 when "system.preferences" is not shared
OSStatus ReleaseAuthority(void)
/* Discard authority to perform operations */
{
- (void) AuthorizationFree( gAuthRef, kAuthorizationFlagDestroyRights);
+ (void) AuthorizationFree( gAuthRef, kAuthorizationFlagDefaults);
gAuthRef = 0;
return AuthorizationCreate( (AuthorizationRights*) NULL, (AuthorizationEnvironment*) NULL,
(AuthorizationFlags) 0, &gAuthRef);
Change History (most recent first):
$Log: DNSServiceDiscoveryPref.m,v $
+Revision 1.16 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
+Revision 1.15 2008/08/18 17:57:04 mcguire
+<rdar://problem/6156209> build error
+
+Revision 1.14 2008/07/18 17:39:14 cheshire
+If NSInteger is not defined (indicated by lack of definition for NSINTEGER_DEFINED)
+then #define "NSInteger" to be "int" like it used to be
+
+Revision 1.13 2008/07/01 01:40:01 mcguire
+<rdar://problem/5823010> 64-bit fixes
+
+Revision 1.12 2008/05/08 00:46:38 cheshire
+<rdar://problem/5919272> GetNextLabel insufficiently defensive
+User shared copy of GetNextLabel in ClientCommon.c instead of having a local copy here
+
Revision 1.11 2007/11/30 23:42:09 cheshire
Fixed compile warning: declaration of 'index' shadows a global declaration
#import "PrivilegedOperations.h"
#import <unistd.h>
+#include "../../Clients/ClientCommon.h"
+
+#ifndef NSINTEGER_DEFINED
+#define NSInteger int
+#endif
+
@implementation DNSServiceDiscoveryPref
-static int
+static NSComparisonResult
MyArrayCompareFunction(id val1, id val2, void *context)
{
(void)context; // Unused
}
-static int
+static NSComparisonResult
MyDomainArrayCompareFunction(id val1, id val2, void *context)
{
(void)context; // Unused
}
-static const char *
-GetNextLabel(const char *cstr, char label[64])
-{
- char *ptr = label;
- while (*cstr && *cstr != '.') // While we have characters in the label...
- {
- char c = *cstr++;
- if (c == '\\')
- {
- c = *cstr++;
- if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
- {
- int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
- int v1 = cstr[ 0] - '0';
- int v2 = cstr[ 1] - '0';
- int val = v0 * 100 + v1 * 10 + v2;
- if (val <= 255) { c = (char)val; cstr += 2; } // If valid three-digit decimal value, use it
- }
- }
- *ptr++ = c;
- if (ptr >= label+64) return(NULL);
- }
- if (*cstr) cstr++; // Skip over the trailing dot (if present)
- *ptr++ = 0;
- return(cstr);
-}
-
-
static void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
{
(void)store; // Unused
-- (int)numberOfRowsInTableView:(NSTableView *)tableView;
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView;
{
(void)tableView; // Unused
int numberOfRows = 0;
}
-- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row;
+- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
{
(void)tableView; // Unused
NSDictionary *browseDomainDict;
[self startDomainBrowsing];
[self watchForPreferenceChanges];
- [tabView setDelegate:self];
-
InitConfigAuthority();
err = EnsureToolInstalled();
if (err == noErr) toolInstalled = YES;
- else fprintf(stderr, "EnsureToolInstalled returned %ld\n", err);
+ else { long int tmp = err; fprintf(stderr, "EnsureToolInstalled returned %ld\n", tmp); }
}
}
-- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
+- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row;
{
(void)row; // Unused
(void)tableView; // Unused
// The "@(#) " pattern is a special prefix the "what" command looks for
const char VersionString_SCCS[] = "@(#) Bonjour Preference Pane " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = VersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
Change History (most recent first):
$Log: PrivilegedOperations.c,v $
+Revision 1.9 2008/06/26 17:34:18 mkrochma
+<rdar://problem/6030630> Pref pane destroying shared "system.preferences" authorization right
+
Revision 1.8 2007/11/30 23:42:33 cheshire
Fixed compile warning: declaration of 'status' shadows a previous local
err = -1;
}
}
- (void) AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
+ (void) AuthorizationFree(authRef, kAuthorizationFlagDefaults);
}
}
Change History (most recent first):
$Log: ddnswriteconfig.m,v $
+Revision 1.13 2008/11/04 20:08:44 cheshire
+Use constant kDNSServiceMaxDomainName instead of literal value "1005"
+
+Revision 1.12 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
+Revision 1.11 2008/06/26 17:34:18 mkrochma
+<rdar://problem/6030630> Pref pane destroying shared "system.preferences" authorization right
+
Revision 1.10 2007/11/30 23:43:04 cheshire
Fixed compile warning: declaration of 'access' shadows a global declaration
#import <sys/stat.h>
#import <sys/mman.h>
#import <mach-o/dyld.h>
+#import <dns_sd.h>
#import <AssertMacros.h>
#import <Security/Security.h>
#import <CoreServices/CoreServices.h>
require( len == kAuthorizationExternalFormLength, ReadParamsFailed);
if (gAuthRef != 0) {
- (void) AuthorizationFree(gAuthRef, kAuthorizationFlagDestroyRights);
+ (void) AuthorizationFree(gAuthRef, kAuthorizationFlagDefaults);
gAuthRef = 0;
}
int result = 0;
u_int32_t tag, len;
char *p;
- char keyname[1005];
- char domain[1005];
- char secret[1005];
+ char keyname[kDNSServiceMaxDomainName];
+ char domain[kDNSServiceMaxDomainName];
+ char secret[kDNSServiceMaxDomainName];
AuthorizationItem kcAuth = { EDIT_SYS_KEYCHAIN_RIGHT, 0, NULL, 0 };
AuthorizationRights authSet = { 1, &kcAuth };
secretString = (CFStringRef)CFDictionaryGetValue(secretDictionary, SC_DYNDNS_SECRET_KEY);
assert(secretString != NULL);
- CFStringGetCString(keyNameString, keyname, 1005, kCFStringEncodingUTF8);
- CFStringGetCString(domainString, domain, 1005, kCFStringEncodingUTF8);
- CFStringGetCString(secretString, secret, 1005, kCFStringEncodingUTF8);
+ CFStringGetCString(keyNameString, keyname, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
+ CFStringGetCString(domainString, domain, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
+ CFStringGetCString(secretString, secret, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
result = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
if (result == noErr) {
// The "@(#) " pattern is a special prefix the "what" command looks for
const char VersionString_SCCS[] = "@(#) ddnswriteconfig " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = VersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
Change History (most recent first):
$Log: SamplemDNSClient.c,v $
+Revision 1.56 2008/10/22 02:59:58 mkrochma
+<rdar://problem/6309616> Fix errors compiling mDNS tool caused by BIND8 removal
+
+Revision 1.55 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
Revision 1.54 2007/11/30 23:39:55 cheshire
Fixed compile warning: declaration of 'client' shadows a global declaration
*/
#include <libc.h>
-#define BIND_8_COMPAT
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <net/if.h>
switch (addtest)
{
case 0: printf("Adding Test HINFO record\n");
- record = DNSServiceRegistrationAddRecord(client, T_HINFO, sizeof(myhinfo9), &myhinfo9[0], 120);
+ record = DNSServiceRegistrationAddRecord(client, ns_t_hinfo, sizeof(myhinfo9), &myhinfo9[0], 120);
addtest = 1;
break;
case 1: printf("Updating Test HINFO record\n");
case 'N':
{
printf("Adding big NULL record\n");
- DNSServiceRegistrationAddRecord(client, T_NULL, sizeof(bigNULL), &bigNULL[0], 120);
+ DNSServiceRegistrationAddRecord(client, ns_t_null, sizeof(bigNULL), &bigNULL[0], 120);
CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
}
break;
printf("Registering Service Test._testdualtxt._tcp.local.\n");
client = DNSServiceRegistrationCreate("", "_testdualtxt._tcp.", "", registerPort.NotAnInteger, TXT1, reg_reply, nil);
// use "sizeof(TXT2)-1" because we don't wan't the C compiler's null byte on the end of the string
- record = DNSServiceRegistrationAddRecord(client, T_TXT, sizeof(TXT2)-1, TXT2, 120);
+ record = DNSServiceRegistrationAddRecord(client, ns_t_txt, sizeof(TXT2)-1, TXT2, 120);
break;
}
// The "@(#) " pattern is a special prefix the "what" command looks for
const char VersionString_SCCS[] = "@(#) mDNS " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = VersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
Change History (most recent first):
$Log: daemon.c,v $
+Revision 1.434 2009/06/27 00:55:27 cheshire
+Added code for displaying the size of various structures like CacheRecord and CacheGroup
+
+Revision 1.433 2009/06/25 23:36:57 cheshire
+To facilitate testing, added command-line switch "-OfferSleepProxyService"
+to re-enable the previously-supported mode of operation where we offer
+sleep proxy service on desktop Macs that are set to never sleep.
+
+Revision 1.432 2009/05/13 17:25:33 mkrochma
+<rdar://problem/6879926> Should not schedule maintenance wake when machine has no advertised services
+Sleep proxy client should only look for services being advertised via Multicast
+
+Revision 1.431 2009/05/12 23:21:18 cheshire
+<rdar://problem/6879926> Should not schedule maintenance wake when machine has no advertised services
+Use mDNSCoreHaveAdvertisedServices routine to determine whether we should schedule a maintenance wake
+
+Revision 1.430 2009/05/01 19:17:36 cheshire
+<rdar://problem/6501561> Sleep Proxy: Reduce the frequency of maintenance wakes: ODD, fans, power
+
+Revision 1.429 2009/04/30 20:07:50 mcguire
+<rdar://problem/6822674> Support multiple UDSs from launchd
+
+Revision 1.428 2009/04/22 19:43:37 cheshire
+To facilitate debugging, added -DebugLogging and -UnicastPacketLogging switches
+as launch-time alternatives to sending SIGUSR1 and SIGUSR2 signals later
+
+Revision 1.427 2009/04/22 01:19:57 jessic2
+<rdar://problem/6814585> Daemon: mDNSResponder is logging garbage for error codes because it's using %ld for int 32
+
+Revision 1.426 2009/04/20 19:25:26 cheshire
+For readability, changed "nomulticastadvertisements" to "NoMulticastAdvertisements"
+
+Revision 1.425 2009/04/20 19:17:19 cheshire
+Added a comment explaining why we don't need our CatchABRT handler on 10.5 and later
+
+Revision 1.424 2009/04/17 19:10:27 mcguire
+<rdar://problem/6802833> May still ping-pong with kernel when a framework calls abort()
+
+Revision 1.423 2009/04/16 16:03:08 mcguire
+<rdar://problem/6792024> abort() causes high CPU usage instead of crash & restart
+
+Revision 1.422 2009/04/11 01:43:28 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.421 2009/04/11 00:20:06 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.420 2009/03/20 23:53:03 jessic2
+<rdar://problem/6646228> SIGHUP should restart all in-progress queries
+
+Revision 1.419 2009/03/20 21:30:04 cheshire
+<rdar://problem/6705866> Crash passing invalid parameters to DNSServiceBrowserCreate()
+Do not append a new question to the browser list until *after* we verify that mDNS_StartBrowse() succeeded
+
+Revision 1.418 2009/03/17 21:32:15 cheshire
+Improved "DHCPWakeTime: SCDynamicStoreCopyDHCPInfo failed" error message
+
+Revision 1.417 2009/03/17 01:25:39 cheshire
+<rdar://problem/6601427> Sleep Proxy: Retransmit and retry Sleep Proxy Server requests
+In SIGINFO output, show three best Sleep Proxies
+
+Revision 1.416 2009/02/21 01:47:36 cheshire
+<rdar://problem/6600825> Race condition when sleep initiated and then immediately canceled
+
+Revision 1.415 2009/02/21 01:45:33 cheshire
+Move declaration of "mDNSs32 interval"
+
+Revision 1.414 2009/02/14 00:05:32 cheshire
+Left-justify interface names
+
+Revision 1.413 2009/02/13 18:16:05 cheshire
+Fixed some compile warnings
+
+Revision 1.412 2009/02/13 06:34:41 cheshire
+Converted LogOperation messages to LogInfo or LogSPS
+
+Revision 1.411 2009/02/12 20:57:26 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.410 2009/02/11 02:32:18 cheshire
+m->p->SystemWakeForNetworkAccessEnabled renamed to m->SystemWakeOnLANEnabled
+
+Revision 1.409 2009/02/09 21:16:14 cheshire
+Improved debugging messages
+
+Revision 1.408 2009/02/07 06:08:44 cheshire
+Commented out testing code
+
+Revision 1.407 2009/02/07 02:57:31 cheshire
+<rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+
+Revision 1.406 2009/02/06 03:06:49 mcguire
+<rdar://problem/5858533> Adopt vproc_transaction API in mDNSResponder
+
+Revision 1.405 2009/02/04 23:00:28 cheshire
+Move logic for deciding when to next wake up into a subroutine called AllowSleepNow
+
+Revision 1.404 2009/02/02 22:18:32 cheshire
+If we wake up and find no wireless network, don't just give up and go back to sleep and never try again
+
+Revision 1.403 2009/01/15 21:58:18 cheshire
+Stop using ifa_name field of NetworkInterfaceInfoOSX structure, because it will be going away
+
+Revision 1.402 2009/01/07 23:08:18 cheshire
+Updated debugging messages and comments
+
+Revision 1.401 2008/12/17 05:05:26 cheshire
+Fixed alignment of NAT mapping syslog messages
+
+Revision 1.400 2008/12/10 19:30:57 cheshire
+Use symbolic name OSXVers_10_3_Panther in version check instead of literal integer "7"
+
+Revision 1.399 2008/12/10 02:13:04 cheshire
+Fix alignment of SIGINFO output for longer interface names like "bridge0"
+
+Revision 1.398 2008/12/04 21:08:51 mcguire
+<rdar://problem/6116863> mDNS: Provide mechanism to disable Multicast advertisements
+
+Revision 1.397 2008/12/04 02:18:50 cheshire
+Improved sleep/wake debugging messages
+
+Revision 1.396 2008/11/26 23:37:44 cheshire
+Use SCDynamicStoreCopyDHCPInfo to compute desired wakeup time for our next DHCP lease renewal
+
+Revision 1.395 2008/11/14 21:56:31 cheshire
+Moved debugging routine ShowTaskSchedulingError() from daemon.c into DNSCommon.c
+
+Revision 1.394 2008/11/14 02:20:03 cheshire
+Include m->NextScheduledSPS in task scheduling calculations
+
+Revision 1.393 2008/11/14 01:22:38 cheshire
+Include SPS-registered records when computing the next required wakeup time
+
+Revision 1.392 2008/11/11 01:55:16 cheshire
+Improved comments; minium requested sleep is 60 seconds
+
+Revision 1.391 2008/11/04 02:29:55 cheshire
+Clear interface list before sleeping
+
+Revision 1.390 2008/11/02 21:22:05 cheshire
+Changed mallocL size parameter back to "unsigned int"
+
+Revision 1.389 2008/11/02 21:14:58 cheshire
+Fixes to make mallocL/freeL debugging checks work on 64-bit
+
+Revision 1.388 2008/10/31 23:05:30 cheshire
+Move logic to decide when to at as Sleep Proxy Server from daemon.c to mDNSMacOSX.c
+
+Revision 1.387 2008/10/30 01:08:18 cheshire
+After waking for network maintenance operations go back to sleep again
+
+Revision 1.386 2008/10/29 22:03:39 cheshire
+Compute correct required wakeup time for NAT traversals and uDNS-registered records
+
+Revision 1.385 2008/10/28 20:40:13 cheshire
+Now that the BPF code in mDNSMacOSX.c makes its own CFSocketCreateWithNative directly, the
+udsSupportAddFDToEventLoop/udsSupportRemoveFDFromEventLoop routines can go back to using kqueue
+
+Revision 1.384 2008/10/27 22:22:59 cheshire
+Extra sanity checking in udsSupportAddFDToEventLoop/udsSupportRemoveFDFromEventLoop
+
+Revision 1.383 2008/10/27 07:24:53 cheshire
+Need a "usleep(1000)" (workaround for <rdar://problem/3585273>) to avoid crashes
+
+Revision 1.382 2008/10/24 01:51:48 cheshire
+Before going to sleep, request a future wakeup to renew NAT-PMP mappings, SPS registrations, etc.
+
+Revision 1.381 2008/10/23 22:25:58 cheshire
+Renamed field "id" to more descriptive "updateid"
+
+Revision 1.380 2008/10/23 02:25:08 cheshire
+Added locking in InternetSharingChanged()
+
+Revision 1.379 2008/10/22 23:23:59 cheshire
+Moved definition of OSXVers from daemon.c into mDNSMacOSX.c
+
+Revision 1.378 2008/10/22 19:55:35 cheshire
+Miscellaneous fixes; renamed FindFirstAnswerInCache to FindSPSInCache
+
+Revision 1.377 2008/10/22 17:17:22 cheshire
+Need to open and close BPF fds when turning Sleep Proxy Server on and off
+
+Revision 1.376 2008/10/22 01:42:39 cheshire
+Before allowing sleep, delay until NetWakeResolve queries have completed
+
+Revision 1.375 2008/10/20 22:31:31 cheshire
+Instead of requesting a single BPF descriptor via mDNSRequestBPF(), call mDNSMacOSXNetworkChanged()
+to signal that UDS is now available to handle BPF requests, and let it work out what it needs
+
+Revision 1.374 2008/10/16 22:40:48 cheshire
+Removed "usleep(100000);" from CFSCallBack()
+
+Revision 1.373 2008/10/16 20:49:30 cheshire
+When kevent/kqueue fails, fall back to using old CFSocket RunLoopSource instead
+
+Revision 1.372 2008/10/15 00:03:21 cheshire
+When finally going to sleep, update m->SleepState from SleepState_Transferring to SleepState_Sleeping
+
+Revision 1.371 2008/10/14 19:09:53 cheshire
+When going to sleep, delay sleep until we've got our acknowledgment from the SPS
+
+Revision 1.370 2008/10/09 22:32:27 cheshire
+Include MAC address in interface listing in SIGINFO output
+
+Revision 1.369 2008/10/09 19:32:39 cheshire
+Updated SIGINFO output to indicate whether we've found a sleep proxy server on a given interface
+Hollow sun with rays "☼" indicates we're still looking; solid sun with rays "☀" indicates we found one
+
+Revision 1.368 2008/10/03 21:23:17 mkrochma
+Fix crash by not passing NULL to CFGetTypeID
+
+Revision 1.367 2008/10/03 18:25:17 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
+Revision 1.366 2008/10/03 00:34:55 cheshire
+<rdar://problem/6134215> Mac with Internet Sharing should also offer Sleep Proxy service
+Start and stop Sleep Proxy service when user starts and stops Internet Sharing
+
+Revision 1.365 2008/10/02 22:23:13 cheshire
+Additional debugging message giving explanation if shutdown is delayed
+
+Revision 1.364 2008/10/01 21:23:40 cheshire
+In SIGINFO interface listing, indicate whether NetWake is set
+
+Revision 1.363 2008/09/27 01:29:15 cheshire
+Call mDNSRequestBPF() to request the helper to send us the BPF fd
+
+Revision 1.362 2008/09/26 19:47:42 cheshire
+Fixed locking error: lock is supposed to be held when calling mDNS_PurgeCacheResourceRecord
+
+Revision 1.361 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
Revision 1.360 2008/03/13 20:55:16 mcguire
<rdar://problem/5769316> fix deprecated warnings/errors
Additional cleanup: use a conditional macro instead of lots of #if
<rdar://problem/5448420> Move CFUserNotification code to mDNSResponderHelper
Revision 1.339 2007/09/06 19:08:29 cheshire
-LogAllOperations check needs to be "#if LogAllOperations || MDNS_DEBUGMSGS"
+LogClientOperations check needs to be "#if LogClientOperations || MDNS_DEBUGMSGS"
Revision 1.338 2007/09/05 23:34:27 mcguire
Revert logging change
#include <pthread.h>
#include <sandbox.h>
#include <SystemConfiguration/SCPreferencesSetSpecific.h>
+#include <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
#if TARGET_OS_EMBEDDED
#include <bootstrap_priv.h>
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
#include "helper.h"
+#include "safe_vproc.h"
//*************************************************************************************************************
-// Globals
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark - Globals
+#endif
static mDNS_PlatformSupport PlatformStorage;
static mach_port_t signal_port = MACH_PORT_NULL;
static mach_port_t server_priv_port = MACH_PORT_NULL;
-static dnssd_sock_t launchd_fd = dnssd_InvalidSocket;
+static dnssd_sock_t *launchd_fds = mDNSNULL;
+static mDNSu32 launchd_fds_count = 0;
// mDNS Mach Message Timeout, in milliseconds.
// We need this to be short enough that we don't deadlock the mDNSResponder if a client
static int restarting_via_mach_init = 0; // Used on Jaguar/Panther when daemon is started via mach_init mechanism
static int started_via_launchdaemon = 0; // Indicates we're running on Tiger or later, where daemon is managed by launchd
-
-static int OSXVers;
-
-static CFRunLoopRef CFRunLoop;
+static mDNSBool advertise = mDNS_Init_AdvertiseLocalAddresses; // By default, advertise addresses (& other records) via multicast
//*************************************************************************************************************
-// Active client list structures
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Active client list structures
+#endif
typedef struct DNSServiceDomainEnumeration_struct DNSServiceDomainEnumeration;
struct DNSServiceDomainEnumeration_struct
DNSServiceBrowserResult *results;
mDNSs32 lastsuccess;
mDNSBool DefaultDomain; // was the browse started on an explicit domain?
- domainname type; // registration type
+ domainname type; // registration type
};
typedef struct DNSServiceResolver_struct DNSServiceResolver;
size_t rdsize;
int NumSubTypes;
char regtype[MAX_ESCAPED_DOMAIN_NAME]; // for use in AllocateSubtypes
- domainlabel name; // used only if autoname is false
+ domainlabel name; // used only if autoname is false
domainname type;
mDNSIPPort port;
unsigned char txtinfo[1024];
static KQSocketEventSource *gEventSources;
//*************************************************************************************************************
-// General Utility Functions
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - General Utility Functions
+#endif
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
// Check platform-layer lists
NetworkInterfaceInfoOSX *i;
for (i = m->p->InterfaceList; i; i = i->next)
- if (i->next == (NetworkInterfaceInfoOSX *)~0 || !i->ifa_name || i->ifa_name == (char *)~0)
- LogMemCorruption("m->p->InterfaceList: %p is garbage (%p)", i, i->ifa_name);
+ if (i->next == (NetworkInterfaceInfoOSX *)~0 || !i->m || i->m == (mDNS *)~0)
+ LogMemCorruption("m->p->InterfaceList: %p is garbage (%p)", i, i->ifinfo.ifname);
ClientTunnel *t;
for (t = m->TunnelClients; t; t=t->next)
LogMemCorruption("m->TunnelClients: %p is garbage (%d)", t, t->dstname.c[0]);
}
-void *mallocL(char *msg, unsigned int size)
+mDNSexport void *mallocL(char *msg, unsigned int size)
{
- unsigned long *mem = malloc(size+8);
+ // Allocate space for two words of sanity checking data before the requested block
+ mDNSu32 *mem = malloc(sizeof(mDNSu32) * 2 + size);
if (!mem)
- {
- LogMsg("malloc( %s : %d ) failed", msg, size);
- return(NULL);
- }
+ { LogMsg("malloc( %s : %d ) failed", msg, size); return(NULL); }
else
{
if (size > 24000) LogMsg("malloc( %s : %lu ) = %p suspiciously large", msg, size, &mem[2]);
}
}
-void freeL(char *msg, void *x)
+mDNSexport void freeL(char *msg, void *x)
{
if (!x)
LogMsg("free( %s @ NULL )!", msg);
else
{
- unsigned long *mem = ((unsigned long *)x) - 2;
- if (mem[0] != 0xDEAD1234) { LogMsg("free( %s @ %p ) !!!! NOT ALLOCATED !!!!", msg, &mem[2]); return; }
+ mDNSu32 *mem = ((mDNSu32 *)x) - 2;
+ if (mem[0] != 0xDEAD1234) { LogMsg("free( %s @ %p ) !!!! NOT ALLOCATED !!!!", msg, &mem[2]); return; }
if (mem[1] > 24000) LogMsg("free( %s : %ld @ %p) suspiciously large", msg, mem[1], &mem[2]);
else if (MACOSX_MDNS_MALLOC_DEBUGGING >= 2) LogMsg("free( %s : %ld @ %p)", msg, mem[1], &mem[2]);
- //mDNSPlatformMemZero(mem, mem[1]+8);
- memset(mem, 0xFF, mem[1]+8);
+ //mDNSPlatformMemZero(mem, sizeof(mDNSu32) * 2 + mem[1]);
+ memset(mem, 0xFF, sizeof(mDNSu32) * 2 + mem[1]);
validatelists(&mDNSStorage);
free(mem);
}
#endif
+//*************************************************************************************************************
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Mach client request handlers
+#endif
+
//*************************************************************************************************************
// Client Death Detection
while (si)
{
ServiceInstance *instance = si;
- si = si->next;
+ si = si->next;
instance->renameonmemfree = mDNSfalse;
if (m && m != x) LogMsg("%5d: DNSServiceRegistration(%##s, %u) STOP; WARNING m %p != x %p", ClientMachPort, instance->srs.RR_SRV.resrec.name->c, SRS_PORT(&instance->srs), m, x);
else LogOperation("%5d: DNSServiceRegistration(%##s, %u) STOP", ClientMachPort, instance->srs.RR_SRV.resrec.name->c, SRS_PORT(&instance->srs));
return(mStatus_NoError);
fail:
- LogMsg("%5d: DNSServiceDomainEnumeration(%d) failed: %s (%ld)", client, regDom, errormsg, err);
+ LogMsg("%5d: DNSServiceDomainEnumeration(%d) failed: %s (%d)", client, regDom, errormsg, err);
return(err);
}
if (!question) { LogMsg("Error: malloc"); return mStatus_NoMemoryErr; }
AssignDomainName(&question->domain, d);
question->next = browser->qlist;
- browser->qlist = question;
LogOperation("%5d: DNSServiceBrowse(%##s%##s) START", browser->ClientMachPort, browser->type.c, d->c);
err = mDNS_StartBrowse(&mDNSStorage, &question->q, &browser->type, d, mDNSInterface_Any, mDNSfalse, FoundInstance, browser);
- if (err) LogMsg("Error: AddDomainToBrowser: mDNS_StartBrowse %d", err);
+ if (!err)
+ browser->qlist = question;
+ else
+ {
+ LogMsg("Error: AddDomainToBrowser: mDNS_StartBrowse %d", err);
+ freeL("DNSServiceBrowserQuestion", question);
+ }
return err;
}
badparam:
err = mStatus_BadParamErr;
fail:
- LogMsg("%5d: DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", client, regtype, domain, errormsg, err);
+ LogMsg("%5d: DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%d)", client, regtype, domain, errormsg, err);
return(err);
}
badparam:
err = mStatus_BadParamErr;
fail:
- LogMsg("%5d: DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%ld)", client, name, regtype, domain, errormsg, err);
+ LogMsg("%5d: DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%d)", client, name, regtype, domain, errormsg, err);
return(err);
}
{
// On conflict for an autoname service, rename and reregister *all* autoname services
IncrementLabelSuffix(&m->nicelabel, mDNStrue);
- m->MainCallback(m, mStatus_ConfigChanged);
+ mDNS_ConfigChanged(m);
}
else if (si->autoname)
{
}
else if (result != mStatus_NATTraversal)
- LogMsg("%5d: DNSServiceRegistration(%##s, %u) Unknown Result %ld", si->ClientMachPort, srs->RR_SRV.resrec.name->c, SRS_PORT(srs), result);
+ LogMsg("%5d: DNSServiceRegistration(%##s, %u) Unknown Result %d", si->ClientMachPort, srs->RR_SRV.resrec.name->c, SRS_PORT(srs), result);
}
mDNSlocal mStatus AddServiceInstance(DNSServiceRegistration *x, const domainname *domain)
badparam:
err = mStatus_BadParamErr;
fail:
- LogMsg("%5d: DNSServiceRegister(\"%s\", \"%s\", \"%s\", %d) failed: %s (%ld)",
+ LogMsg("%5d: DNSServiceRegister(\"%s\", \"%s\", \"%s\", %d) failed: %s (%d)",
client, name, regtype, domain, mDNSVal16(port), errormsg, err);
return(err);
}
if (result == mStatus_NoError)
{
if (!SameDomainLabelCS(m->p->userhostlabel.c, m->hostlabel.c))
- LogOperation("Local Hostname changed from \"%#s.local\" to \"%#s.local\"", m->p->userhostlabel.c, m->hostlabel.c);
+ LogInfo("Local Hostname changed from \"%#s.local\" to \"%#s.local\"", m->p->userhostlabel.c, m->hostlabel.c);
// One second pause in case we get a Computer Name update too -- don't want to alert the user twice
RecordUpdatedNiceLabel(m, mDNSPlatformOneSecond);
}
else if (result == mStatus_NameConflict)
{
- LogOperation("Local Hostname conflict for \"%#s.local\"", m->hostlabel.c);
+ LogInfo("Local Hostname conflict for \"%#s.local\"", m->hostlabel.c);
if (!m->p->HostNameConflict) m->p->HostNameConflict = NonZeroTime(m->timenow);
else if (m->timenow - m->p->HostNameConflict > 60 * mDNSPlatformOneSecond)
{
{
// Allocate another chunk of cache storage
CacheEntity *storage = mallocL("mStatus_GrowCache", sizeof(CacheEntity) * RR_CACHE_SIZE);
- //LogOperation("GrowCache %d * %d = %d", sizeof(CacheEntity), RR_CACHE_SIZE, sizeof(CacheEntity) * RR_CACHE_SIZE);
+ //LogInfo("GrowCache %d * %d = %d", sizeof(CacheEntity), RR_CACHE_SIZE, sizeof(CacheEntity) * RR_CACHE_SIZE);
if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE);
}
else if (result == mStatus_ConfigChanged)
return mStatus_NoError;
fail:
- LogMsg("%5d: DNSServiceRegistrationAddRecord(%##s, type %d, length %d) failed: %s (%ld)", client, x ? x->name.c : (mDNSu8*)"\x8""«NULL»", type, data_len, errormsg, err);
+ LogMsg("%5d: DNSServiceRegistrationAddRecord(%##s, type %d, length %d) failed: %s (%d)", client, x ? x->name.c : (mDNSu8*)"\x8""«NULL»", type, data_len, errormsg, err);
return mStatus_UnknownErr;
}
return(mStatus_NoError);
fail:
- LogMsg("%5d: DNSServiceRegistrationUpdateRecord(%##s, %d) failed: %s (%ld)", client, name->c, data_len, errormsg, err);
+ LogMsg("%5d: DNSServiceRegistrationUpdateRecord(%##s, %d) failed: %s (%d)", client, name->c, data_len, errormsg, err);
return(err);
}
return mStatus_NoError;
fail:
- LogMsg("%5d: DNSServiceRegistrationUpdateRecord(%##s, %X, %d) failed: %s (%ld)", client, name->c, reference, data_len, errormsg, err);
+ LogMsg("%5d: DNSServiceRegistrationUpdateRecord(%##s, %X, %d) failed: %s (%d)", client, name->c, reference, data_len, errormsg, err);
return(err);
}
return mStatus_NoError;
fail:
- LogMsg("%5d: DNSServiceRegistrationRemoveRecord(%X) failed: %s (%ld)", client, reference, errormsg, err);
+ LogMsg("%5d: DNSServiceRegistrationRemoveRecord(%X) failed: %s (%d)", client, reference, errormsg, err);
return(err);
}
//*************************************************************************************************************
-// Support Code
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Startup, shutdown, and supporting code
+#endif
mDNSlocal void DNSserverCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
{
mDNSlocal void ExitCallback(int sig)
{
(void)sig; // Unused
- LogMsgIdent(mDNSResponderVersionString, "stopping");
+ LogMsg("%s stopping", mDNSResponderVersionString);
debugf("ExitCallback");
if (!mDNS_DebugMode && !started_via_launchdaemon)
while (DNSServiceRegistrationList)
AbortClient(DNSServiceRegistrationList ->ClientMachPort, DNSServiceRegistrationList);
- if (udsserver_exit(launchd_fd) < 0) LogMsg("ExitCallback: udsserver_exit failed");
+ if (udsserver_exit() < 0) LogMsg("ExitCallback: udsserver_exit failed");
debugf("ExitCallback: mDNS_StartExit");
mDNS_StartExit(&mDNSStorage);
// Send a mach_msg to ourselves (since that is signal safe) telling us to cleanup and exit
mDNSlocal void HandleSIG(int sig)
{
- debugf(" ");
- debugf("HandleSIG %d", sig);
+ // WARNING: can't call syslog or fprintf from signal handler
mach_msg_header_t header;
header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
header.msgh_remote_port = signal_port;
header.msgh_size = sizeof(header);
header.msgh_id = sig;
if (mach_msg_send(&header) != MACH_MSG_SUCCESS)
- {
- LogMsg("HandleSIG %d: mach_msg_send failed", sig);
if (sig == SIGTERM || sig == SIGINT) exit(-1);
- }
}
mDNSlocal void CatchABRT(int sig)
{
- LogMsg("Received SIGABRT %d", sig);
- sleep(1); // Pause to make sure syslog gets the message
- while(1) *(long*)0 = 0; // Generate a CrashReporter stack trace so we can find out what library called abort();
+ // WARNING: can't call syslog or fprintf from signal handler
+ // We want a CrashReporter stack trace so we can find out what library called abort()
+ // So that we will crash, unblock all signals (that abort() may have blocked)
+ sigset_t mask;
+ sigfillset(&mask);
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ (void)sig;
+ while(1) *(long*)0 = 0;
}
mDNSlocal void INFOCallback(void)
NetworkInterfaceInfoOSX *i;
DNSServer *s;
- LogMsgIdent(mDNSResponderVersionString, "---- BEGIN STATE LOG ----");
+ LogMsg("---- BEGIN STATE LOG ----");
udsserver_info(&mDNSStorage);
{
for (i = mDNSStorage.p->InterfaceList; i; i = i->next)
{
+ // Allow six characters for interface name, for names like "vmnet8"
if (!i->Exists)
- LogMsgNoIdent("Interface: %s %5s(%lu) %.6a %#a dormant for %d seconds",
- i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifa_name, i->scope_id, &i->BSSID,
+ LogMsgNoIdent("%p %s %-6s(%lu) %.6a %.6a %#-14a dormant for %d seconds",
+ i->ifinfo.InterfaceID,
+ i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifinfo.ifname, i->scope_id, &i->ifinfo.MAC, &i->BSSID,
&i->ifinfo.ip, utc - i->LastSeen);
else
- LogMsgNoIdent("Interface: %s %5s(%lu) %.6a %s %s %-15.4a %s InterfaceID %p %s %s %#a",
- i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifa_name, i->scope_id, &i->BSSID,
+ {
+ const CacheRecord *sps[3];
+ FindSPSInCache(&mDNSStorage, &i->ifinfo.NetWakeBrowse, sps);
+ LogMsgNoIdent("%p %s %-6s(%lu) %.6a %.6a %s %s %-15.4a %s %s %s %s %#a",
+ i->ifinfo.InterfaceID,
+ i->sa_family == AF_INET ? "v4" : i->sa_family == AF_INET6 ? "v6" : "??", i->ifinfo.ifname, i->scope_id, &i->ifinfo.MAC, &i->BSSID,
i->ifinfo.InterfaceActive ? "Active" : " ",
i->ifinfo.IPv4Available ? "v4" : " ",
i->ifinfo.IPv4Available ? (mDNSv4Addr*)&i->ifa_v4addr : &zerov4Addr,
i->ifinfo.IPv6Available ? "v6" : " ",
- i->ifinfo.InterfaceID,
- i->ifinfo.Advertise ? "Adv" : " ",
- i->ifinfo.McastTxRx ? "TxRx" : " ",
+ i->ifinfo.Advertise ? "⊙" : " ",
+ i->ifinfo.McastTxRx ? "⇆" : " ",
+ !(i->ifinfo.InterfaceActive && i->ifinfo.NetWake) ? " " : !sps[0] ? "☼" : "☀",
&i->ifinfo.ip);
+
+ if (sps[0]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[0]->resrec.rdata->u.name.c), sps[0]->resrec.rdata->u.name.c);
+ if (sps[1]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[1]->resrec.rdata->u.name.c), sps[1]->resrec.rdata->u.name.c);
+ if (sps[2]) LogMsgNoIdent(" %13d %#s", SPSMetric(sps[2]->resrec.rdata->u.name.c), sps[2]->resrec.rdata->u.name.c);
+ }
}
}
{
NetworkInterfaceInfoOSX *ifx = (NetworkInterfaceInfoOSX *)s->interface;
LogMsgNoIdent("DNS Server %##s %s%s%#a:%d %s",
- s->domain.c, ifx ? ifx->ifa_name : "", ifx ? " " : "", &s->addr, mDNSVal16(s->port),
+ s->domain.c, ifx ? ifx->ifinfo.ifname : "", ifx ? " " : "", &s->addr, mDNSVal16(s->port),
s->teststate == DNSServer_Untested ? "(Untested)" :
s->teststate == DNSServer_Passed ? "" :
s->teststate == DNSServer_Failed ? "(Failed)" :
}
mDNSs32 now = mDNS_TimeNow(&mDNSStorage);
- LogMsgNoIdent("Timenow 0x%08lX (%ld)", (mDNSu32)now, now);
+ LogMsgNoIdent("Timenow 0x%08lX (%d)", (mDNSu32)now, now);
- LogMsgIdent(mDNSResponderVersionString, "---- END STATE LOG ----");
+ LogMsg("---- END STATE LOG ----");
}
mDNSlocal void SignalCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
CacheGroup *cg;
CacheRecord *rr;
LogMsg("SIGHUP: Purge cache");
+ mDNS_Lock(m);
FORALL_CACHERECORDS(slot, cg, rr) mDNS_PurgeCacheResourceRecord(m, rr);
+ // Restart unicast and multicast queries
+ mDNSCoreRestartQueries(m);
+ mDNS_Unlock(m);
} break;
case SIGINT:
case SIGTERM: ExitCallback(msg_header->msgh_id); break;
case SIGINFO: INFOCallback(); break;
- case SIGUSR1: // mDNSCoreMachineSleep(m, !m->SleepState); break;
- LogMsg("SIGUSR1: Simulate Network Configuration Change Event");
- mDNSMacOSXNetworkChanged(m);
-
- // Simulate KeychainChanged
- mDNS_Lock(m);
- SetDomainSecrets(m);
- mDNS_Unlock(m);
-
+ case SIGUSR1: mDNS_LoggingEnabled = mDNS_LoggingEnabled ? 0 : 1;
+ LogMsg("SIGUSR1: Logging %s", mDNS_LoggingEnabled ? "Enabled" : "Disabled");
+ WatchDogReportingThreshold = mDNS_LoggingEnabled ? 50 : 250;
+ break;
+ case SIGUSR2: mDNS_PacketLoggingEnabled = mDNS_PacketLoggingEnabled ? 0 : 1;
+ LogMsg("SIGUSR2: Packet Logging %s", mDNS_PacketLoggingEnabled ? "Enabled" : "Disabled");
break;
- case SIGUSR2: SigLogLevel(); break;
default: LogMsg("SignalCallback: Unknown signal %d", msg_header->msgh_id); break;
}
KQueueUnlock(m, "Unix Signal");
{
s_port = CFMachPortCreate(NULL, DNSserverCallback, NULL, NULL);
m_port = CFMachPortGetPort(s_port);
- char *MachServerName = OSXVers < 7 ? "DNSServiceDiscoveryServer" : "com.apple.mDNSResponder";
+ char *MachServerName = OSXVers < OSXVers_10_3_Panther ? "DNSServiceDiscoveryServer" : "com.apple.mDNSResponder";
kern_return_t status = bootstrap_register(bootstrap_port, MachServerName, m_port);
if (status)
err = mDNS_Init(&mDNSStorage, &PlatformStorage,
rrcachestorage, RR_CACHE_SIZE,
- mDNS_Init_AdvertiseLocalAddresses,
+ advertise,
mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext);
- if (err) { LogMsg("Daemon start: mDNS_Init failed %ld", err); return(err); }
+ if (err) { LogMsg("Daemon start: mDNS_Init failed %d", err); return(err); }
client_death_port = CFMachPortGetPort(d_port);
signal_port = CFMachPortGetPort(i_port);
- CFRunLoop = CFRunLoopGetCurrent();
- CFRunLoopAddSource(CFRunLoop, d_rls, kCFRunLoopDefaultMode);
- CFRunLoopAddSource(CFRunLoop, s_rls, kCFRunLoopDefaultMode);
- CFRunLoopAddSource(CFRunLoop, i_rls, kCFRunLoopDefaultMode);
+ CFRunLoopAddSource(PlatformStorage.CFRunLoop, d_rls, kCFRunLoopDefaultMode);
+ CFRunLoopAddSource(PlatformStorage.CFRunLoop, s_rls, kCFRunLoopDefaultMode);
+ CFRunLoopAddSource(PlatformStorage.CFRunLoop, i_rls, kCFRunLoopDefaultMode);
CFRelease(d_rls);
CFRelease(s_rls);
CFRelease(i_rls);
// we then systematically lose our own looped-back packets.
if (m->p->NetworkChanged && now - m->p->NetworkChanged >= 0) mDNSMacOSXNetworkChanged(m);
+ if (m->p->RequestReSleep && now - m->p->RequestReSleep >= 0) { m->p->RequestReSleep = 0; mDNSPowerRequest(0, 0); }
+
// KeyChain frequently fails to notify clients of change events. To work around this
// we set a timer and periodically poll to detect if any changes have occurred.
// Without this Back To My Mac just does't work for a large number of users.
if (nextevent - m->p->KeyChainBugTimer > 0)
nextevent = m->p->KeyChainBugTimer;
+ if (m->p->RequestReSleep)
+ if (nextevent - m->p->RequestReSleep > 0)
+ nextevent = m->p->RequestReSleep;
+
// 3. Deliver any waiting browse messages to clients
DNSServiceBrowser *b = DNSServiceBrowserList;
while (b)
{
- // NOTE: Need to advance b to the next element BEFORE we call DeliverInstance(), because in the
+ // Note: Need to advance b to the next element BEFORE we call DeliverInstance(), because in the
// event that the client Mach queue overflows, DeliverInstance() will call AbortBlockedClient()
// and that will cause the DNSServiceBrowser object's memory to be freed before it returns
DNSServiceBrowser *x = b;
return(nextevent);
}
-mDNSlocal void ShowTaskSchedulingError(mDNS *const m)
+// Right now we consider *ALL* of our DHCP leases
+// It might make sense to be a bit more selective and only consider the leases on interfaces
+// (a) that are capable and enabled for wake-on-LAN, and
+// (b) where we have found (and successfully registered with) a Sleep Proxy
+// If we can't be woken for traffic on a given interface, then why keep waking to renew its lease?
+mDNSlocal mDNSu32 DHCPWakeTime(void)
{
- mDNS_Lock(m);
-
- LogMsg("Task Scheduling Error: Continuously busy for more than a second");
-
- // NOTE: To accurately diagnose *why* we're busy, the debugging code here needs to mirror the logic in GetNextScheduledEvent
-
- if (m->NewQuestions && (!m->NewQuestions->DelayAnswering || m->timenow - m->NewQuestions->DelayAnswering >= 0))
- LogMsg("Task Scheduling Error: NewQuestion %##s (%s)",
- m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));
- if (m->NewLocalOnlyQuestions)
- LogMsg("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
- m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));
- if (m->NewLocalRecords && LocalRecordReady(m->NewLocalRecords))
- LogMsg("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, m->NewLocalRecords));
- if (m->SuppressSending && m->timenow - m->SuppressSending >= 0)
- LogMsg("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
-#ifndef UNICAST_DISABLED
- if (m->timenow - m->NextuDNSEvent >= 0)
- LogMsg("Task Scheduling Error: NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
-#endif
- if (m->timenow - m->NextCacheCheck >= 0)
- LogMsg("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
- if (m->timenow - m->NextScheduledQuery >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
- if (m->timenow - m->NextScheduledProbe >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
- if (m->timenow - m->NextScheduledResponse >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
- if (m->timenow - m->NextScheduledNATOp >= 0)
- LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
-
- mDNS_Unlock(&mDNSStorage);
+ mDNSu32 e = 24 * 3600; // Maximum maintenance wake interval is 24 hours
+ const CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
+ if (!now) LogMsg("DHCPWakeTime: CFAbsoluteTimeGetCurrent failed");
+ else
+ {
+ const SCPreferencesRef prefs = SCPreferencesCreate(NULL, CFSTR("mDNSResponder:DHCPWakeTime"), NULL);
+ if (!prefs) LogMsg("DHCPWakeTime: SCPreferencesCreate failed");
+ else
+ {
+ const SCNetworkSetRef currentset = SCNetworkSetCopyCurrent(prefs);
+ if (!currentset) LogMsg("DHCPWakeTime: SCNetworkSetCopyCurrent failed");
+ else
+ {
+ const CFArrayRef services = SCNetworkSetCopyServices(currentset);
+ if (!services) LogMsg("DHCPWakeTime: SCNetworkSetCopyServices failed");
+ else
+ {
+ int i;
+ for (i = 0; i < CFArrayGetCount(services); i++)
+ {
+ const SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, i);
+ if (!service) LogMsg("DHCPWakeTime: CFArrayGetValueAtIndex %d failed", i);
+ else
+ {
+ const CFStringRef serviceid = SCNetworkServiceGetServiceID(service);
+ if (!serviceid) LogMsg("DHCPWakeTime: SCNetworkServiceGetServiceID %d failed", i);
+ else
+ {
+ // Note: It's normal for this call to return NULL, for interfaces not using DHCP
+ const CFDictionaryRef dhcp = SCDynamicStoreCopyDHCPInfo(NULL, serviceid);
+ if (dhcp)
+ {
+ const CFDateRef start = DHCPInfoGetLeaseStartTime(dhcp);
+ const CFDataRef lease = DHCPInfoGetOptionData(dhcp, 51); // Option 51 = IP Address Lease Time
+ if (!start || !lease || CFDataGetLength(lease) < 4)
+ LogMsg("DHCPWakeTime: SCDynamicStoreCopyDHCPInfo index %d failed "
+ "CFDateRef start %p CFDataRef lease %p CFDataGetLength(lease) %d",
+ i, start, lease, lease ? CFDataGetLength(lease) : 0);
+ else
+ {
+ const UInt8 *d = CFDataGetBytePtr(lease);
+ if (!d) LogMsg("DHCPWakeTime: CFDataGetBytePtr %d failed", i);
+ else
+ {
+ const mDNSu32 elapsed = now - CFDateGetAbsoluteTime(start);
+ const mDNSu32 lifetime = (mDNSs32) ((mDNSs32)d[0] << 24 | (mDNSs32)d[1] << 16 | (mDNSs32)d[2] << 8 | d[3]);
+ const mDNSu32 remaining = lifetime - elapsed;
+ const mDNSu32 wake = remaining > 60 ? remaining - remaining/10 : 54; // Wake at 90% of the lease time
+ LogSPS("DHCP Address Lease Elapsed %6u Lifetime %6u Remaining %6u Wake %6u", elapsed, lifetime, remaining, wake);
+ if (e > wake) e = wake;
+ }
+ }
+ CFRelease(dhcp);
+ }
+ }
+ }
+ }
+ CFRelease(services);
+ }
+ CFRelease(currentset);
+ }
+ CFRelease(prefs);
+ }
+ }
+ return(e);
}
-mDNSlocal mDNSBool ReadyForSleep(mDNS *m)
+// We deliberately schedule our wakeup for halfway between when we'd *like* it and when we *need* it.
+// For example, if our DHCP lease expires in two hours, we'll typically renew it at the halfway point, after one hour.
+// If we scheduled our wakeup for the one-hour renewal time, that might be just seconds from now, and sleeping
+// for a few seconds and then waking again is silly and annoying.
+// If we scheduled our wakeup for the two-hour expiry time, and we were slow to wake, we might lose our lease.
+// Scheduling our wakeup for halfway in between -- 90 minutes -- avoids short wakeups while still
+// allowing us an adequate safety margin to renew our lease before we lose it.
+
+mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
{
- (void)m;
+ mDNSBool ready = mDNSCoreReadyForSleep(m);
+ if (m->SleepState && !ready && now - m->SleepLimit < 0) return(mDNSfalse);
- // 1. Scan list of private LLQs, and make sure they've all completed their handshake with the server
- DNSQuestion *q;
- for (q = m->Questions; q; q = q->next)
- if (!mDNSOpaque16IsZero(q->TargetQID) && q->LongLived && q->ReqLease == 0 && q->tcp) return(mDNSfalse);
+ m->p->WakeAtUTC = 0;
+ int result = kIOReturnSuccess;
+ CFDictionaryRef opts = NULL;
- // 2. Scan list of registered records
- AuthRecord *rr;
- for (rr = m->ResourceRecords; rr; rr = rr->next)
- if (rr->state == regState_Refresh && rr->tcp) return(mDNSfalse);
+ // If the sleep request was cancelled, and we're no longer planning to sleep, don't need to
+ // do the stuff below, but we *DO* still need to acknowledge the sleep message we received.
+ if (!m->SleepState)
+ LogMsg("AllowSleepNow: Sleep request was canceled with %d ticks remaining", m->SleepLimit - now);
+ else
+ {
+ if (!m->SystemWakeOnLANEnabled || !mDNSCoreHaveAdvertisedMulticastServices(m))
+ LogSPS("AllowSleepNow: Not scheduling wakeup: SystemWakeOnLAN %s enabled; %s advertised services",
+ m->SystemWakeOnLANEnabled ? "is" : "not",
+ mDNSCoreHaveAdvertisedMulticastServices(m) ? "have" : "no");
+ else
+ {
+ mDNSs32 dhcp = DHCPWakeTime();
+ LogSPS("ComputeWakeTime: DHCP Wake %d", dhcp);
+ mDNSs32 interval = mDNSCoreIntervalToNextWake(m, now) / mDNSPlatformOneSecond;
+ if (interval > dhcp) interval = dhcp;
+
+ // If we're not ready to sleep (failed to register with Sleep Proxy, maybe because of
+ // transient network problem) then schedule a wakeup in one hour to try again. Otherwise,
+ // a single SPS failure could result in a remote machine falling permanently asleep, requiring
+ // someone to go to the machine in person to wake it up again, which would be unacceptable.
+ if (!ready && interval > 3600) interval = 3600;
+
+ //interval = 48; // For testing
+
+#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+ if (m->p->IOPMConnection) // If lightweight-wake capability is available, use that
+ {
+ const CFDateRef WakeDate = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent() + interval);
+ if (!WakeDate) LogMsg("ScheduleNextWake: CFDateCreate failed");
+ else
+ {
+ const mDNSs32 reqs = kIOPMSystemPowerStateCapabilityNetwork;
+ const CFNumberRef Requirements = CFNumberCreate(NULL, kCFNumberSInt32Type, &reqs);
+ if (!Requirements) LogMsg("ScheduleNextWake: CFNumberCreate failed");
+ else
+ {
+ const void *OptionKeys[2] = { CFSTR("WakeDate"), CFSTR("Requirements") };
+ const void *OptionVals[2] = { WakeDate, Requirements };
+ opts = CFDictionaryCreate(NULL, (void*)OptionKeys, (void*)OptionVals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (!opts) LogMsg("ScheduleNextWake: CFDictionaryCreate failed");
+ CFRelease(Requirements);
+ }
+ CFRelease(WakeDate);
+ }
+ LogSPS("AllowSleepNow: Will request lightweight wakeup in %d seconds", interval);
+ }
+ else // else schedule the wakeup using the old API instead to
+#endif
+ {
+ // If we wake within +/- 30 seconds of our requested time we'll assume the system woke for us,
+ // so we should put it back to sleep. To avoid frustrating the user, we always request at least
+ // 60 seconds sleep, so if they immediately re-wake the system within seconds of it going to sleep,
+ // we then shouldn't hit our 30-second window, and we won't attempt to re-sleep the machine.
+ if (interval < 60) interval = 60;
+
+ result = mDNSPowerRequest(1, interval);
+
+ if (result == kIOReturnNotReady)
+ {
+ LogMsg("Requested wakeup in %d seconds unsuccessful; retrying with longer intervals", interval);
+ // IOPMSchedulePowerEvent fails with kIOReturnNotReady (-536870184/0xe00002d8) if the
+ // requested wake time is "too soon", but there's no API to find out what constitutes
+ // "too soon" on any given OS/hardware combination, so if we get kIOReturnNotReady
+ // we just have to iterate with successively longer intervals until it doesn't fail.
+ // Additionally, if our power request is deemed "too soon" for the machine to get to
+ // sleep and wake back up again, we attempt to cancel the sleep request, since the
+ // implication is that the system won't manage to be awake again at the time we need it.
+ do
+ {
+ interval += (interval < 20) ? 1 : ((interval+3) / 4);
+ result = mDNSPowerRequest(1, interval);
+ }
+ while (result == kIOReturnNotReady);
+ }
+
+ if (result) LogMsg("AllowSleepNow: Requested wakeup in %d seconds unsuccessful: %d %X", interval, result, result);
+ else LogSPS("AllowSleepNow: Requested wakeup in %d seconds", interval);
+ m->p->WakeAtUTC = mDNSPlatformUTC() + interval;
+ }
+ }
+
+ // Clear our interface list to empty state, ready to go to sleep
+ // As a side effect of doing this, we'll also cancel any outstanding SPS Resolve calls that didn't complete
+ m->SleepState = SleepState_Sleeping;
+ mDNSMacOSXNetworkChanged(m);
+ }
+
+ LogSPS("AllowSleepNow: %s(%lX) %s at %ld (%d ticks remaining)",
+#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+ (m->p->IOPMConnection) ? "IOPMConnectionAcknowledgeEventWithOptions" :
+#endif
+ (result == kIOReturnSuccess) ? "IOAllowPowerChange" : "IOCancelPowerChange",
+ m->p->SleepCookie, ready ? "ready for sleep" : "giving up", now, m->SleepLimit - now);
- // 2. Scan list of registered services
- ServiceRecordSet *srs;
- for (srs = m->ServiceRegistrations; srs; srs = srs->uDNS_next)
- if (srs->state == regState_NoTarget && srs->tcp) return(mDNSfalse);
+ m->SleepLimit = 0; // Don't clear m->SleepLimit until after we've logged it above
+#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+ if (m->p->IOPMConnection) IOPMConnectionAcknowledgeEventWithOptions(m->p->IOPMConnection, m->p->SleepCookie, opts);
+ else
+#endif
+ if (result == kIOReturnSuccess) IOAllowPowerChange (m->p->PowerConnection, m->p->SleepCookie);
+ else IOCancelPowerChange(m->p->PowerConnection, m->p->SleepCookie);
+
+ if (opts) CFRelease(opts);
return(mDNStrue);
}
#endif
pthread_mutex_lock(&PlatformStorage.BigMutex);
- LogOperation("Starting time value 0x%08lX (%ld)", (mDNSu32)mDNSStorage.timenow_last, mDNSStorage.timenow_last);
+ LogInfo("Starting time value 0x%08lX (%ld)", (mDNSu32)mDNSStorage.timenow_last, mDNSStorage.timenow_last);
// This is the main work loop:
// (1) First we give mDNSCore a chance to finish off any of its deferred work and calculate the next sleep time
mDNSs32 nextTimerEvent = udsserver_idle(mDNSDaemonIdle(m));
mDNSs32 end = mDNSPlatformRawTime();
if (end - start >= WatchDogReportingThreshold)
- LogOperation("WARNING: Idle task took %dms to complete", end - start);
+ LogInfo("WARNING: Idle task took %dms to complete", end - start);
mDNSs32 now = mDNS_TimeNow(m);
if (m->ShutdownTime)
{
+ if (mDNSStorage.ResourceRecords)
+ {
+ LogInfo("Cannot exit yet; Resource Record still exists: %s", ARDisplayString(m, mDNSStorage.ResourceRecords));
+ if (mDNS_LoggingEnabled) usleep(10000); // Sleep 10ms so that we don't flood syslog with too many messages
+ }
+ if (mDNSStorage.ServiceRegistrations)
+ LogInfo("Cannot exit yet; ServiceRegistrations still exists: %s", ARDisplayString(m, &mDNSStorage.ServiceRegistrations->RR_SRV));
if (mDNS_ExitNow(m, now))
{
- LogOperation("mDNS_FinalExit");
+ if (!mDNSStorage.ResourceRecords && !mDNSStorage.ServiceRegistrations)
+ safe_vproc_transaction_end();
+ LogInfo("mDNS_FinalExit");
mDNS_FinalExit(&mDNSStorage);
usleep(1000); // Little 1ms pause before exiting, so we don't lose our final syslog messages
exit(0);
nextTimerEvent = m->ShutdownTime;
}
- if (m->p->SleepLimit)
- {
- mDNSBool ready = ReadyForSleep(m);
- if (ready || now - m->p->SleepLimit >= 0)
- {
- LogOperation("IOAllowPowerChange(%lX) %s at %ld (%d ticks remaining)", m->p->SleepCookie,
- ready ? "ready for sleep" : "giving up", now, m->p->SleepLimit - now);
- m->p->SleepLimit = 0;
- IOAllowPowerChange(m->p->PowerConnection, m->p->SleepCookie);
- }
- else
- if (nextTimerEvent - m->p->SleepLimit >= 0)
- nextTimerEvent = m->p->SleepLimit;
- }
+ if (m->SleepLimit)
+ if (!AllowSleepNow(m, now))
+ if (nextTimerEvent - m->SleepLimit >= 0)
+ nextTimerEvent = m->SleepLimit;
// Convert absolute wakeup time to a relative time from now
mDNSs32 ticks = nextTimerEvent - now;
{
const KQueueEntry *const kqentry = new_events[i].udata;
mDNSs32 stime = mDNSPlatformRawTime();
-#if LogAllOperations || MDNS_DEBUGMSGS
const char *const KQtask = kqentry->KQtask; // Grab a copy in case KQcallback deletes the task
-#endif
kqentry->KQcallback(new_events[i].ident, new_events[i].filter, kqentry->KQcontext);
mDNSs32 etime = mDNSPlatformRawTime();
if (etime - stime >= WatchDogReportingThreshold)
- LogOperation("WARNING: %s took %dms to complete", KQtask, etime - stime);
+ LogInfo("WARNING: %s took %dms to complete", KQtask, etime - stime);
}
}
}
int err = launch_data_get_errno(resp);
// When running on Tiger with "ServiceIPC = false", we get "err == EACCES" to tell us there's no launchdata to fetch
if (err != EACCES) LogMsg("launch_msg returned %d", err);
- else LogOperation("Launchd provided no launchdata; will open Mach port and Unix Domain Socket explicitly...", err);
+ else LogInfo("Launchd provided no launchdata; will open Mach port and Unix Domain Socket explicitly...", err);
}
else
{
if (!skt) LogMsg("launch_data_dict_lookup Listeners returned NULL");
else
{
- launch_data_t s = launch_data_array_get_index(skt, 0);
- if (!s) LogMsg("launch_data_array_get_index(skt, 0) returned NULL");
+ launchd_fds_count = launch_data_array_get_count(skt);
+ if (launchd_fds_count == 0) LogMsg("launch_data_array_get_count(skt) returned 0");
else
{
- launchd_fd = launch_data_get_fd(s);
- LogOperation("Launchd Unix Domain Socket: %d", launchd_fd);
+ launchd_fds = mallocL("LaunchdCheckin", sizeof(dnssd_sock_t) * launchd_fds_count);
+ if (!launchd_fds) LogMsg("LaunchdCheckin: malloc failed");
+ else
+ {
+ size_t i;
+ for(i = 0; i < launchd_fds_count; i++)
+ {
+ launch_data_t s = launch_data_array_get_index(skt, i);
+ if (!s)
+ {
+ launchd_fds[i] = dnssd_InvalidSocket;
+ LogMsg("launch_data_array_get_index(skt, %d) returned NULL", i);
+ }
+ else
+ {
+ launchd_fds[i] = launch_data_get_fd(s);
+ LogInfo("Launchd Unix Domain Socket [%d]: %d", i, launchd_fds[i]);
+ }
+ }
+ }
// In some early versions of 10.4.x, the permissions on the UDS were not set correctly, so we fix them here
chmod(MDNS_UDS_SERVERPATH, S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH);
}
else
{
launch_data_t p = launch_data_dict_lookup(ports, "com.apple.mDNSResponder");
- if (!p) LogOperation("launch_data_array_get_index(ports, 0) returned NULL");
+ if (!p) LogInfo("launch_data_dict_lookup(ports, \"com.apple.mDNSResponder\") returned NULL");
else
{
m_port = launch_data_get_fd(p);
- LogOperation("Launchd Mach Port: %d", m_port);
+ LogInfo("Launchd Mach Port: %d", m_port);
if (m_port == ~0U) m_port = MACH_PORT_NULL;
}
}
*p = '/';
if (unlink(path) < 0 && errno != ENOENT) LogMsg("DropPrivileges: Could not unlink \"%s\": (%d) %s", path, errno, strerror(errno));
else if (symlink(path, MDNS_UDS_SERVERPATH) < 0) LogMsg("DropPrivileges: Could not symlink \"%s\" -> \"%s\": (%d) %s", MDNS_UDS_SERVERPATH, path, errno, strerror(errno));
- else LogOperation("DropPrivileges: Created subdirectory and symlink");
+ else LogInfo("DropPrivileges: Created subdirectory and symlink");
}
}
kern_return_t status;
pthread_t KQueueThread;
- LogMsgIdent(mDNSResponderVersionString, "starting");
+ LogMsg("%s starting", mDNSResponderVersionString);
+
+#if 0
+ LogMsg("CacheRecord %d", sizeof(CacheRecord));
+ LogMsg("CacheGroup %d", sizeof(CacheGroup));
+ LogMsg("ResourceRecord %d", sizeof(ResourceRecord));
+ LogMsg("RData_small %d", sizeof(RData_small));
+
+ LogMsg("sizeof(CacheEntity) %d", sizeof(CacheEntity));
+ LogMsg("RR_CACHE_SIZE %d", RR_CACHE_SIZE);
+ LogMsg("block usage %d", sizeof(CacheEntity) * RR_CACHE_SIZE);
+ LogMsg("block wastage %d", 16*1024 - sizeof(CacheEntity) * RR_CACHE_SIZE);
+#endif
+
+ safe_vproc_transaction_begin();
if (0 == geteuid()) DropPrivileges();
for (i=1; i<argc; i++)
{
- if (!strcasecmp(argv[i], "-d" )) mDNS_DebugMode = mDNStrue;
- if (!strcasecmp(argv[i], "-launchd" )) started_via_launchdaemon = mDNStrue;
- if (!strcasecmp(argv[i], "-launchdaemon")) started_via_launchdaemon = mDNStrue;
+ if (!strcasecmp(argv[i], "-d" )) mDNS_DebugMode = mDNStrue;
+ if (!strcasecmp(argv[i], "-launchd" )) started_via_launchdaemon = mDNStrue;
+ if (!strcasecmp(argv[i], "-launchdaemon" )) started_via_launchdaemon = mDNStrue;
+ if (!strcasecmp(argv[i], "-NoMulticastAdvertisements")) advertise = mDNS_Init_DontAdvertiseLocalAddresses;
+ if (!strcasecmp(argv[i], "-DebugLogging" )) mDNS_LoggingEnabled = mDNStrue;
+ if (!strcasecmp(argv[i], "-UnicastPacketLogging" )) mDNS_PacketLoggingEnabled = mDNStrue;
+ if (!strcasecmp(argv[i], "-OfferSleepProxyService" ))
+ OfferSleepProxyService = (i+1<argc && mDNSIsDigit(argv[i+1][0]) && mDNSIsDigit(argv[i+1][1]) && argv[i+1][2]==0) ? atoi(argv[++i]) : 80;
}
+
+ // Note that mDNSPlatformInit will set DivertMulticastAdvertisements in the mDNS structure
+ if (!advertise) LogMsg("Administratively prohibiting multicast advertisements");
+
+ OSXVers = mDNSMacOSXSystemBuildNumber(NULL);
signal(SIGHUP, HandleSIG); // (Debugging) Purge the cache to check for cache handling bugs
signal(SIGINT, HandleSIG); // Ctrl-C: Detach from Mach BootstrapService and exit cleanly
- signal(SIGABRT, CatchABRT); // For debugging -- SIGABRT should never happen
+ // On 10.5 and later, the default action for SIGABRT is to generate a crash report, so we only need our CatchABRT handler on 10.4
+ if (OSXVers <= OSXVers_10_4_Tiger)
+ {
+ LogInfo("Adding SIGABRT handler");
+ signal(SIGABRT, CatchABRT); // For debugging -- SIGABRT should never happen
+ }
signal(SIGPIPE, SIG_IGN ); // Don't want SIGPIPE signals -- we'll handle EPIPE errors directly
signal(SIGTERM, HandleSIG); // Machine shutting down: Detach from and exit cleanly like Ctrl-C
signal(SIGINFO, HandleSIG); // (Debugging) Write state snapshot to syslog
- signal(SIGUSR1, HandleSIG); // (Debugging) Simulate network change notification from System Configuration Framework
- signal(SIGUSR2, HandleSIG); // (Debugging) Change log level
+ signal(SIGUSR1, HandleSIG); // (Debugging) Enable Logging
+ signal(SIGUSR2, HandleSIG); // (Debugging) Enable Packet Logging
mDNSStorage.p = &PlatformStorage; // Make sure mDNSStorage.p is set up, because validatelists uses it
LaunchdCheckin();
char *sandbox_msg;
int sandbox_err = sandbox_init("mDNSResponder", SANDBOX_NAMED, &sandbox_msg);
if (sandbox_err) { LogMsg("WARNING: sandbox_init error %s", sandbox_msg); sandbox_free_error(sandbox_msg); }
- else LogOperation("Now running under Apple Sandbox restrictions");
+ else LogInfo("Now running under Apple Sandbox restrictions");
}
#endif
- OSXVers = mDNSMacOSXSystemBuildNumber(NULL);
status = mDNSDaemonInitialize();
if (status) { LogMsg("Daemon start: mDNSDaemonInitialize failed"); goto exit; }
- status = udsserver_init(launchd_fd);
+
+ status = udsserver_init(launchd_fds, launchd_fds_count);
if (status) { LogMsg("Daemon start: udsserver_init failed"); goto exit; }
-
+
+ mDNSMacOSXNetworkChanged(&mDNSStorage);
+
// Start the kqueue thread
i = pthread_create(&KQueueThread, NULL, KQueueLoop, &mDNSStorage);
if (i == -1) { LogMsg("pthread_create() failed errno %d (%s)", errno, strerror(errno)); status = errno; goto exit; }
mDNS_Close(&mDNSStorage);
}
- LogMsgIdent(mDNSResponderVersionString, "exiting");
+ LogMsg("%s exiting", mDNSResponderVersionString);
exit:
if (!mDNS_DebugMode && !started_via_launchdaemon) destroyBootstrapService();
// uds_daemon.c support routines /////////////////////////////////////////////
-// Arrange things so that callback is called with context when data appears on fd
-mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context)
+// Arrange things so that when data appears on fd, callback is called with context
+mDNSexport mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context)
{
+ KQSocketEventSource **p = &gEventSources;
+ while (*p && (*p)->fd != fd) p = &(*p)->next;
+ if (*p) { LogMsg("udsSupportAddFDToEventLoop: ERROR fd %d already has EventLoop source entry", fd); return mStatus_AlreadyRegistered; }
+
KQSocketEventSource *newSource = (KQSocketEventSource*) mallocL("KQSocketEventSource", sizeof *newSource);
if (!newSource) return mStatus_NoMemoryErr;
- mDNSPlatformMemZero(newSource, sizeof(*newSource));
- newSource->fd = fd;
+ newSource->next = mDNSNULL;
+ newSource->fd = fd;
newSource->kqs.KQcallback = callback;
newSource->kqs.KQcontext = context;
newSource->kqs.KQtask = "UDS client";
if (KQueueSet(fd, EV_ADD, EVFILT_READ, &newSource->kqs) == 0)
{
- KQSocketEventSource **p = &gEventSources;
- while (*p) p = &(*p)->next;
*p = newSource;
return mStatus_NoError;
}
- else
- {
- close(fd);
- free(newSource);
- return mStatus_NoMemoryErr;
- }
+
+ LogMsg("KQueueSet failed for fd %d errno %d (%s)", fd, errno, strerror(errno));
+ freeL("KQSocketEventSource", newSource);
+ return mStatus_BadParamErr;
}
-mStatus udsSupportRemoveFDFromEventLoop(int fd) // Note: This also CLOSES the file descriptor
+mDNSexport mStatus udsSupportRemoveFDFromEventLoop(int fd) // Note: This also CLOSES the file descriptor
{
KQSocketEventSource **p = &gEventSources;
while (*p && (*p)->fd != fd) p = &(*p)->next;
- if (*p)
+ if (*p)
{
KQSocketEventSource *s = *p;
*p = (*p)->next;
freeL("KQSocketEventSource", s);
return mStatus_NoError;
}
+ LogMsg("udsSupportRemoveFDFromEventLoop: ERROR fd %d not found in EventLoop source list", fd);
return mStatus_NoSuchNameErr;
}
+#if _BUILDING_XCODE_PROJECT_
// If mDNSResponder crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = mDNSResponderVersionString;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
// For convenience when using the "strings" command, this is the last thing in the file
// The "@(#) " pattern is a special prefix the "what" command looks for
Change History (most recent first):
$Log: helper-main.c,v $
+Revision 1.28 2009/04/11 00:20:08 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.27 2009/03/09 19:00:26 mcguire
+<rdar://problem/6660098> temporarily don't use getpwnam
+
+Revision 1.26 2009/03/05 23:08:12 cheshire
+<rdar://problem/6648751> mDNSResponderHelper deadlocked — Can't use syslog from within a signal handler
+
+Revision 1.25 2009/02/06 03:06:49 mcguire
+<rdar://problem/5858533> Adopt vproc_transaction API in mDNSResponder
+
+Revision 1.24 2009/01/28 17:20:46 mcguire
+changed incorrect notice level log to debug
+
+Revision 1.23 2009/01/28 03:17:19 mcguire
+<rdar://problem/5858535> helper: Adopt vproc_transaction API
+
+Revision 1.22 2008/12/19 01:56:47 mcguire
+<rdar://problem/6181947> crashes in mDNSResponderHelper
+
+Revision 1.21 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
+Revision 1.20 2008/08/13 23:11:35 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+
+Revision 1.19 2008/08/13 23:04:06 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+Preparation: rename message function, as it will no longer be called only on idle exit
+
+Revision 1.18 2008/08/13 22:56:32 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+Preparation: store mach port in global variable so we can write to it from a signal handler
+
+Revision 1.17 2008/07/24 01:04:04 mcguire
+<rdar://problem/6003721> helper spawned every 10s
+
+Revision 1.16 2008/07/01 01:40:01 mcguire
+<rdar://problem/5823010> 64-bit fixes
+
Revision 1.15 2008/03/13 20:55:16 mcguire
<rdar://problem/5769316> fix deprecated warnings/errors
Additional cleanup: use a conditional macro instead of lots of #if
#include "helper-server.h"
#include "helpermsg.h"
#include "helpermsgServer.h"
+#include "safe_vproc.h"
#if TARGET_OS_EMBEDDED
#include <bootstrap_priv.h>
union __ReplyUnion__proxy_helper_subsystem rep;
};
+#ifdef VPROC_HAS_TRANSACTIONS
+typedef struct __transaction_s
+ {
+ struct __transaction_s* next;
+ vproc_transaction_t vt;
+ } transaction_t;
+
+static transaction_t* transactions = NULL;
+#endif
+
static const mach_msg_size_t MAX_MSG_SIZE = sizeof(union max_msg_size) + MAX_TRAILER_SIZE;
static aslclient logclient = NULL;
static int opt_debug;
static pthread_t idletimer_thread;
-unsigned long maxidle = 10;
+unsigned long maxidle = 15;
unsigned long actualidle = 3600;
CFRunLoopRef gRunLoop = NULL;
CFRunLoopTimerRef gTimer = NULL;
+mach_port_t gPort = MACH_PORT_NULL;
+
static void helplogv(int level, const char *fmt, va_list ap)
{
if (NULL == logclient) { vfprintf(stderr, fmt, ap); fflush(stderr); }
helplogv(level, fmt, ap);
va_end(ap);
}
+
+// for safe_vproc
+void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *fmt, ...)
+ {
+ (void)logLevel;
+ va_list ap;
+ va_start(ap, fmt);
+ // safe_vproc only calls LogMsg, so assume logLevel maps to ASL_LEVEL_ERR
+ helplog(ASL_LEVEL_ERR, fmt, ap);
+ va_end(ap);
+ }
+
+static void handle_sigterm(int sig)
+ {
+ // debug("entry sig=%d", sig); Can't use syslog from within a signal handler
+ assert(sig == SIGTERM);
+ (void)proxy_mDNSExit(gPort);
+ }
static void initialize_logging(void)
{
static void initialize_id(void)
{
static char login[] = "_mdnsresponder";
- struct passwd *pwd = getpwnam(login);
+ struct passwd hardcode;
+ struct passwd *pwd = &hardcode; // getpwnam(login);
+ hardcode.pw_uid = 65;
+ hardcode.pw_gid = 65;
if (!pwd) { helplog(ASL_LEVEL_ERR, "Could not find account name `%s'. I will only help root.", login); return; }
mDNSResponderUID = pwd->pw_uid;
static void diediedie(CFRunLoopTimerRef timer, void *context)
{
- debug("entry");
+ debug("entry %p %p %d", timer, context, maxidle);
assert(gTimer == timer);
if (maxidle)
- (void)proxy_mDNSIdleExit((mach_port_t)context);
+ (void)proxy_mDNSExit(gPort);
}
void pause_idle_timer(void)
return NULL;
}
-static void initialize_timer(mach_port_t port)
+static int initialize_timer()
{
- CFRunLoopTimerContext cxt = {0, (void *)port, NULL, NULL, NULL};
- gTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + actualidle, actualidle, 0, 0, diediedie, &cxt);
+ gTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + actualidle, actualidle, 0, 0, diediedie, NULL);
int err = 0;
- debug("entry port=%p", port);
- if (0 != (err = pthread_create(&idletimer_thread, NULL, idletimer, (void *)port)))
+ debug("entry");
+ if (0 != (err = pthread_create(&idletimer_thread, NULL, idletimer, NULL)))
helplog(ASL_LEVEL_ERR, "Could not start idletimer thread: %s", strerror(err));
+
+ return err;
}
static mach_port_t checkin(char *service_name)
{
char *p = NULL;
kern_return_t kr = KERN_FAILURE;
- mach_port_t port = MACH_PORT_NULL;
long n;
int ch;
+ mach_msg_header_t hdr;
while ((ch = getopt(ac, av, "dt:")) != -1)
switch (ch)
// Explicitly ensure that our Keychain operations utilize the system domain.
SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
#endif
- port = checkin(kmDNSHelperServiceName);
- if (!port)
+ gPort = checkin(kmDNSHelperServiceName);
+ if (!gPort)
{
helplog(ASL_LEVEL_ERR, "Launchd provided no launchdata; will open Mach port explicitly");
- port = register_service(kmDNSHelperServiceName);
+ gPort = register_service(kmDNSHelperServiceName);
}
if (maxidle) actualidle = maxidle;
- initialize_timer(port);
- kr = mach_msg_server(helper_server, MAX_MSG_SIZE, port,
- MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
- if (KERN_SUCCESS != kr)
- { helplog(ASL_LEVEL_ERR, "mach_msg_server: %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); }
+ signal(SIGTERM, handle_sigterm);
+
+ if (initialize_timer()) exit(EXIT_FAILURE);
+ for (n=0; n<100000; n++) if (!gRunLoop) usleep(100);
+ if (!gRunLoop)
+ {
+ helplog(ASL_LEVEL_ERR, "gRunLoop not set after waiting");
+ exit(EXIT_FAILURE);
+ }
+
+ for(;;)
+ {
+ hdr.msgh_bits = 0;
+ hdr.msgh_local_port = gPort;
+ hdr.msgh_remote_port = MACH_PORT_NULL;
+ hdr.msgh_size = sizeof(hdr);
+ hdr.msgh_id = 0;
+ kr = mach_msg(&hdr, MACH_RCV_LARGE | MACH_RCV_MSG, 0, hdr.msgh_size, gPort, 0, 0);
+ if (MACH_RCV_TOO_LARGE != kr) helplog(ASL_LEVEL_ERR, "kr: %d: %s", kr, mach_error_string(kr));
+
+ safe_vproc_transaction_begin();
+
+ kr = mach_msg_server_once(helper_server, MAX_MSG_SIZE, gPort,
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
+ if (KERN_SUCCESS != kr)
+ { helplog(ASL_LEVEL_ERR, "mach_msg_server: %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); }
+
+ safe_vproc_transaction_end();
+ }
exit(EXIT_SUCCESS);
}
// The "@(#) " pattern is a special prefix the "what" command looks for
const char VersionString_SCCS[] = "@(#) mDNSResponderHelper " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = VersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
Change History (most recent first):
$Log: helper-server.h,v $
+Revision 1.5 2009/02/06 03:06:49 mcguire
+<rdar://problem/5858533> Adopt vproc_transaction API in mDNSResponder
+
+Revision 1.4 2009/01/28 03:17:19 mcguire
+<rdar://problem/5858535> helper: Adopt vproc_transaction API
+
Revision 1.3 2007/09/07 22:44:03 mcguire
<rdar://problem/5448420> Move CFUserNotification code to mDNSResponderHelper
Change History (most recent first):
$Log: helper-stubs.c,v $
+Revision 1.19 2009/04/20 20:40:14 cheshire
+<rdar://problem/6786150> uDNS: Running location cycling caused configd and mDNSResponder to deadlock
+Changed mDNSPreferencesSetName (and similar) routines from MIG "routine" to MIG "simpleroutine"
+so we don't deadlock waiting for a result that we're just going to ignore anyway
+
+Revision 1.18 2009/03/20 22:12:27 mcguire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+Make the call to the helper a simpleroutine: don't wait for an unused return value
+
+Revision 1.17 2009/03/20 20:52:22 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+
+Revision 1.16 2009/03/14 01:42:56 mcguire
+<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
+
+Revision 1.15 2009/01/22 02:14:27 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.14 2009/01/14 01:38:42 mcguire
+<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
+
+Revision 1.13 2009/01/14 01:28:17 mcguire
+removed unused variable
+
+Revision 1.12 2008/11/11 00:46:37 cheshire
+Don't just show "<unknown error>"; show the actual numeric error code too, so we can see what the unknown error was
+
+Revision 1.11 2008/11/04 23:54:09 cheshire
+Added routine mDNSSetARP(), used to replace an SPS client's entry in our ARP cache with
+a dummy one, so that IP traffic to the SPS client initiated by the SPS machine can be
+captured by our BPF filters, and used as a trigger to wake the sleeping machine.
+
+Revision 1.10 2008/10/29 21:25:35 cheshire
+Don't report kIOReturnNotReady errors
+
+Revision 1.9 2008/10/24 01:42:36 cheshire
+Added mDNSPowerRequest helper routine to request a scheduled wakeup some time in the future
+
+Revision 1.8 2008/10/20 22:01:28 cheshire
+Made new Mach simpleroutine "mDNSRequestBPF"
+
+Revision 1.7 2008/09/27 00:58:32 cheshire
+Added mDNSRequestBPF definition
+
Revision 1.6 2007/12/10 23:23:48 cheshire
Removed unnecessary log message ("mDNSKeychainGetSecrets failed 0 00000000" because mDNSKeychainGetSecrets was failing to return a valid array)
#include <mach/mach_error.h>
#include <mach/vm_map.h>
#include <servers/bootstrap.h>
+#include <IOKit/IOReturn.h>
#include <CoreFoundation/CoreFoundation.h>
#include "mDNSDebug.h"
#include "helper.h"
};
#undef ERROR
-static mach_port_t
-getHelperPort(int retry)
+static mach_port_t getHelperPort(int retry)
{
static mach_port_t port = MACH_PORT_NULL;
-
- if (retry)
- port = MACH_PORT_NULL;
- if (port == MACH_PORT_NULL &&
- BOOTSTRAP_SUCCESS != bootstrap_look_up(bootstrap_port,
- kmDNSHelperServiceName, &port))
+ if (retry) port = MACH_PORT_NULL;
+ if (port == MACH_PORT_NULL && BOOTSTRAP_SUCCESS != bootstrap_look_up(bootstrap_port, kmDNSHelperServiceName, &port))
LogMsg("%s: cannot contact helper", __func__);
return port;
}
-const char *
-mDNSHelperError(int err)
+const char *mDNSHelperError(int err)
{
- const char *p = "<unknown error>";
+ static const char *p = "<unknown error>";
if (mDNSHelperErrorBase < err && mDNSHelperErrorEnd > err)
p = errorstring[err - mDNSHelperErrorBase - 1];
return p;
}
/* Ugly but handy. */
-#define MACHRETRYLOOP_BEGIN(kr, retry, err, fin) for (;;) {
-
-#define MACHRETRYLOOP_END(kr, retry, err, fin) \
- if (KERN_SUCCESS == (kr)) break; \
- else if (MACH_SEND_INVALID_DEST == (kr) && 0 == (retry)++) continue; \
- else \
- { \
- (err) = kmDNSHelperCommunicationFailed; \
- LogMsg("%s: Mach communication failed: %s", __func__, mach_error_string(kr)); \
- goto fin; \
- } \
- } \
- if (0 != (err)) { LogMsg("%s: %s", __func__, mDNSHelperError((err))); goto fin; }
-
-int
-mDNSPreferencesSetName(int key, domainlabel* old, domainlabel* new)
+// We don't bother reporting kIOReturnNotReady because that error code occurs in "normal" operation
+// and doesn't indicate anything unexpected that needs to be investigated
+
+#define MACHRETRYLOOP_BEGIN(kr, retry, err, fin) \
+ for (;;) \
+ {
+#define MACHRETRYLOOP_END(kr, retry, err, fin) \
+ if (KERN_SUCCESS == (kr)) break; \
+ else if (MACH_SEND_INVALID_DEST == (kr) && 0 == (retry)++) continue; \
+ else \
+ { \
+ (err) = kmDNSHelperCommunicationFailed; \
+ LogMsg("%s: Mach communication failed: %s", __func__, mach_error_string(kr)); \
+ goto fin; \
+ } \
+ } \
+ if (0 != (err) && kIOReturnNotReady != (err)) \
+ { LogMsg("%s: %d 0x%X (%s)", __func__, (err), (err), mDNSHelperError(err)); goto fin; }
+
+void mDNSPreferencesSetName(int key, domainlabel *old, domainlabel *new)
{
kern_return_t kr = KERN_FAILURE;
int retry = 0;
if (new) ConvertDomainLabelToCString_unescaped(new, newname);
MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
- kr = proxy_mDNSPreferencesSetName(getHelperPort(retry), key, oldname, newname, &err);
+ kr = proxy_mDNSPreferencesSetName(getHelperPort(retry), key, oldname, newname);
MACHRETRYLOOP_END(kr, retry, err, fin);
fin:
- return err;
+ (void)err;
}
-int
-mDNSDynamicStoreSetConfig(int key, CFPropertyListRef value)
+void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropertyListRef value)
{
CFWriteStreamRef stream = NULL;
CFDataRef bytes = NULL;
int retry = 0;
int err = 0;
- if (NULL == (stream = CFWriteStreamCreateWithAllocatedBuffers(NULL,
- NULL)))
+ if (NULL == (stream = CFWriteStreamCreateWithAllocatedBuffers(NULL, NULL)))
{
err = kmDNSHelperCreationFailed;
- LogMsg("%s: CFWriteStreamCreateWithAllocatedBuffers failed",
- __func__);
+ LogMsg("%s: CFWriteStreamCreateWithAllocatedBuffers failed", __func__);
goto fin;
}
CFWriteStreamOpen(stream);
- if (0 == CFPropertyListWriteToStream(value, stream,
- kCFPropertyListBinaryFormat_v1_0, NULL))
+ if (0 == CFPropertyListWriteToStream(value, stream, kCFPropertyListBinaryFormat_v1_0, NULL))
{
err = kmDNSHelperPListWriteFailed;
LogMsg("%s: CFPropertyListWriteToStream failed", __func__);
goto fin;
}
- if (NULL == (bytes = CFWriteStreamCopyProperty(stream,
- kCFStreamPropertyDataWritten)))
+ if (NULL == (bytes = CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten)))
{
err = kmDNSHelperCreationFailed;
LogMsg("%s: CFWriteStreamCopyProperty failed", __func__);
CFRelease(stream);
stream = NULL;
MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
- kr = proxy_mDNSDynamicStoreSetConfig(getHelperPort(retry), key,
- (vm_offset_t)CFDataGetBytePtr(bytes),
- CFDataGetLength(bytes), &err);
+ kr = proxy_mDNSDynamicStoreSetConfig(getHelperPort(retry), key, subkey ? subkey : "", (vm_offset_t)CFDataGetBytePtr(bytes), CFDataGetLength(bytes));
MACHRETRYLOOP_END(kr, retry, err, fin);
fin:
- if (NULL != stream)
- {
- CFWriteStreamClose(stream);
- CFRelease(stream);
- }
- if (NULL != bytes)
- CFRelease(bytes);
+ if (NULL != stream) { CFWriteStreamClose(stream); CFRelease(stream); }
+ if (NULL != bytes) CFRelease(bytes);
+ (void)err;
+ }
+
+void mDNSRequestBPF(void)
+ {
+ kern_return_t kr = KERN_FAILURE;
+ int retry = 0, err = 0;
+ MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
+ kr = proxy_mDNSRequestBPF(getHelperPort(retry));
+ MACHRETRYLOOP_END(kr, retry, err, fin);
+fin:
+ (void)err;
+ }
+
+int mDNSPowerRequest(int key, int interval)
+ {
+ kern_return_t kr = KERN_FAILURE;
+ int retry = 0, err = 0;
+ MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
+ kr = proxy_mDNSPowerRequest(getHelperPort(retry), key, interval, &err);
+ MACHRETRYLOOP_END(kr, retry, err, fin);
+fin:
+ return err;
+ }
+
+int mDNSSetARP(int ifindex, const v4addr_t ip, const ethaddr_t eth)
+ {
+ kern_return_t kr = KERN_FAILURE;
+ int retry = 0, err = 0;
+ MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
+ kr = proxy_mDNSSetARP(getHelperPort(retry), ifindex, (uint8_t*)ip, (uint8_t*)eth, &err);
+ MACHRETRYLOOP_END(kr, retry, err, fin);
+fin:
return err;
}
-int
-mDNSKeychainGetSecrets(CFArrayRef *result)
+void mDNSNotify(const char *title, const char *msg) // Both strings are UTF-8 text
+ {
+ kern_return_t kr = KERN_FAILURE;
+ int retry = 0, err = 0;
+ MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
+ kr = proxy_mDNSNotify(getHelperPort(retry), title, msg);
+ MACHRETRYLOOP_END(kr, retry, err, fin);
+fin:
+ (void)err;
+ }
+
+int mDNSKeychainGetSecrets(CFArrayRef *result)
{
CFPropertyListRef plist = NULL;
CFDataRef bytes = NULL;
unsigned int numsecrets = 0;
void *secrets = NULL;
mach_msg_type_number_t secretsCnt = 0;
- int retry = 0;
- int err = 0;
+ int retry = 0, err = 0;
MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
- kr = proxy_mDNSKeychainGetSecrets(getHelperPort(retry),
- &numsecrets, (vm_offset_t *)&secrets, &secretsCnt, &err);
+ kr = proxy_mDNSKeychainGetSecrets(getHelperPort(retry), &numsecrets, (vm_offset_t *)&secrets, &secretsCnt, &err);
MACHRETRYLOOP_END(kr, retry, err, fin);
- if (NULL == (bytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
- secrets, secretsCnt, kCFAllocatorNull)))
+ if (NULL == (bytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, secrets, secretsCnt, kCFAllocatorNull)))
{
err = kmDNSHelperCreationFailed;
LogMsg("%s: CFDataCreateWithBytesNoCopy failed", __func__);
goto fin;
}
- if (NULL == (plist = CFPropertyListCreateFromXMLData(
- kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL)))
+ if (NULL == (plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL)))
{
err = kmDNSHelperInvalidPList;
LogMsg("%s: CFPropertyListCreateFromXMLData failed", __func__);
*result = (CFArrayRef)plist;
fin:
- if (NULL != bytes)
- CFRelease(bytes);
- if (NULL != secrets)
- vm_deallocate(mach_task_self(), (vm_offset_t)secrets,
- secretsCnt);
+ if (NULL != bytes) CFRelease(bytes);
+ if (NULL != secrets) vm_deallocate(mach_task_self(), (vm_offset_t)secrets, secretsCnt);
return err;
}
-int
-mDNSAutoTunnelInterfaceUpDown(int updown, v6addr_t address)
+void mDNSAutoTunnelInterfaceUpDown(int updown, v6addr_t address)
{
kern_return_t kr = KERN_SUCCESS;
- int retry = 0;
- int err = 0;
-
+ int retry = 0, err = 0;
MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
- kr = proxy_mDNSAutoTunnelInterfaceUpDown(getHelperPort(retry),
- updown, address, &err);
+ kr = proxy_mDNSAutoTunnelInterfaceUpDown(getHelperPort(retry), updown, address);
MACHRETRYLOOP_END(kr, retry, err, fin);
-
fin:
- return err;
+ (void)err;
}
-int
-mDNSConfigureServer(int updown, const char *keydata)
+void mDNSConfigureServer(int updown, const domainname *const fqdn)
{
kern_return_t kr = KERN_SUCCESS;
- int retry = 0;
- int err = 0;
-
+ int retry = 0, err = 0;
+ char fqdnStr[MAX_ESCAPED_DOMAIN_NAME] = { 0 };
+ if (fqdn && ConvertDomainNameToCString(fqdn, fqdnStr))
+ {
+ // remove the trailing dot, as that is not used in the keychain entry racoon will lookup
+ mDNSu32 fqdnEnd = mDNSPlatformStrLen(fqdnStr);
+ if (fqdnEnd) fqdnStr[fqdnEnd - 1] = 0;
+ }
MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
- kr = proxy_mDNSConfigureServer(getHelperPort(retry), updown, keydata, &err);
+ kr = proxy_mDNSConfigureServer(getHelperPort(retry), updown, fqdnStr);
MACHRETRYLOOP_END(kr, retry, err, fin);
-
fin:
- return err;
+ (void)err;
}
-int
-mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
+int mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
v4addr_t local_outer, short local_port, v6addr_t remote_inner,
- v4addr_t remote_outer, short remote_port, const char *keydata)
+ v4addr_t remote_outer, short remote_port, const domainname *const fqdn)
{
kern_return_t kr = KERN_SUCCESS;
- const char *p = NULL;
- int retry = 0;
- int err = 0;
-
- if (kmDNSAutoTunnelSetKeysReplace == replacedelete)
- p = keydata;
- else
- p = "";
+ int retry = 0, err = 0;
+ char fqdnStr[MAX_ESCAPED_DOMAIN_NAME] = { 0 };
+ if (fqdn && ConvertDomainNameToCString(fqdn, fqdnStr))
+ {
+ // remove the trailing dot, as that is not used in the keychain entry racoon will lookup
+ mDNSu32 fqdnEnd = mDNSPlatformStrLen(fqdnStr);
+ if (fqdnEnd) fqdnStr[fqdnEnd - 1] = 0;
+ }
MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
- kr = proxy_mDNSAutoTunnelSetKeys(getHelperPort(retry), replacedelete,
- local_inner, local_outer, local_port, remote_inner, remote_outer,
- remote_port, keydata, &err);
+ kr = proxy_mDNSAutoTunnelSetKeys(getHelperPort(retry), replacedelete, local_inner, local_outer, local_port, remote_inner, remote_outer, remote_port, fqdnStr, &err);
MACHRETRYLOOP_END(kr, retry, err, fin);
-
fin:
return err;
}
Change History (most recent first):
$Log: helper.c,v $
+Revision 1.66 2009/04/20 20:40:14 cheshire
+<rdar://problem/6786150> uDNS: Running location cycling caused configd and mDNSResponder to deadlock
+Changed mDNSPreferencesSetName (and similar) routines from MIG "routine" to MIG "simpleroutine"
+so we don't deadlock waiting for a result that we're just going to ignore anyway
+
+Revision 1.65 2009/03/20 22:12:28 mcguire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+Make the call to the helper a simpleroutine: don't wait for an unused return value
+
+Revision 1.64 2009/03/20 21:52:39 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+Need to CFRelease strings in do_mDNSNotify
+
+Revision 1.63 2009/03/20 21:21:15 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+Need to set error code correctly in do_mDNSNotify
+
+Revision 1.62 2009/03/20 20:52:22 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+
+Revision 1.61 2009/03/14 01:42:56 mcguire
+<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
+
+Revision 1.60 2009/02/18 02:09:10 cheshire
+<rdar://problem/6514947> Sleep Proxy: PF_ROUTE command to set ARP entry returns errno 17 (EEXIST)
+Also need to set rtmsg.hdr.rtm_index
+
+Revision 1.59 2009/02/17 23:33:45 cheshire
+<rdar://problem/6514947> Sleep Proxy: PF_ROUTE command to set ARP entry returns errno 17 (EEXIST)
+
+Revision 1.58 2009/02/04 22:23:04 cheshire
+Simplified do_mDNSPowerRequest --
+code was checking for CFAbsoluteTimeGetCurrent() returning NULL, which makes no sense
+
+Revision 1.57 2009/01/22 02:14:27 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.56 2009/01/20 21:03:22 cheshire
+Improved debugging messages
+
+Revision 1.55 2009/01/20 02:37:26 mcguire
+revert previous erroneous commit
+
+Revision 1.54 2009/01/20 02:35:15 mcguire
+mDNSMacOSX/mDNSMacOSX.c
+
+Revision 1.53 2009/01/14 01:38:42 mcguire
+<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
+
+Revision 1.52 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.51 2009/01/12 22:26:12 mkrochma
+Change DynamicStore location from BonjourSleepProxy/DiscoveredServers to SleepProxyServers
+
+Revision 1.50 2008/12/15 18:40:41 mcguire
+<rdar://problem/6444440> Socket leak in helper's doTunnelPolicy
+
+Revision 1.49 2008/12/12 00:37:42 mcguire
+<rdar://problem/6417648> BTMM outbound fails if /var/run/racoon doesn't exist
+
+Revision 1.48 2008/12/05 02:35:24 mcguire
+<rdar://problem/6107390> Write to the DynamicStore when a Sleep Proxy server is available on the network
+
+Revision 1.47 2008/11/21 02:28:55 mcguire
+<rdar://problem/6354979> send racoon a SIGUSR1 instead of SIGHUP
+
+Revision 1.46 2008/11/11 02:09:42 cheshire
+Removed some unnecessary log messages
+
+Revision 1.45 2008/11/06 23:35:38 cheshire
+Refinements to the do_mDNSSetARP() routine
+
+Revision 1.44 2008/11/05 18:41:14 cheshire
+Log errors from read() call in do_mDNSSetARP()
+
+Revision 1.43 2008/11/04 23:54:09 cheshire
+Added routine mDNSSetARP(), used to replace an SPS client's entry in our ARP cache with
+a dummy one, so that IP traffic to the SPS client initiated by the SPS machine can be
+captured by our BPF filters, and used as a trigger to wake the sleeping machine.
+
+Revision 1.42 2008/10/31 23:35:31 cheshire
+When scheduling new power event make sure all old events are deleted;
+mDNSPowerRequest(-1,-1); just clears old events without scheduling a new one
+
+Revision 1.41 2008/10/31 18:41:55 cheshire
+Do update_idle_timer() before returning from do_mDNSRequestBPF()
+
+Revision 1.40 2008/10/30 01:05:27 cheshire
+mDNSPowerRequest(0, 0) means "sleep now"
+
+Revision 1.39 2008/10/29 21:26:50 cheshire
+Only log IOPMSchedulePowerEvent calls when there's an error
+
+Revision 1.38 2008/10/24 01:42:36 cheshire
+Added mDNSPowerRequest helper routine to request a scheduled wakeup some time in the future
+
+Revision 1.37 2008/10/24 00:17:22 mcguire
+Add compatibility for older racoon behavior
+
+Revision 1.36 2008/10/22 17:22:31 cheshire
+Remove SO_NOSIGPIPE bug workaround
+
+Revision 1.35 2008/10/20 22:01:28 cheshire
+Made new Mach simpleroutine "mDNSRequestBPF"
+
+Revision 1.34 2008/10/02 23:50:07 mcguire
+<rdar://problem/6136442> shutdown time issues
+improve log messages when SCDynamicStoreCreate() fails
+
+Revision 1.33 2008/09/30 01:00:45 cheshire
+Added workaround to avoid SO_NOSIGPIPE bug
+
+Revision 1.32 2008/09/27 01:11:46 cheshire
+Added handler to respond to kmDNSSendBPF message
+
+Revision 1.31 2008/09/08 17:42:40 mcguire
+<rdar://problem/5536811> change location of racoon files
+cleanup, handle stat failure cases, reduce log messages
+
+Revision 1.30 2008/09/05 21:51:26 mcguire
+<rdar://problem/6077707> BTMM: Need to launch racoon by opening VPN control socket
+
+Revision 1.29 2008/09/05 18:26:53 mcguire
+<rdar://problem/6077707> BTMM: Need to launch racoon by opening VPN control socket
+
+Revision 1.28 2008/09/04 22:49:28 mcguire
+<rdar://problem/5536811> change location of racoon files
+
+Revision 1.27 2008/08/28 23:11:12 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+
+Revision 1.26 2008/08/19 00:35:02 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+
+Revision 1.25 2008/08/13 23:04:06 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+Preparation: rename message function, as it will no longer be called only on idle exit
+
Revision 1.24 2008/01/30 19:01:51 mcguire
<rdar://problem/5703989> Crash in mDNSResponderHelper
#include <bsm/libbsm.h>
#include <net/if.h>
#include <net/route.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
#include <netinet/in.h>
+#include <netinet/if_ether.h>
#include <netinet6/in6_var.h>
#include <netinet6/nd6.h>
#include <netinet6/ipsec.h>
#include <string.h>
#include <unistd.h>
#include <Security/Security.h>
+#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCDynamicStore.h>
#include <SystemConfiguration/SCPreferencesSetSpecific.h>
#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
#include <TargetConditionals.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+
#include "mDNSEmbeddedAPI.h"
#include "dns_sd.h"
#include "dnssd_ipc.h"
#include "helper-server.h"
#include "ipsec_options.h"
+#ifndef RTF_IFSCOPE
+#define RTF_IFSCOPE 0x1000000
+#endif
+
#if TARGET_OS_EMBEDDED
#define NO_CFUSERNOTIFICATION 1
#define NO_SECURITYFRAMEWORK 1
#endif
+// Embed the client stub code here, so we can access private functions like ConnectToServer, create_hdr, deliver_request
+#include "../mDNSShared/dnssd_ipc.c"
+#include "../mDNSShared/dnssd_clientstub.c"
+
typedef struct sadb_x_policy *ipsec_policy_t;
uid_t mDNSResponderUID;
return ok;
}
-#ifndef MDNS_NO_IPSEC
-static void
-closefds(int from)
+kern_return_t
+do_mDNSExit(__unused mach_port_t port, audit_token_t token)
{
- int fd = 0;
- struct dirent entry, *entryp = NULL;
- DIR *dirp = opendir("/dev/fd");
+ debug("entry");
+ if (!authorized(&token))
+ goto fin;
+ helplog(ASL_LEVEL_INFO, "exit");
+ exit(0);
- if (dirp == NULL)
+fin:
+ debug("fin");
+ return KERN_SUCCESS;
+ }
+
+kern_return_t do_mDNSRequestBPF(__unused mach_port_t port, audit_token_t token)
+ {
+ if (!authorized(&token)) return KERN_SUCCESS;
+ DNSServiceRef ref;
+ DNSServiceErrorType err = ConnectToServer(&ref, 0, send_bpf, NULL, NULL, NULL);
+ if (err) { helplog(ASL_LEVEL_ERR, "do_mDNSRequestBPF: ConnectToServer %d", err); return err; }
+
+ char *ptr;
+ size_t len = sizeof(DNSServiceFlags);
+ ipc_msg_hdr *hdr = create_hdr(send_bpf, &len, &ptr, 0, ref);
+ if (!hdr) { DNSServiceRefDeallocate(ref); return kDNSServiceErr_NoMemory; }
+ put_flags(0, &ptr);
+ deliver_request(hdr, ref); // Will free hdr for us
+ DNSServiceRefDeallocate(ref);
+ update_idle_timer();
+ return KERN_SUCCESS;
+ }
+
+kern_return_t do_mDNSPowerRequest(__unused mach_port_t port, int key, int interval, int *err, audit_token_t token)
+ {
+ *err = -1;
+ if (!authorized(&token)) { *err = kmDNSHelperNotAuthorized; goto fin; }
+
+ CFArrayRef events = IOPMCopyScheduledPowerEvents();
+ if (events)
{
- /* fall back to the erroneous getdtablesize method */
- for (fd = from; fd < getdtablesize(); ++fd)
- close(fd);
- return;
+ int i;
+ CFIndex count = CFArrayGetCount(events);
+ for (i=0; i<count; i++)
+ {
+ CFDictionaryRef dict = CFArrayGetValueAtIndex(events, i);
+ CFStringRef id = CFDictionaryGetValue(dict, CFSTR(kIOPMPowerEventAppNameKey));
+ if (CFEqual(id, CFSTR("mDNSResponderHelper")))
+ {
+ CFDateRef EventTime = CFDictionaryGetValue(dict, CFSTR(kIOPMPowerEventTimeKey));
+ CFStringRef EventType = CFDictionaryGetValue(dict, CFSTR(kIOPMPowerEventTypeKey));
+ IOReturn result = IOPMCancelScheduledPowerEvent(EventTime, id, EventType);
+ //helplog(ASL_LEVEL_ERR, "Deleting old event %s");
+ if (result) helplog(ASL_LEVEL_ERR, "IOPMCancelScheduledPowerEvent %d failed %d", i, result);
+ }
+ }
+ CFRelease(events);
}
- while (0 == readdir_r(dirp, &entry, &entryp) && NULL != entryp)
+
+ if (key < 0) // mDNSPowerRequest(-1,-1) means "clear any stale schedules" (see above)
+ *err = 0;
+ else if (key == 0) // mDNSPowerRequest(0, 0) means "sleep now"
{
- fd = atoi(entryp->d_name);
- if (fd >= from && fd != dirfd(dirp))
- close(fd);
+ IOReturn r = IOPMSleepSystem(IOPMFindPowerManagement(MACH_PORT_NULL));
+ if (r) { usleep(100000); helplog(ASL_LEVEL_ERR, "IOPMSleepSystem %d", r); }
+ *err = r;
}
- closedir(dirp);
+ else if (key > 0)
+ {
+ CFDateRef w = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent() + interval);
+ if (w)
+ {
+ IOReturn r = IOPMSchedulePowerEvent(w, CFSTR("mDNSResponderHelper"), key ? CFSTR(kIOPMAutoWake) : CFSTR(kIOPMAutoSleep));
+ if (r) { usleep(100000); helplog(ASL_LEVEL_ERR, "IOPMSchedulePowerEvent(%d) %d %x", interval, r, r); }
+ *err = r;
+ CFRelease(w);
+ }
+ }
+fin:
+ update_idle_timer();
+ return KERN_SUCCESS;
}
-#endif
-kern_return_t
-do_mDNSIdleExit(__unused mach_port_t port, audit_token_t token)
+kern_return_t do_mDNSSetARP(__unused mach_port_t port, int ifindex, v4addr_t v4, ethaddr_t eth, int *err, audit_token_t token)
{
- debug("entry");
- if (!authorized(&token))
- goto fin;
- helplog(ASL_LEVEL_INFO, "Idle exit");
- exit(0);
+ //helplog(ASL_LEVEL_ERR, "do_mDNSSetARP %d %d.%d.%d.%d %02X:%02X:%02X:%02X:%02X:%02X",
+ // ifindex, v4[0], v4[1], v4[2], v4[3], eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
+
+ *err = -1;
+ if (!authorized(&token)) { *err = kmDNSHelperNotAuthorized; goto fin; }
+
+ static int s = -1, seq = 0;
+ if (s < 0)
+ {
+ s = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (s < 0) helplog(ASL_LEVEL_ERR, "do_mDNSSetARP: socket(PF_ROUTE, SOCK_RAW, 0) failed %d (%s)", errno, strerror(errno));
+ }
+
+ if (s >= 0)
+ {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+
+ struct { struct rt_msghdr hdr; struct sockaddr_inarp dst; struct sockaddr_dl sdl; } rtmsg;
+ memset(&rtmsg, 0, sizeof(rtmsg));
+
+ rtmsg.hdr.rtm_msglen = sizeof(rtmsg);
+ rtmsg.hdr.rtm_version = RTM_VERSION;
+ rtmsg.hdr.rtm_type = RTM_ADD;
+ rtmsg.hdr.rtm_index = ifindex;
+ rtmsg.hdr.rtm_flags = RTF_HOST | RTF_STATIC | RTF_IFSCOPE;
+ rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
+ rtmsg.hdr.rtm_pid = 0;
+ rtmsg.hdr.rtm_seq = seq++;
+ rtmsg.hdr.rtm_errno = 0;
+ rtmsg.hdr.rtm_use = 0;
+ rtmsg.hdr.rtm_inits = RTV_EXPIRE;
+ rtmsg.hdr.rtm_rmx.rmx_expire = tv.tv_sec + 30;
+
+ rtmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
+ rtmsg.dst.sin_family = AF_INET;
+ rtmsg.dst.sin_port = 0;
+ rtmsg.dst.sin_addr.s_addr = *(in_addr_t*)v4;
+ rtmsg.dst.sin_srcaddr.s_addr = 0;
+ rtmsg.dst.sin_tos = 0;
+ rtmsg.dst.sin_other = 0;
+
+ rtmsg.sdl.sdl_len = sizeof(struct sockaddr_dl);
+ rtmsg.sdl.sdl_family = AF_LINK;
+ rtmsg.sdl.sdl_index = ifindex;
+ rtmsg.sdl.sdl_type = IFT_ETHER;
+ rtmsg.sdl.sdl_nlen = 0;
+ rtmsg.sdl.sdl_alen = ETHER_ADDR_LEN;
+ rtmsg.sdl.sdl_slen = 0;
+
+ // Target MAC address goes in rtmsg.sdl.sdl_data[0..5]; (See LLADDR() in /usr/include/net/if_dl.h)
+ memcpy(rtmsg.sdl.sdl_data, eth, sizeof(ethaddr_t));
+
+ int len = write(s, (char *)&rtmsg, sizeof(rtmsg));
+ if (len < 0)
+ helplog(ASL_LEVEL_ERR, "do_mDNSSetARP: write(%d) interface %d address %d.%d.%d.%d seq %d result %d errno %d (%s)",
+ sizeof(rtmsg), ifindex, v4[0], v4[1], v4[2], v4[3], rtmsg.hdr.rtm_seq, len, errno, strerror(errno));
+ len = read(s, (char *)&rtmsg, sizeof(rtmsg));
+ if (len < 0)
+ helplog(ASL_LEVEL_ERR, "do_mDNSSetARP: read (%d) interface %d address %d.%d.%d.%d seq %d result %d errno %d (%s)",
+ sizeof(rtmsg), ifindex, v4[0], v4[1], v4[2], v4[3], rtmsg.hdr.rtm_seq, len, errno, strerror(errno));
+
+ *err = 0;
+ }
fin:
- debug("fin");
+ update_idle_timer();
+ return KERN_SUCCESS;
+ }
+
+kern_return_t do_mDNSNotify(__unused mach_port_t port, const char *title, const char *msg, audit_token_t token)
+ {
+ if (!authorized(&token)) return KERN_SUCCESS;
+
+#ifndef NO_CFUSERNOTIFICATION
+ static const char footer[] = "(Note: This message only appears on machines with 17.x.x.x IP addresses — i.e. at Apple — not on customer machines.)";
+ CFStringRef alertHeader = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
+ CFStringRef alertBody = CFStringCreateWithCString(NULL, msg, kCFStringEncodingUTF8);
+ CFStringRef alertFooter = CFStringCreateWithCString(NULL, footer, kCFStringEncodingUTF8);
+ CFStringRef alertMessage = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\r\r%@"), alertBody, alertFooter);
+ CFRelease(alertBody);
+ CFRelease(alertFooter);
+ int err = CFUserNotificationDisplayNotice(0.0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, alertHeader, alertMessage, NULL);
+ if (err) helplog(ASL_LEVEL_ERR, "CFUserNotificationDisplayNotice returned %d", err);
+ CFRelease(alertHeader);
+ CFRelease(alertMessage);
+#endif /* NO_CFUSERNOTIFICATION */
+
+ update_idle_timer();
return KERN_SUCCESS;
}
kern_return_t
do_mDNSDynamicStoreSetConfig(__unused mach_port_t port, int key,
- vm_offset_t value, mach_msg_type_number_t valueCnt, int *err,
+ const char* subkey, vm_offset_t value, mach_msg_type_number_t valueCnt,
audit_token_t token)
{
CFStringRef sckey = NULL;
+ Boolean release_sckey = FALSE;
CFDataRef bytes = NULL;
CFPropertyListRef plist = NULL;
SCDynamicStoreRef store = NULL;
debug("entry");
- *err = 0;
- if (!authorized(&token))
- {
- *err = kmDNSHelperNotAuthorized;
- goto fin;
- }
+ if (!authorized(&token)) goto fin;
+
switch ((enum mDNSDynamicStoreSetConfigKey)key)
- {
- case kmDNSMulticastConfig:
- sckey = CFSTR("State:/Network/" kDNSServiceCompMulticastDNS);
- break;
- case kmDNSDynamicConfig:
- sckey = CFSTR("State:/Network/DynamicDNS");
- break;
- case kmDNSPrivateConfig:
- sckey = CFSTR("State:/Network/" kDNSServiceCompPrivateDNS);
- break;
- case kmDNSBackToMyMacConfig:
- sckey = CFSTR("State:/Network/BackToMyMac");
- break;
- default:
- debug("unrecognized key %d", key);
- *err = kmDNSHelperInvalidConfigKey;
- goto fin;
+ {
+ case kmDNSMulticastConfig:
+ sckey = CFSTR("State:/Network/" kDNSServiceCompMulticastDNS);
+ break;
+ case kmDNSDynamicConfig:
+ sckey = CFSTR("State:/Network/DynamicDNS");
+ break;
+ case kmDNSPrivateConfig:
+ sckey = CFSTR("State:/Network/" kDNSServiceCompPrivateDNS);
+ break;
+ case kmDNSBackToMyMacConfig:
+ sckey = CFSTR("State:/Network/BackToMyMac");
+ break;
+ case kmDNSSleepProxyServersState:
+ {
+ CFMutableStringRef tmp = CFStringCreateMutable(kCFAllocatorDefault, 0);
+ CFStringAppend(tmp, CFSTR("State:/Network/Interface/"));
+ CFStringAppendCString(tmp, subkey, kCFStringEncodingUTF8);
+ CFStringAppend(tmp, CFSTR("/SleepProxyServers"));
+ sckey = CFStringCreateCopy(kCFAllocatorDefault, tmp);
+ release_sckey = TRUE;
+ CFRelease(tmp);
+ break;
+ }
+ default:
+ debug("unrecognized key %d", key);
+ goto fin;
}
if (NULL == (bytes = CFDataCreateWithBytesNoCopy(NULL, (void *)value,
valueCnt, kCFAllocatorNull)))
{
debug("CFDataCreateWithBytesNoCopy of value failed");
- *err = kmDNSHelperCreationFailed;
goto fin;
}
if (NULL == (plist = CFPropertyListCreateFromXMLData(NULL, bytes,
kCFPropertyListImmutable, NULL)))
{
debug("CFPropertyListCreateFromXMLData of bytes failed");
- *err = kmDNSHelperInvalidPList;
goto fin;
}
CFRelease(bytes);
if (NULL == (store = SCDynamicStoreCreate(NULL,
CFSTR(kmDNSHelperServiceName), NULL, NULL)))
{
- debug("SCDynamicStoreCreate failed");
- *err = kmDNSHelperDynamicStoreFailed;
+ debug("SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
goto fin;
}
SCDynamicStoreSetValue(store, sckey, plist);
- *err = 0;
debug("succeeded");
fin:
- if (0 != *err)
- debug("failed err=%d", *err);
if (NULL != bytes)
CFRelease(bytes);
if (NULL != plist)
CFRelease(plist);
if (NULL != store)
CFRelease(store);
+ if (release_sckey && sckey)
+ CFRelease(sckey);
vm_deallocate(mach_task_self(), value, valueCnt);
update_idle_timer();
return KERN_SUCCESS;
}
kern_return_t
-do_mDNSPreferencesSetName(__unused mach_port_t port, int key, const char* old, const char* new, int *err, audit_token_t token)
+do_mDNSPreferencesSetName(__unused mach_port_t port, int key, const char* old, const char* new, audit_token_t token)
{
SCPreferencesRef session = NULL;
Boolean ok = FALSE;
Boolean needUpdate = FALSE;
debug("entry %s old=%s new=%s", key==kmDNSComputerName ? "ComputerName" : (key==kmDNSLocalHostName ? "LocalHostName" : "UNKNOWN"), old, new);
- *err = 0;
- if (!authorized(&token))
- {
- *err = kmDNSHelperNotAuthorized;
- goto fin;
- }
+ if (!authorized(&token)) goto fin;
+
switch ((enum mDNSPreferencesSetNameKey)key)
{
case kmDNSComputerName:
break;
default:
debug("unrecognized key: %d", key);
- *err = kmDNSHelperInvalidNameKey;
goto fin;
}
if (cfstr == NULL || session == NULL)
{
debug("SCPreferencesCreate failed");
- *err = kmDNSHelperPreferencesFailed;
goto fin;
}
if (!SCPreferencesLock(session, 0))
{
debug("lock failed");
- *err = kmDNSHelperPreferencesLockFailed;
goto fin;
}
locked = TRUE;
!SCPreferencesApplyChanges(session))
{
debug("SCPreferences update failed");
- *err = kmDNSHelperPreferencesSetFailed;
goto fin;
}
- *err = 0;
debug("succeeded");
fin:
- if (0 != *err)
- debug("failed err=%d", *err);
if (NULL != cfstr)
CFRelease(cfstr);
if (NULL != session)
err = kmDNSHelperDatagramSocketCreationFailed;
goto fin;
}
- bzero(&ifra_in6, sizeof(ifra_in6));
+ memset(&ifra_in6, 0, sizeof(ifra_in6));
strlcpy(ifra_in6.ifra_name, kTunnelAddressInterface,
sizeof(ifra_in6.ifra_name));
ifra_in6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
err = kmDNSHelperDatagramSocketCreationFailed;
goto fin;
}
- bzero(&ifr, sizeof(ifr));
+ memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, kTunnelAddressInterface, sizeof(ifr.ifr_name));
ifr.ifr_ifru.ifru_addr.sin6_family = AF_INET6;
ifr.ifr_ifru.ifru_addr.sin6_len = sizeof(struct sockaddr_in6);
int
do_mDNSAutoTunnelInterfaceUpDown(__unused mach_port_t port, int updown,
- v6addr_t address, int *err, audit_token_t token)
+ v6addr_t address, audit_token_t token)
{
#ifndef MDNS_NO_IPSEC
debug("entry");
- *err = 0;
- if (!authorized(&token))
- {
- *err = kmDNSHelperNotAuthorized;
- goto fin;
- }
+ if (!authorized(&token)) goto fin;
+
switch ((enum mDNSUpDown)updown)
- {
- case kmDNSUp:
- *err = aliasTunnelAddress(address);
- break;
- case kmDNSDown:
- *err = unaliasTunnelAddress(address);
- break;
- default:
- *err = kmDNSHelperInvalidInterfaceState;
- goto fin;
+ {
+ case kmDNSUp:
+ aliasTunnelAddress(address);
+ break;
+ case kmDNSDown:
+ unaliasTunnelAddress(address);
+ break;
+ default:
+ goto fin;
}
debug("succeeded");
}
#ifndef MDNS_NO_IPSEC
-static const char racoon_config_path[] = "/etc/racoon/remote/anonymous.conf";
-static const char racoon_config_path_orig[] = "/etc/racoon/remote/anonymous.conf.orig";
+
+static const char g_racoon_config_dir[] = "/var/run/racoon/";
+static const char g_racoon_config_dir_old[] = "/etc/racoon/remote/";
+
+CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
+CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
+
+// Major version 6 is 10.2.x (Jaguar)
+// Major version 7 is 10.3.x (Panther)
+// Major version 8 is 10.4.x (Tiger)
+// Major version 9 is 10.5.x (Leopard)
+// Major version 10 is 10.6.x (SnowLeopard)
+static int MacOSXSystemBuildNumber(char* letter_out, int* minor_out)
+ {
+ int major = 0, minor = 0;
+ char letter = 0, buildver[256]="<Unknown>";
+ CFDictionaryRef vers = _CFCopySystemVersionDictionary();
+ if (vers)
+ {
+ CFStringRef cfbuildver = CFDictionaryGetValue(vers, _kCFSystemVersionBuildVersionKey);
+ if (cfbuildver) CFStringGetCString(cfbuildver, buildver, sizeof(buildver), kCFStringEncodingUTF8);
+ sscanf(buildver, "%d%c%d", &major, &letter, &minor);
+ CFRelease(vers);
+ }
+ else
+ helplog(ASL_LEVEL_NOTICE, "_CFCopySystemVersionDictionary failed");
+
+ if (!major) { major=10; letter = 'A'; minor = 190; helplog(ASL_LEVEL_NOTICE, "Note: No Major Build Version number found; assuming 10A190"); }
+ if (letter_out) *letter_out = letter;
+ if (minor_out) *minor_out = minor;
+ return(major);
+ }
+
+static int g_oldRacoon = -1;
+static int g_racoonSignal = SIGUSR1;
+
+static void DetermineRacoonVersion()
+ {
+ if (g_oldRacoon == -1)
+ {
+ char letter = 0;
+ int minor = 0;
+ g_oldRacoon = (MacOSXSystemBuildNumber(&letter, &minor) < 10);
+ if (g_oldRacoon || (letter == 'A' && minor < 218)) g_racoonSignal = SIGHUP;
+ debug("%s, signal=%d", g_oldRacoon?"old":"new", g_racoonSignal);
+ }
+ }
+
+static int UseOldRacoon()
+ {
+ DetermineRacoonVersion();
+ return g_oldRacoon;
+ }
+
+static int RacoonSignal()
+ {
+ DetermineRacoonVersion();
+ return g_racoonSignal;
+ }
+
+static const char* GetRacoonConfigDir()
+ {
+ return UseOldRacoon() ? g_racoon_config_dir_old : g_racoon_config_dir;
+ }
+
+static const char* GetOldRacoonConfigDir()
+ {
+ return UseOldRacoon() ? NULL : g_racoon_config_dir_old;
+ }
+
+static const char racoon_config_file[] = "anonymous.conf";
+static const char racoon_config_file_orig[] = "anonymous.conf.orig";
static const char configHeader[] = "# BackToMyMac\n";
-static int IsFamiliarRacoonConfiguration()
+static int IsFamiliarRacoonConfiguration(const char* racoon_config_path)
{
int fd = open(racoon_config_path, O_RDONLY);
- debug("entry");
+ debug("entry %s", racoon_config_path);
if (0 > fd)
{
helplog(ASL_LEVEL_NOTICE, "open \"%s\" failed: %s", racoon_config_path, strerror(errno));
}
static void
-revertAnonymousRacoonConfiguration()
+revertAnonymousRacoonConfiguration(const char* dir)
{
- debug("entry");
- if (!IsFamiliarRacoonConfiguration())
+ if (!dir) return;
+
+ debug("entry %s", dir);
+
+ char racoon_config_path[64];
+ strlcpy(racoon_config_path, dir, sizeof(racoon_config_path));
+ strlcat(racoon_config_path, racoon_config_file, sizeof(racoon_config_path));
+
+ struct stat s;
+ int ret = stat(racoon_config_path, &s);
+ debug("stat(%s): %d errno=%d", racoon_config_path, ret, errno);
+ if (ret == 0)
{
- helplog(ASL_LEVEL_NOTICE, "\"%s\" does not look familiar, leaving in place", racoon_config_path);
+ if (IsFamiliarRacoonConfiguration(racoon_config_path))
+ {
+ helplog(ASL_LEVEL_INFO, "\"%s\" looks familiar, unlinking", racoon_config_path);
+ unlink(racoon_config_path);
+ }
+ else
+ {
+ helplog(ASL_LEVEL_NOTICE, "\"%s\" does not look familiar, leaving in place", racoon_config_path);
+ return;
+ }
+ }
+ else if (errno != ENOENT)
+ {
+ helplog(ASL_LEVEL_NOTICE, "stat failed for \"%s\", leaving in place: %s", racoon_config_path, strerror(errno));
return;
}
- if (0 > rename(racoon_config_path_orig, racoon_config_path))
+ char racoon_config_path_orig[64];
+ strlcpy(racoon_config_path_orig, dir, sizeof(racoon_config_path_orig));
+ strlcat(racoon_config_path_orig, racoon_config_file_orig, sizeof(racoon_config_path_orig));
+
+ ret = stat(racoon_config_path_orig, &s);
+ debug("stat(%s): %d errno=%d", racoon_config_path_orig, ret, errno);
+ if (ret == 0)
{
- helplog(ASL_LEVEL_NOTICE, "rename \"%s\" \"%s\" failed: %s", racoon_config_path_orig, racoon_config_path, strerror(errno));
- helplog(ASL_LEVEL_NOTICE, "\"%s\" looks familiar, unlinking", racoon_config_path);
- unlink(racoon_config_path);
+ if (0 > rename(racoon_config_path_orig, racoon_config_path))
+ helplog(ASL_LEVEL_NOTICE, "rename \"%s\" \"%s\" failed: %s", racoon_config_path_orig, racoon_config_path, strerror(errno));
+ else
+ debug("reverted \"%s\" to \"%s\"", racoon_config_path_orig, racoon_config_path);
+ }
+ else if (errno != ENOENT)
+ {
+ helplog(ASL_LEVEL_NOTICE, "stat failed for \"%s\", leaving in place: %s", racoon_config_path_orig, strerror(errno));
+ return;
+ }
+ }
+
+static void
+moveAsideAnonymousRacoonConfiguration(const char* dir)
+ {
+ if (!dir) return;
+
+ debug("entry %s", dir);
+
+ char racoon_config_path[64];
+ strlcpy(racoon_config_path, dir, sizeof(racoon_config_path));
+ strlcat(racoon_config_path, racoon_config_file, sizeof(racoon_config_path));
+
+ struct stat s;
+ int ret = stat(racoon_config_path, &s);
+ if (ret == 0)
+ {
+ if (IsFamiliarRacoonConfiguration(racoon_config_path))
+ {
+ helplog(ASL_LEVEL_INFO, "\"%s\" looks familiar, unlinking", racoon_config_path);
+ unlink(racoon_config_path);
+ }
+ else
+ {
+ char racoon_config_path_orig[64];
+ strlcpy(racoon_config_path_orig, dir, sizeof(racoon_config_path_orig));
+ strlcat(racoon_config_path_orig, racoon_config_file_orig, sizeof(racoon_config_path_orig));
+ if (0 > rename(racoon_config_path, racoon_config_path_orig)) // If we didn't write it, move it to the side so it can be reverted later
+ helplog(ASL_LEVEL_NOTICE, "rename \"%s\" to \"%s\" failed: %s", racoon_config_path, racoon_config_path_orig, strerror(errno));
+ else
+ debug("successfully renamed \"%s\" to \"%s\"", racoon_config_path, racoon_config_path_orig);
+ }
+ }
+ else if (errno != ENOENT)
+ {
+ helplog(ASL_LEVEL_NOTICE, "stat failed for \"%s\", leaving in place: %s", racoon_config_path, strerror(errno));
+ return;
}
}
static int
-createAnonymousRacoonConfiguration(const char *keydata)
+ensureExistenceOfRacoonConfigDir(const char* const racoon_config_dir)
+ {
+ struct stat s;
+ int ret = stat(racoon_config_dir, &s);
+ if (ret != 0)
+ {
+ if (errno != ENOENT)
+ {
+ helplog(ASL_LEVEL_ERR, "stat of \"%s\" failed (%d): %s",
+ racoon_config_dir, ret, strerror(errno));
+ return -1;
+ }
+ else
+ {
+ ret = mkdir(racoon_config_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ if (ret != 0)
+ {
+ helplog(ASL_LEVEL_ERR, "mkdir \"%s\" failed: %s",
+ racoon_config_dir, strerror(errno));
+ return -1;
+ }
+ else
+ helplog(ASL_LEVEL_INFO, "created directory \"%s\"", racoon_config_dir);
+ }
+ }
+ else if (!(s.st_mode & S_IFDIR))
+ {
+ helplog(ASL_LEVEL_ERR, "\"%s\" is not a directory!",
+ racoon_config_dir);
+ return -1;
+ }
+
+ return 0;
+ }
+
+static int
+createAnonymousRacoonConfiguration(const char *fqdn)
{
static const char config1[] =
"remote anonymous {\n"
" situation identity_only;\n"
" verify_identifier off;\n"
" generate_policy on;\n"
- " shared_secret use \"";
+ " shared_secret keychain_by_id \"dns:";
static const char config2[] =
"\";\n"
" nonce_size 16;\n"
" authentication_algorithm hmac_sha1;\n"
" compression_algorithm deflate;\n"
"}\n";
- char tmp_config_path[] =
- "/etc/racoon/remote/tmp.XXXXXX";
- int fd = mkstemp(tmp_config_path);
-
+ char tmp_config_path[64];
+ char racoon_config_path[64];
+ const char* const racoon_config_dir = GetRacoonConfigDir();
+ const char* const racoon_config_dir_old = GetOldRacoonConfigDir();
+ int fd = -1;
+
debug("entry");
+
+ if (0 > ensureExistenceOfRacoonConfigDir(racoon_config_dir))
+ return -1;
+
+ strlcpy(tmp_config_path, racoon_config_dir, sizeof(tmp_config_path));
+ strlcat(tmp_config_path, "tmp.XXXXXX", sizeof(tmp_config_path));
+
+ fd = mkstemp(tmp_config_path);
if (0 > fd)
{
}
write(fd, configHeader, sizeof(configHeader)-1);
write(fd, config1, sizeof(config1)-1);
- write(fd, keydata, strlen(keydata));
+ write(fd, fqdn, strlen(fqdn));
write(fd, config2, sizeof(config2)-1);
close(fd);
- if (IsFamiliarRacoonConfiguration())
- helplog(ASL_LEVEL_NOTICE, "\"%s\" looks familiar, will overwrite", racoon_config_path);
- else if (0 > rename(racoon_config_path, racoon_config_path_orig)) // If we didn't write it, move it to the side so it can be reverted later
- helplog(ASL_LEVEL_NOTICE, "rename \"%s\" \"%s\" failed: %s", racoon_config_path, racoon_config_path_orig, strerror(errno));
- else
- debug("successfully renamed \"%s\" \"%s\"", racoon_config_path, racoon_config_path_orig);
+ strlcpy(racoon_config_path, racoon_config_dir, sizeof(racoon_config_path));
+ strlcat(racoon_config_path, racoon_config_file, sizeof(racoon_config_path));
+
+ moveAsideAnonymousRacoonConfiguration(racoon_config_dir_old);
+ moveAsideAnonymousRacoonConfiguration(racoon_config_dir);
if (0 > rename(tmp_config_path, racoon_config_path))
{
unlink(tmp_config_path);
helplog(ASL_LEVEL_ERR, "rename \"%s\" \"%s\" failed: %s",
tmp_config_path, racoon_config_path, strerror(errno));
- revertAnonymousRacoonConfiguration();
+ revertAnonymousRacoonConfiguration(racoon_config_dir_old);
+ revertAnonymousRacoonConfiguration(racoon_config_dir);
return -1;
}
debug("refusing to kill PID %lu", m);
return kmDNSHelperRacoonNotificationFailed;
}
- if (0 != kill(m, SIGHUP))
+ if (0 != kill(m, RacoonSignal()))
{
debug("Could not signal racoon (%lu): %s", m, strerror(errno));
return kmDNSHelperRacoonNotificationFailed;
}
- debug("Sent SIGHUP to racoon (%lu)", m);
+ debug("Sent racoon (%lu) signal %d", m, RacoonSignal());
return 0;
}
+static void
+closefds(int from)
+ {
+ int fd = 0;
+ struct dirent entry, *entryp = NULL;
+ DIR *dirp = opendir("/dev/fd");
+
+ if (dirp == NULL)
+ {
+ /* fall back to the erroneous getdtablesize method */
+ for (fd = from; fd < getdtablesize(); ++fd)
+ close(fd);
+ return;
+ }
+ while (0 == readdir_r(dirp, &entry, &entryp) && NULL != entryp)
+ {
+ fd = atoi(entryp->d_name);
+ if (fd >= from && fd != dirfd(dirp))
+ close(fd);
+ }
+ closedir(dirp);
+ }
+
static int
-startRacoon(void)
+startRacoonOld(void)
{
debug("entry");
char * const racoon_args[] = { "/usr/sbin/racoon", "-e", NULL };
return 0;
}
+// constant and structure for the racoon control socket
+#define VPNCTL_CMD_PING 0x0004
+typedef struct vpnctl_hdr_struct
+ {
+ u_int16_t msg_type;
+ u_int16_t flags;
+ u_int32_t cookie;
+ u_int32_t reserved;
+ u_int16_t result;
+ u_int16_t len;
+ } vpnctl_hdr;
+
+static int
+startRacoon(void)
+ {
+ debug("entry");
+ int fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (0 > fd)
+ {
+ helplog(ASL_LEVEL_ERR, "Could not create endpoint for racoon control socket: %d %s",
+ errno, strerror(errno));
+ return kmDNSHelperRacoonStartFailed;
+ }
+
+ struct sockaddr_un saddr;
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sun_family = AF_UNIX;
+ saddr.sun_len = sizeof(saddr);
+ static const char racoon_control_sock_path[] = "/var/run/vpncontrol.sock";
+ strcpy(saddr.sun_path, racoon_control_sock_path);
+ int result = connect(fd, (struct sockaddr*) &saddr, saddr.sun_len);
+ if (0 > result)
+ {
+ helplog(ASL_LEVEL_ERR, "Could not connect racoon control socket %s: %d %s",
+ racoon_control_sock_path, errno, strerror(errno));
+ return kmDNSHelperRacoonStartFailed;
+ }
+
+ u_int32_t btmm_cookie = 0x4d4d5442;
+ vpnctl_hdr h = { VPNCTL_CMD_PING, 0, btmm_cookie, 0, 0, 0 };
+ size_t bytes = 0;
+ ssize_t ret = 0;
+
+ while (bytes < sizeof(vpnctl_hdr))
+ {
+ ret = write(fd, ((unsigned char*)&h)+bytes, sizeof(vpnctl_hdr) - bytes);
+ if (ret == -1)
+ {
+ helplog(ASL_LEVEL_ERR, "Could not write to racoon control socket: %d %s",
+ errno, strerror(errno));
+ return kmDNSHelperRacoonStartFailed;
+ }
+ bytes += ret;
+ }
+
+ int nfds = fd + 1;
+ fd_set fds;
+ int counter = 0;
+ struct timeval tv;
+ bytes = 0;
+ h.cookie = 0;
+
+ while (counter < 100)
+ {
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ tv = (struct timeval){ 0, 10000 }; // 10 milliseconds * 100 iterations = 1 second max wait time
+
+ result = select(nfds, &fds, (fd_set*)NULL, (fd_set*)NULL, &tv);
+ if (result > 0)
+ {
+ if (FD_ISSET(fd, &fds))
+ {
+ ret = read(fd, ((unsigned char*)&h)+bytes, sizeof(vpnctl_hdr) - bytes);
+
+ if (ret == -1)
+ {
+ helplog(ASL_LEVEL_ERR, "Could not read from racoon control socket: %d %s",
+ strerror(errno));
+ break;
+ }
+ bytes += ret;
+ if (bytes >= sizeof(vpnctl_hdr)) break;
+ }
+ else
+ {
+ debug("select returned but fd_isset not on expected fd\n");
+ }
+ }
+ else if (result < 0)
+ {
+ debug("select returned %d errno %d %s\n", result, errno, strerror(errno));
+ if (errno != EINTR) break;
+ }
+ }
+
+ close(fd);
+
+ if (bytes < sizeof(vpnctl_hdr) || h.cookie != btmm_cookie) return kmDNSHelperRacoonStartFailed;
+
+ debug("racoon started");
+ return 0;
+ }
+
static int
kickRacoon(void)
{
if ( 0 == notifyRacoon() )
return 0;
- return startRacoon();
+ return UseOldRacoon() ? startRacoonOld() : startRacoon();
}
#endif /* ndef MDNS_NO_IPSEC */
int
-do_mDNSConfigureServer(__unused mach_port_t port, int updown, const char *keydata, int *err, audit_token_t token)
+do_mDNSConfigureServer(__unused mach_port_t port, int updown, const char *fqdn, audit_token_t token)
{
#ifndef MDNS_NO_IPSEC
debug("entry");
- *err = 0;
-
- if (!authorized(&token))
- {
- *err = kmDNSHelperNotAuthorized;
- goto fin;
- }
+ if (!authorized(&token)) goto fin;
switch ((enum mDNSUpDown)updown)
{
case kmDNSUp:
- if (0 != createAnonymousRacoonConfiguration(keydata))
- {
- *err = kmDNSHelperRacoonConfigCreationFailed;
- goto fin;
- }
+ if (0 != createAnonymousRacoonConfiguration(fqdn)) goto fin;
break;
case kmDNSDown:
- revertAnonymousRacoonConfiguration();
+ revertAnonymousRacoonConfiguration(GetOldRacoonConfigDir());
+ revertAnonymousRacoonConfiguration(GetRacoonConfigDir());
break;
default:
- *err = kmDNSHelperInvalidServerState;
goto fin;
}
- if (0 != (*err = kickRacoon()))
+ if (0 != kickRacoon())
goto fin;
debug("succeeded");
fin:
#else
- (void)port; (void)updown; (void)keydata; (void)token;
+ (void)port; (void)updown; (void)fqdn; (void)token;
*err = kmDNSHelperIPsecDisabled;
#endif
update_idle_timer();
debug("succeeded");
fin:
- if (0 >= s)
- close(s);
+ if (s >= 0)
+ pfkey_close(s);
if (NULL != policy)
free(policy);
return err;
do_mDNSAutoTunnelSetKeys(__unused mach_port_t port, int replacedelete,
v6addr_t loc_inner, v4addr_t loc_outer, uint16_t loc_port,
v6addr_t rmt_inner, v4addr_t rmt_outer, uint16_t rmt_port,
- const char *keydata, int *err, audit_token_t token)
+ const char *fqdn, int *err, audit_token_t token)
{
#ifndef MDNS_NO_IPSEC
static const char config[] =
" situation identity_only;\n"
" verify_identifier off;\n"
" generate_policy on;\n"
- " shared_secret use \"%s\";\n"
+ " my_identifier user_fqdn \"dns:%s\";\n"
+ " shared_secret keychain \"dns:%s\";\n"
" nonce_size 16;\n"
" lifetime time 5 min;\n"
" initial_contact on;\n"
lo, loc_port, ro, rmt_port);
if ((int)sizeof(path) <= snprintf(path, sizeof(path),
- "/etc/racoon/remote/%s.%u.conf", ro,
+ "%s%s.%u.conf", GetRacoonConfigDir(), ro,
rmt_port))
{
*err = kmDNSHelperResultTooLarge;
}
if (kmDNSAutoTunnelSetKeysReplace == replacedelete)
{
+ if (0 > ensureExistenceOfRacoonConfigDir(GetRacoonConfigDir()))
+ {
+ *err = kmDNSHelperRacoonConfigCreationFailed;
+ goto fin;
+ }
if ((int)sizeof(tmp_path) <=
snprintf(tmp_path, sizeof(tmp_path), "%s.XXXXXX", path))
{
}
if (0 > (fd = mkstemp(tmp_path)))
{
- helplog(ASL_LEVEL_ERR, "mktemp \"%s\" failed: %s",
+ helplog(ASL_LEVEL_ERR, "mkstemp \"%s\" failed: %s",
tmp_path, strerror(errno));
*err = kmDNSHelperRacoonConfigCreationFailed;
goto fin;
goto fin;
}
fd = -1;
- fprintf(fp, config, configHeader, ro, rmt_port, keydata, ri, li, li, ri);
+ fprintf(fp, config, configHeader, ro, rmt_port, fqdn, fqdn, ri, li, li, ri);
fclose(fp);
fp = NULL;
if (0 > rename(tmp_path, path))
Change History (most recent first):
$Log: helper.h,v $
+Revision 1.18 2009/04/20 20:40:14 cheshire
+<rdar://problem/6786150> uDNS: Running location cycling caused configd and mDNSResponder to deadlock
+Changed mDNSPreferencesSetName (and similar) routines from MIG "routine" to MIG "simpleroutine"
+so we don't deadlock waiting for a result that we're just going to ignore anyway
+
+Revision 1.17 2009/03/20 22:12:28 mcguire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+Make the call to the helper a simpleroutine: don't wait for an unused return value
+
+Revision 1.16 2009/03/20 20:52:22 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+
+Revision 1.15 2009/03/14 01:42:56 mcguire
+<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
+
+Revision 1.14 2009/01/22 02:14:27 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.13 2009/01/14 01:38:43 mcguire
+<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
+
+Revision 1.12 2009/01/12 22:26:13 mkrochma
+Change DynamicStore location from BonjourSleepProxy/DiscoveredServers to SleepProxyServers
+
+Revision 1.11 2008/12/05 02:35:24 mcguire
+<rdar://problem/6107390> Write to the DynamicStore when a Sleep Proxy server is available on the network
+
+Revision 1.10 2008/11/04 23:54:09 cheshire
+Added routine mDNSSetARP(), used to replace an SPS client's entry in our ARP cache with
+a dummy one, so that IP traffic to the SPS client initiated by the SPS machine can be
+captured by our BPF filters, and used as a trigger to wake the sleeping machine.
+
+Revision 1.9 2008/10/24 01:42:36 cheshire
+Added mDNSPowerRequest helper routine to request a scheduled wakeup some time in the future
+
+Revision 1.8 2008/10/20 22:01:28 cheshire
+Made new Mach simpleroutine "mDNSRequestBPF"
+
+Revision 1.7 2008/09/27 00:58:11 cheshire
+Added mDNSRequestBPF declaration
+
Revision 1.6 2007/09/20 22:33:17 cheshire
Tidied up inconsistent and error-prone naming -- used to be mDNSResponderHelper in
some places and mDNSResponder.helper in others; now mDNSResponderHelper everywhere
kmDNSMulticastConfig = 1,
kmDNSDynamicConfig,
kmDNSPrivateConfig,
- kmDNSBackToMyMacConfig
+ kmDNSBackToMyMacConfig,
+ kmDNSSleepProxyServersState
};
enum mDNSPreferencesSetNameKey
#include "helpermsg-types.h"
extern const char *mDNSHelperError(int errornum);
-extern int mDNSPreferencesSetName(int key, domainlabel* old, domainlabel* new);
-extern int mDNSDynamicStoreSetConfig(int key, CFPropertyListRef value);
-extern int mDNSKeychainGetSecrets(CFArrayRef *secrets);
-extern int mDNSAutoTunnelInterfaceUpDown(int updown, v6addr_t addr);
-extern int mDNSConfigureServer(int updown, const char *keydata);
-extern int mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
- v4addr_t local_outer, short local_port, v6addr_t remote_inner,
- v4addr_t remote_outer, short remote_port, const char *keydata);
+
+extern void mDNSRequestBPF(void);
+extern int mDNSPowerRequest(int key, int interval);
+extern int mDNSSetARP(int ifindex, const v4addr_t ip, const ethaddr_t eth);
+extern void mDNSNotify(const char *title, const char *msg); // Both strings are UTF-8 text
+extern void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropertyListRef value);
+extern void mDNSPreferencesSetName(int key, domainlabel *old, domainlabel *new);
+extern int mDNSKeychainGetSecrets(CFArrayRef *secrets);
+extern void mDNSAutoTunnelInterfaceUpDown(int updown, v6addr_t addr);
+extern void mDNSConfigureServer(int updown, const domainname *const fqdn);
+extern int mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
+ v4addr_t local_outer, short local_port, v6addr_t remote_inner,
+ v4addr_t remote_outer, short remote_port, const domainname *const fqdn);
#endif /* H_HELPER_H */
Change History (most recent first):
$Log: helpermsg-types.h,v $
+Revision 1.3 2009/01/22 02:14:27 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
Revision 1.2 2007/08/23 21:52:19 cheshire
Added License header
#define H_HELPERMSG_TYPES_H
#include <stdint.h>
-typedef uint8_t v6addr_t[16];
-typedef uint8_t v4addr_t[4];
+typedef uint8_t v4addr_t [ 4];
+typedef uint8_t ethaddr_t[ 6];
+typedef uint8_t v6addr_t [16];
typedef const char *string_t;
#endif /* H_HELPERMSG_TYPES_H */
Change History (most recent first):
$Log: helpermsg.defs,v $
+Revision 1.17 2009/04/20 20:40:14 cheshire
+<rdar://problem/6786150> uDNS: Running location cycling caused configd and mDNSResponder to deadlock
+Changed mDNSPreferencesSetName (and similar) routines from MIG "routine" to MIG "simpleroutine"
+so we don't deadlock waiting for a result that we're just going to ignore anyway
+
+Revision 1.16 2009/03/20 22:12:28 mcguire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+Make the call to the helper a simpleroutine: don't wait for an unused return value
+
+Revision 1.15 2009/03/20 20:52:22 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+
+Revision 1.14 2009/03/14 01:42:56 mcguire
+<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
+
+Revision 1.13 2009/01/22 02:14:26 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.12 2009/01/14 01:38:43 mcguire
+<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
+
+Revision 1.11 2008/11/04 23:54:09 cheshire
+Added routine mDNSSetARP(), used to replace an SPS client's entry in our ARP cache with
+a dummy one, so that IP traffic to the SPS client initiated by the SPS machine can be
+captured by our BPF filters, and used as a trigger to wake the sleeping machine.
+
+Revision 1.10 2008/10/24 01:42:36 cheshire
+Added mDNSPowerRequest helper routine to request a scheduled wakeup some time in the future
+
+Revision 1.9 2008/10/20 22:01:28 cheshire
+Made new Mach simpleroutine "mDNSRequestBPF"
+
+Revision 1.8 2008/09/26 21:18:13 cheshire
+Tidy up code layout
+
+Revision 1.7 2008/08/13 23:04:06 mcguire
+<rdar://problem/5858535> handle SIGTERM in mDNSResponderHelper
+Preparation: rename message function, as it will no longer be called only on idle exit
+
Revision 1.6 2007/09/07 22:44:03 mcguire
<rdar://problem/5448420> Move CFUserNotification code to mDNSResponderHelper
import "helpermsg-types.h";
-type v6addr_t = array [16] of uint8_t;
-type v4addr_t = array [4] of uint8_t;
+type v4addr_t = array [ 4] of uint8_t;
+type ethaddr_t = array [ 6] of uint8_t;
+type v6addr_t = array [16] of uint8_t;
type string_t = c_string[*:1024];
subsystem helper 1833193043;
serverprefix do_;
userprefix proxy_;
-simpleroutine mDNSIdleExit(
- port : mach_port_t;
- ServerAuditToken token : audit_token_t);
-
-routine mDNSDynamicStoreSetConfig(
- port : mach_port_t;
- key : int;
- value : pointer_t;
- out err : int;
- ServerAuditToken token : audit_token_t);
-
-routine mDNSPreferencesSetName(
- port : mach_port_t;
- key : int;
- old : string_t;
- new : string_t;
- out err : int;
- ServerAuditToken token : audit_token_t);
-
-routine mDNSKeychainGetSecrets(
- port : mach_port_t;
- out numsecrets : unsigned;
- out secrets : pointer_t;
- out err : int;
- ServerAuditToken token : audit_token_t);
-
-routine mDNSAutoTunnelInterfaceUpDown(
- port : mach_port_t;
- updown : int;
- address : v6addr_t;
- out err : int;
- ServerAuditToken token : audit_token_t);
-
-routine mDNSConfigureServer(
- port : mach_port_t;
- updown : int;
- keydata : string_t;
- out err : int;
- ServerAuditToken token : audit_token_t);
-
-routine mDNSAutoTunnelSetKeys(
- port : mach_port_t;
- replacedelete : int;
- local_inner : v6addr_t;
- local_outer : v4addr_t;
- local_port : uint16_t;
- remote_inner : v6addr_t;
- remote_outer : v4addr_t;
- remote_port : uint16_t;
- keydata : string_t;
- out err : int;
- ServerAuditToken token : audit_token_t);
+simpleroutine mDNSExit( port : mach_port_t;
+ ServerAuditToken token : audit_token_t);
+
+simpleroutine mDNSRequestBPF( port : mach_port_t;
+ ServerAuditToken token : audit_token_t);
+
+routine mDNSPowerRequest( port : mach_port_t;
+ key : int;
+ interval : int;
+ out err : int;
+ ServerAuditToken token : audit_token_t);
+
+routine mDNSSetARP( port : mach_port_t;
+ ifindex : int;
+ ip : v4addr_t;
+ eth : ethaddr_t;
+ out err : int;
+ ServerAuditToken token : audit_token_t);
+
+simpleroutine mDNSNotify( port : mach_port_t;
+ title : string_t;
+ msg : string_t;
+ ServerAuditToken token : audit_token_t);
+
+simpleroutine mDNSDynamicStoreSetConfig(
+ port : mach_port_t;
+ key : int;
+ subkey : string_t;
+ value : pointer_t;
+ ServerAuditToken token : audit_token_t);
+
+simpleroutine mDNSPreferencesSetName( port : mach_port_t;
+ key : int;
+ old : string_t;
+ new : string_t;
+ ServerAuditToken token : audit_token_t);
+
+routine mDNSKeychainGetSecrets( port : mach_port_t;
+ out numsecrets : unsigned;
+ out secrets : pointer_t;
+ out err : int;
+ ServerAuditToken token : audit_token_t);
+
+simpleroutine mDNSAutoTunnelInterfaceUpDown(
+ port : mach_port_t;
+ updown : int;
+ address : v6addr_t;
+ ServerAuditToken token : audit_token_t);
+
+simpleroutine mDNSConfigureServer( port : mach_port_t;
+ updown : int;
+ fqdn : string_t;
+ ServerAuditToken token : audit_token_t);
+
+routine mDNSAutoTunnelSetKeys( port : mach_port_t;
+ replacedelete : int;
+ local_inner : v6addr_t;
+ local_outer : v4addr_t;
+ local_port : uint16_t;
+ remote_inner : v6addr_t;
+ remote_outer : v4addr_t;
+ remote_port : uint16_t;
+ fqdn : string_t;
+ out err : int;
+ ServerAuditToken token : audit_token_t);
Change History (most recent first):
$Log: mDNSMacOSX.c,v $
-Revision 1.536.2.2 2008/07/30 01:08:17 mcguire
-<rdar://problem/6090007> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-merge r1.540 from <rdar://problem/3988320>
+Revision 1.687 2009/06/30 21:16:09 cheshire
+<rdar://problem/7020041> 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
-Revision 1.536.2.1 2008/07/29 20:48:10 mcguire
-<rdar://problem/6090007> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-merge r1.539 from <rdar://problem/3988320>
+Revision 1.686 2009/06/25 23:36:56 cheshire
+To facilitate testing, added command-line switch "-OfferSleepProxyService"
+to re-enable the previously-supported mode of operation where we offer
+sleep proxy service on desktop Macs that are set to never sleep.
+
+Revision 1.685 2009/06/25 23:15:12 cheshire
+Don't try to use private header file "IOPowerSourcesPrivate.h"
+(it prevents external developers from being able to compile the code)
+
+Revision 1.684 2009/06/24 22:14:22 cheshire
+<rdar://problem/6911445> Plugging and unplugging the power cable shouldn't cause a network change event
+
+Revision 1.683 2009/06/08 22:31:03 cheshire
+Fixed typo in comment: Portability > 35 means nominal weight < 3kg
+
+Revision 1.682 2009/05/19 23:30:31 cheshire
+Suppressed some unnecessary debugging messages; added AppleTV to list of recognized hardware
+
+Revision 1.681 2009/05/12 23:23:15 cheshire
+Removed unnecessary "mDNSPlatformTCPConnect - connect failed ... Error 50 (Network is down)" debugging message
+
+Revision 1.680 2009/05/05 01:32:50 jessic2
+<rdar://problem/6830541> regservice_callback: instance->request is NULL 0 -- Clean up spurious logs resulting from fixing this bug.
+
+Revision 1.679 2009/05/01 23:48:46 jessic2
+<rdar://problem/6830541> regservice_callback: instance->request is NULL 0
+
+Revision 1.678 2009/04/24 23:32:28 cheshire
+To facilitate testing, put back code to be a sleep proxy when set to never sleep, compiled out by compile-time switch
+
+Revision 1.677 2009/04/24 20:50:16 mcguire
+<rdar://problem/6791775> 4 second delay in DNS response
+
+Revision 1.676 2009/04/24 02:17:58 mcguire
+<rdar://problem/5264124> uDNS: Not always respecting preference order of DNS servers
+
+Revision 1.675 2009/04/23 18:51:28 mcguire
+<rdar://problem/6729406> uDNS: PPP doesn't automatically reconnect on wake from sleep (no name resolver)
+
+Revision 1.674 2009/04/23 00:58:01 jessic2
+<rdar://problem/6802117> uDNS: DNS stops working after configd crashes
+
+Revision 1.673 2009/04/22 01:19:57 jessic2
+<rdar://problem/6814585> Daemon: mDNSResponder is logging garbage for error codes because it's using %ld for int 32
+
+Revision 1.672 2009/04/21 16:34:47 mcguire
+<rdar://problem/6810663> null deref in mDNSPlatformSetDNSConfig
+
+Revision 1.671 2009/04/15 01:14:07 mcguire
+<rdar://problem/6791775> 4 second delay in DNS response
+
+Revision 1.670 2009/04/15 01:10:39 jessic2
+<rdar://problem/6466541> BTMM: Add support for setting kDNSServiceErr_NoSuchRecord in DynamicStore
+
+Revision 1.669 2009/04/11 02:02:34 mcguire
+<rdar://problem/6780046> crash in doSSLHandshake
+
+Revision 1.668 2009/04/11 00:20:08 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.667 2009/04/09 20:01:00 cheshire
+<rdar://problem/6767122> IOPMCopyActivePMPreferences not available on Apple TV
+At Rory's suggestion, removed unnecessary "Could not get Wake On LAN value" log message
+
+Revision 1.666 2009/04/07 21:57:53 cheshire
+<rdar://problem/6767122> IOPMCopyActivePMPreferences not available on Apple TV
+Put previous code back
+
+Revision 1.665 2009/04/03 21:48:44 mcguire
+Back out checkin 1.664 (<rdar://problem/6755199> MessageTracer: prepend domain to make signature field unique)
+
+Revision 1.663 2009/04/02 22:21:16 mcguire
+<rdar://problem/6577409> Adopt IOPM APIs
+
+Revision 1.662 2009/04/02 01:08:15 mcguire
+<rdar://problem/6735635> Don't be a sleep proxy when set to sleep never
+
+Revision 1.661 2009/04/01 17:50:14 mcguire
+cleanup mDNSRandom
+
+Revision 1.660 2009/04/01 01:13:10 mcguire
+<rdar://problem/6744276> Sleep Proxy: Detect lid closed
+
+Revision 1.659 2009/03/30 21:11:07 jessic2
+<rdar://problem/6728725> Need to do some polish work on MessageTracer logging
+
+Revision 1.658 2009/03/30 20:07:28 mcguire
+<rdar://problem/6736133> BTMM: SSLHandshake threads are leaking Mach ports
+
+Revision 1.657 2009/03/27 17:27:13 cheshire
+<rdar://problem/6724859> Need to support querying IPv6 DNS servers
+
+Revision 1.656 2009/03/26 05:02:48 mcguire
+fix build error in dnsextd
+
+Revision 1.655 2009/03/26 03:59:00 jessic2
+Changes for <rdar://problem/6492552&6492593&6492609&6492613&6492628&6492640&6492699>
+
+Revision 1.654 2009/03/20 20:53:26 cheshire
+Added test code for testing with MacBook Air, using a USB dongle that doesn't actually support Wake-On-LAN
+
+Revision 1.653 2009/03/20 20:52:22 cheshire
+<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
+
+Revision 1.652 2009/03/19 23:44:47 mcguire
+<rdar://problem/6699216> Properly handle EADDRINUSE
+
+Revision 1.651 2009/03/17 19:15:24 mcguire
+<rdar://problem/6655415> SSLHandshake deadlock issues
+
+Revision 1.650 2009/03/17 01:24:22 cheshire
+Updated to new Sleep Proxy metric ranges: 100000-999999; 1000000 means "do not use"
+
+Revision 1.649 2009/03/15 01:30:29 mcguire
+fix log message
+
+Revision 1.648 2009/03/15 01:16:08 mcguire
+<rdar://problem/6655415> SSLHandshake deadlock issues
+
+Revision 1.647 2009/03/14 01:42:56 mcguire
+<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
+
+Revision 1.646 2009/03/13 01:36:24 mcguire
+<rdar://problem/6657640> Reachability fixes on DNS config change
+
+Revision 1.645 2009/03/10 23:48:33 cheshire
+<rdar://problem/6665739> Task scheduling failure when Sleep Proxy Server is active
+
+Revision 1.644 2009/03/10 04:17:09 cheshire
+Check for NULL answer in UpdateSPSStatus()
+
+Revision 1.643 2009/03/10 01:15:55 cheshire
+Sleep Proxies with invalid names (score 10000) need to be ignored
+
+Revision 1.642 2009/03/08 04:46:51 mkrochma
+Change Keychain LogMsg to LogInfo
+
+Revision 1.641 2009/03/05 23:53:34 cheshire
+Removed spurious "SnowLeopardPowerChanged: wake ERROR" syslog message
+
+Revision 1.640 2009/03/05 21:57:13 cheshire
+Don't close BPF fd until we have no more records we're proxying for on that interface
+
+Revision 1.639 2009/03/04 01:45:01 cheshire
+HW_MODEL information should be LogSPS, not LogMsg
+
+Revision 1.638 2009/03/03 22:51:54 cheshire
+<rdar://problem/6504236> Sleep Proxy: Waking on same network but different interface will cause conflicts
+
+Revision 1.637 2009/02/26 22:58:47 cheshire
+<rdar://problem/6616335> Crash in mDNSResponder at mDNSResponder • CloseBPF + 75
+Fixed race condition between the kqueue thread and the CFRunLoop thread.
+
+Revision 1.636 2009/02/21 01:38:39 cheshire
+Added comment: mDNSCoreMachineSleep(m, false); // Will set m->SleepState = SleepState_Awake;
+
+Revision 1.635 2009/02/17 23:29:03 cheshire
+Throttle logging to a slower rate when running on SnowLeopard
+
+Revision 1.634 2009/02/14 00:29:17 mcguire
+fixed typo
+
+Revision 1.633 2009/02/14 00:07:11 cheshire
+Need to set up m->SystemWakeOnLANEnabled before calling UpdateInterfaceList(m, utc);
+
+Revision 1.632 2009/02/13 19:40:07 cheshire
+Improved alignment of LogSPS messages
+
+Revision 1.631 2009/02/13 18:16:05 cheshire
+Fixed some compile warnings
+
+Revision 1.630 2009/02/13 06:32:43 cheshire
+Converted LogOperation messages to LogInfo or LogSPS
+
+Revision 1.629 2009/02/12 20:57:26 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.628 2009/02/11 02:34:45 cheshire
+m->p->SystemWakeForNetworkAccessEnabled renamed to m->SystemWakeOnLANEnabled
+
+Revision 1.627 2009/02/10 00:19:17 cheshire
+<rdar://problem/6107426> Sleep Proxy: Adopt SIOCGIFWAKEFLAGS ioctl to determine interface WOMP-ability
+
+Revision 1.626 2009/02/10 00:15:38 cheshire
+<rdar://problem/6551529> Sleep Proxy: "Unknown DNS packet type 8849" logs
+
+Revision 1.625 2009/02/09 21:24:25 cheshire
+Set correct bit in ifr.ifr_wake_flags (was coincidentally working because IF_WAKE_ON_MAGIC_PACKET happens to have the value 1)
+
+Revision 1.624 2009/02/09 21:11:43 cheshire
+Need to acknowledge kIOPMSystemPowerStateCapabilityCPU message
+
+Revision 1.623 2009/02/09 06:20:42 cheshire
+Upon receiving system power change notification, make sure our m->p->SystemWakeForNetworkAccessEnabled value
+correctly reflects the current system setting
+
+Revision 1.622 2009/02/07 02:57:32 cheshire
+<rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+
+Revision 1.621 2009/02/06 03:18:12 mcguire
+<rdar://problem/6534643> BTMM: State not cleaned up on SIGTERM w/o reboot
+
+Revision 1.620 2009/02/02 22:14:11 cheshire
+Instead of repeatedly checking the Dynamic Store, use m->p->SystemWakeForNetworkAccessEnabled variable
+
+Revision 1.619 2009/01/24 02:11:58 cheshire
+Handle case where config->resolver[0]->nameserver[0] is NULL
+
+Revision 1.618 2009/01/24 01:55:51 cheshire
+Handle case where config->resolver[0]->domain is NULL
+
+Revision 1.617 2009/01/24 01:48:42 cheshire
+<rdar://problem/4786302> Implement logic to determine when to send dot-local lookups via Unicast
+
+Revision 1.616 2009/01/24 00:28:43 cheshire
+Updated comments
+
+Revision 1.615 2009/01/22 02:14:26 cheshire
+<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
+
+Revision 1.614 2009/01/21 03:43:57 mcguire
+<rdar://problem/6511765> BTMM: Add support for setting kDNSServiceErr_NATPortMappingDisabled in DynamicStore
+
+Revision 1.613 2009/01/20 02:38:41 mcguire
+fix previous checkin comment
+
+Revision 1.612 2009/01/20 02:35:15 mcguire
+<rdar://problem/6508974> don't update BTMM & SleepProxyServers status at shutdown time
+
+Revision 1.611 2009/01/17 04:15:40 cheshire
+Updated "did sleep(5)" debugging message
+
+Revision 1.610 2009/01/16 20:37:30 cheshire
+Fixed incorrect value of EOPNOTSUPP
+
+Revision 1.609 2009/01/16 03:08:13 cheshire
+Use kernel event notifications to track KEV_DL_WAKEFLAGS_CHANGED
+(indicates when SIOCGIFWAKEFLAGS changes for an interface, e.g. when AirPort
+switches from a base-station that's WakeOnLAN-capable to one that isn't)
+
+Revision 1.608 2009/01/16 01:27:03 cheshire
+Initial work to adopt SIOCGIFWAKEFLAGS ioctl to determine whether an interface is WakeOnLAN-capable
+
+Revision 1.607 2009/01/15 22:24:01 cheshire
+Get rid of unnecessary ifa_name field in NetworkInterfaceInfoOSX (it just duplicates the content of ifinfo.ifname)
+This also eliminates an unnecessary malloc, memory copy, and free
+
+Revision 1.606 2009/01/15 00:22:49 mcguire
+<rdar://problem/6437092> NAT-PMP: mDNSResponder needs to listen on 224.0.0.1:5350/UDP with REUSEPORT
+
+Revision 1.605 2009/01/14 01:38:43 mcguire
+<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
+
+Revision 1.604 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.603 2009/01/12 22:26:13 mkrochma
+Change DynamicStore location from BonjourSleepProxy/DiscoveredServers to SleepProxyServers
+
+Revision 1.602 2008/12/19 20:23:34 mcguire
+<rdar://problem/6459269> Lots of duplicate log messages about failure to bind to NAT-PMP Announcement port
+
+Revision 1.601 2008/12/15 19:51:56 mcguire
+<rdar://problem/6443067> Retry UDP socket creation only when randomizing ports
+
+Revision 1.600 2008/12/12 21:30:14 cheshire
+Additional defensive coding -- make sure InterfaceID is found in our list before using it
+
+Revision 1.599 2008/12/12 04:36:26 cheshire
+Make sure we don't overflow our BPF filter buffer
+Only add addresses for records where the InterfaceID matches
+
+Revision 1.598 2008/12/12 00:57:51 cheshire
+Updated BPF filter generation to explicitly match addresses we're proxying for,
+rather than just matching any unknown IP address
+
+Revision 1.597 2008/12/10 20:37:05 cheshire
+Don't mark interfaces like PPP as being WakeonLAN-capable
+
+Revision 1.596 2008/12/10 19:34:30 cheshire
+Use symbolic OS version names instead of literal integers
+
+Revision 1.595 2008/12/10 02:25:31 cheshire
+Minor fixes to use of LogClientOperations symbol
+
+Revision 1.594 2008/12/10 02:11:45 cheshire
+ARMv5 compiler doesn't like uncommented stuff after #endif
+
+Revision 1.593 2008/12/09 23:08:55 mcguire
+<rdar://problem/6430877> should use IP_BOUND_IF
+additional cleanup
+
+Revision 1.592 2008/12/09 19:58:44 mcguire
+<rdar://problem/6430877> should use IP_BOUND_IF
+
+Revision 1.591 2008/12/09 15:39:05 cheshire
+Workaround for bug on Leopard and earlier where Ethernet drivers report wrong link state immediately after wake from sleep
+
+Revision 1.590 2008/12/09 05:21:54 cheshire
+Should key sleep/wake handling off kIOMessageSystemWillPowerOn message -- the kIOMessageSystemHasPoweredOn
+message is delayed by some seemingly-random amount in the range 0-15 seconds.
+
+Revision 1.589 2008/12/05 02:35:25 mcguire
+<rdar://problem/6107390> Write to the DynamicStore when a Sleep Proxy server is available on the network
+
+Revision 1.588 2008/12/04 21:08:52 mcguire
+<rdar://problem/6116863> mDNS: Provide mechanism to disable Multicast advertisements
+
+Revision 1.587 2008/12/04 02:17:47 cheshire
+Additional sleep/wake debugging messages
+
+Revision 1.586 2008/11/26 20:34:55 cheshire
+Changed some "LogOperation" debugging messages to "debugf"
+
+Revision 1.585 2008/11/25 20:53:35 cheshire
+Updated portability metrics; added Xserve and PowerBook to list
+
+Revision 1.584 2008/11/25 05:07:16 cheshire
+<rdar://problem/6374328> Advertise Sleep Proxy metrics in service name
+
+Revision 1.583 2008/11/20 01:42:31 cheshire
+For consistency with other parts of the code, changed code to only check
+that the first 4 bytes of MAC address are zero, not the whole 6 bytes.
+
+Revision 1.582 2008/11/14 22:59:09 cheshire
+When on a network with more than one subnet overlayed on a single physical link, don't make local ARP
+entries for hosts that are on our physical link but not on our logical subnet -- it confuses the kernel
+
+Revision 1.581 2008/11/14 21:01:26 cheshire
+Log a warning if we fail to get a MAC address for an interface
+
+Revision 1.580 2008/11/14 02:16:15 cheshire
+Clean up NetworkChanged handling
+
+Revision 1.579 2008/11/12 23:15:37 cheshire
+Updated log messages
+
+Revision 1.578 2008/11/06 23:41:57 cheshire
+Refinement: Only need to create local ARP entry when sending ARP packet to broadcast address or to ourselves
+
+Revision 1.577 2008/11/06 01:15:47 mcguire
+Fix compile error that occurs when LogOperation is disabled
+
+Revision 1.576 2008/11/05 21:55:21 cheshire
+Fixed mistake in BPF filter generation
+
+Revision 1.575 2008/11/04 23:54:09 cheshire
+Added routine mDNSSetARP(), used to replace an SPS client's entry in our ARP cache with
+a dummy one, so that IP traffic to the SPS client initiated by the SPS machine can be
+captured by our BPF filters, and used as a trigger to wake the sleeping machine.
+
+Revision 1.574 2008/11/04 00:27:58 cheshire
+Corrected some timing anomalies in sleep/wake causing spurious name self-conflicts
+
+Revision 1.573 2008/11/03 01:12:42 mkrochma
+Fix compile error that occurs when LogOperation is disabled
+
+Revision 1.572 2008/10/31 23:36:13 cheshire
+One wakeup clear any previous power requests
+
+Revision 1.571 2008/10/31 23:05:30 cheshire
+Move logic to decide when to at as Sleep Proxy Server from daemon.c to mDNSMacOSX.c
+
+Revision 1.570 2008/10/30 01:08:19 cheshire
+After waking for network maintenance operations go back to sleep again
+
+Revision 1.569 2008/10/29 21:39:43 cheshire
+Updated syslog messages; close BPF socket on read error
+
+Revision 1.568 2008/10/28 20:37:28 cheshire
+Changed code to create its own CFSocketCreateWithNative directly, instead of
+relying on udsSupportAddFDToEventLoop/udsSupportRemoveFDFromEventLoop
+
+Revision 1.567 2008/10/27 22:31:37 cheshire
+Can't just close BPF_fd using "close(i->BPF_fd);" -- need to call
+"udsSupportRemoveFDFromEventLoop(i->BPF_fd);" to remove it from our event source list
+
+Revision 1.566 2008/10/23 22:33:23 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
+Revision 1.565 2008/10/22 23:23:55 cheshire
+Moved definition of OSXVers from daemon.c into mDNSMacOSX.c
+
+Revision 1.564 2008/10/22 22:08:46 cheshire
+Take IP header length into account when determining how many bytes to return from BPF filter
+
+Revision 1.563 2008/10/22 20:59:28 cheshire
+BPF filter needs to capture a few more bytes so that we can examine TCP header fields
+
+Revision 1.562 2008/10/22 19:48:29 cheshire
+Improved syslog messages
+
+Revision 1.561 2008/10/22 17:18:57 cheshire
+Need to open and close BPF fds when turning Sleep Proxy Server on and off
+
+Revision 1.560 2008/10/22 01:09:36 cheshire
+Fixed build warning when not using LogClientOperations
+
+Revision 1.559 2008/10/21 01:05:30 cheshire
+Added code to receive raw packets using Berkeley Packet Filter (BPF)
+
+Revision 1.558 2008/10/16 22:42:06 cheshire
+Removed debugging messages
+
+Revision 1.557 2008/10/09 22:33:14 cheshire
+Fill in ifinfo.MAC field when fetching interface list
+
+Revision 1.556 2008/10/09 21:15:23 cheshire
+In mDNSPlatformUDPSocket(), need to create an IPv6 socket as well as IPv4
+
+Revision 1.555 2008/10/09 19:05:57 cheshire
+No longer want to inhibit all networking when going to sleep
+
+Revision 1.554 2008/10/08 18:36:51 mkrochma
+<rdar://problem/4371323> Supress Couldn't read user-specified Computer Name logs
+
+Revision 1.553 2008/10/04 00:47:12 cheshire
+If NetWake setting changes for an interface, treat it as a whole new interface (like BSSID changing)
+
+Revision 1.552 2008/10/03 23:32:15 cheshire
+Added definition of mDNSPlatformSendRawPacket
+
+Revision 1.551 2008/10/03 18:25:16 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
+Revision 1.550 2008/10/03 00:51:58 cheshire
+Removed spurious "else" case that got left in by mistake
+
+Revision 1.549 2008/10/03 00:50:13 cheshire
+Minor code rearrangement; don't set up interface list until *after* we've started watching for network changes
+
+Revision 1.548 2008/10/03 00:26:25 cheshire
+Export DictionaryIsEnabled() so it's callable from other files
+
+Revision 1.547 2008/10/02 23:50:07 mcguire
+<rdar://problem/6136442> shutdown time issues
+improve log messages when SCDynamicStoreCreate() fails
+
+Revision 1.546 2008/10/02 22:26:21 cheshire
+Moved declaration of BPF_fd from uds_daemon.c to mDNSMacOSX.c, where it really belongs
+
+Revision 1.545 2008/10/01 22:01:40 cheshire
+On Allan Nathanson's advice, add "State:/IOKit/PowerManagement/CurrentSettings"
+to keys array instead of patterns array, for efficiency
+
+Revision 1.544 2008/10/01 21:35:35 cheshire
+Monitor "State:/IOKit/PowerManagement/CurrentSettings" to track state of "Wake for network access" setting
+
+Revision 1.543 2008/09/26 23:05:56 mkrochma
+Improve log messages by using good old UTF-8
+
+Revision 1.542 2008/09/26 19:49:51 cheshire
+Improved "failed to send packet" debugging message
+
+Revision 1.541 2008/09/25 21:02:05 cheshire
+<rdar://problem/6245044> Stop using separate m->ServiceRegistrations list
+In TunnelServers(), need to check main m->ResourceRecords list to see
+if we have a non-zero number of advertised AutoTunnel services
+
+Revision 1.540 2008/07/30 00:55:56 mcguire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+Additional fixes so that we know when a socket has been closed while in a loop reading from it
+
+Revision 1.539 2008/07/24 20:23:04 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+
+Revision 1.538 2008/06/02 05:39:39 mkrochma
+<rdar://problem/5932760> Don't set TOS bits anymore
+
+Revision 1.537 2008/05/01 18:30:54 mkrochma
+<rdar://problem/5895642> Make mDNSResponder and mDNSResponderHelper shutdown at regular time
Revision 1.536 2008/03/25 01:27:30 mcguire
<rdar://problem/5810718> Status sometimes wrong when link goes down
#define USE_V6_ONLY_WHEN_NO_ROUTABLE_V4 0
-#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
+#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
#include "DNSCommon.h"
#include "uDNS.h"
-#include "mDNSMacOSX.h" // Defines the specific types needed to run mDNS on this platform
-#include "../mDNSShared/uds_daemon.h" // Defines communication interface from platform layer up to UDS daemon
+#include "mDNSMacOSX.h" // Defines the specific types needed to run mDNS on this platform
+#include "dns_sd.h" // For mDNSInterface_LocalOnly etc.
#include "PlatformCommon.h"
#include <stdio.h>
#include <stdarg.h> // For va_list support
+#include <stdlib.h> // For arc4random
#include <net/if.h>
#include <net/if_types.h> // For IFT_ETHER
#include <net/if_dl.h>
+#include <net/bpf.h> // For BIOCSETIF etc.
#include <sys/uio.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>
+
+#if USE_IOPMCOPYACTIVEPMPREFERENCES
+#include <IOKit/ps/IOPowerSources.h>
+#include <IOKit/ps/IOPowerSourcesPrivate.h>
+#endif
+
#include <mach/mach_error.h>
#include <mach/mach_port.h>
#include <mach/mach_time.h>
#include "helper.h"
+#include <asl.h>
+
#define kInterfaceSpecificOption "interface="
// ***************************************************************************
#pragma mark - Globals
#endif
+// By default we don't offer sleep proxy service
+// If OfferSleepProxyService is set non-zero (typically via command-line switch),
+// then we'll offer sleep proxy service on desktop Macs that are set to never sleep.
+// We currently do not offer sleep proxy service on laptops, or on machines that are set to go to sleep.
+mDNSexport int OfferSleepProxyService = 0;
+
+mDNSexport int OSXVers;
mDNSexport int KQueueFD;
#ifndef NO_SECURITYFRAMEWORK
static CFArrayRef ServerCerts;
#endif /* NO_SECURITYFRAMEWORK */
-#define DYNDNS_KEYCHAIN_SERVICE "DynDNS Shared Secret"
+static CFStringRef NetworkChangedKey_IPv4;
+static CFStringRef NetworkChangedKey_IPv6;
+static CFStringRef NetworkChangedKey_Hostnames;
+static CFStringRef NetworkChangedKey_Computername;
+static CFStringRef NetworkChangedKey_DNS;
+static CFStringRef NetworkChangedKey_DynamicDNS = CFSTR("Setup:/Network/DynamicDNS");
+static CFStringRef NetworkChangedKey_BackToMyMac = CFSTR("Setup:/Network/BackToMyMac");
+
+static char HINFO_HWstring_buffer[32];
+static char *HINFO_HWstring = "Device";
+static int HINFO_HWstring_prefixlen = 6;
+
+mDNSexport int WatchDogReportingThreshold = 250;
-CFStringRef NetworkChangedKey_IPv4;
-CFStringRef NetworkChangedKey_IPv6;
-CFStringRef NetworkChangedKey_Hostnames;
-CFStringRef NetworkChangedKey_Computername;
-CFStringRef NetworkChangedKey_DNS;
-CFStringRef NetworkChangedKey_DynamicDNS = CFSTR("Setup:/Network/DynamicDNS");
-CFStringRef NetworkChangedKey_BackToMyMac = CFSTR("Setup:/Network/BackToMyMac");
+#if APPLE_OSX_mDNSResponder
+static mDNSu8 SPMetricPortability = 99;
+static mDNSu8 SPMetricMarginalPower = 99;
+static mDNSu8 SPMetricTotalPower = 99;
+mDNSexport domainname ActiveDirectoryPrimaryDomain;
+mDNSexport int ActiveDirectoryPrimaryDomainLabelCount;
+mDNSexport mDNSAddr ActiveDirectoryPrimaryDomainServer;
+#endif // APPLE_OSX_mDNSResponder
// ***************************************************************************
// Functions
// Typically point-to-point interfaces are modems (including mobile-phone pseudo-modems), and we don't want
// to run up the user's bill sending multicast traffic over a link where there's only a single device at the
// other end, and that device (e.g. a modem bank) is probably not answering Multicast DNS queries anyway.
-#define MulticastInterface(i) ((i->ifa_flags & IFF_MULTICAST) && !(i->ifa_flags & IFF_POINTOPOINT))
+#define MulticastInterface(i) (((i)->ifa_flags & IFF_MULTICAST) && !((i)->ifa_flags & IFF_POINTOPOINT))
mDNSexport void NotifyOfElusiveBug(const char *title, const char *msg) // Both strings are UTF-8 text
{
notifyCount++;
#ifndef NO_CFUSERNOTIFICATION
- static const char footer[] = "(Note: This message only appears on machines with 17.x.x.x IP addresses — i.e. at Apple — not on customer machines.)";
- CFStringRef alertHeader = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
- CFStringRef alertBody = CFStringCreateWithCString(NULL, msg, kCFStringEncodingUTF8);
- CFStringRef alertFooter = CFStringCreateWithCString(NULL, footer, kCFStringEncodingUTF8);
- CFStringRef alertMessage = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\r\r%@"), alertBody, alertFooter);
- CFUserNotificationDisplayNotice(0.0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, alertHeader, alertMessage, NULL);
+ mDNSNotify(title, msg);
#endif /* NO_CFUSERNOTIFICATION */
}
{
NetworkInterfaceInfoOSX *i;
for (i = m->p->InterfaceList; i; i = i->next)
- if (i->Exists && !strcmp(i->ifa_name, ifname) &&
+ if (i->Exists && !strcmp(i->ifinfo.ifname, ifname) &&
((type == AF_UNSPEC ) ||
(type == AF_INET && i->ifinfo.ip.type == mDNSAddrType_IPv4) ||
(type == AF_INET6 && i->ifinfo.ip.type == mDNSAddrType_IPv6))) return(i);
if (i->ifinfo.InterfaceID && i->scope_id == ifindex) return(i->ifinfo.InterfaceID);
// Not found. Make sure our interface list is up to date, then try again.
- LogOperation("InterfaceID for interface index %d not found; Updating interface list", ifindex);
+ LogInfo("InterfaceID for interface index %d not found; Updating interface list", ifindex);
mDNSMacOSXNetworkChanged(m);
for (i = m->p->InterfaceList; i; i = i->next)
if (i->ifinfo.InterfaceID && i->scope_id == ifindex) return(i->ifinfo.InterfaceID);
if ((mDNSInterfaceID)i == id) return(i->scope_id);
// Not found. Make sure our interface list is up to date, then try again.
- LogOperation("Interface index for InterfaceID %p not found; Updating interface list", id);
+ LogInfo("Interface index for InterfaceID %p not found; Updating interface list", id);
mDNSMacOSXNetworkChanged(m);
for (i = m->p->InterfaceList; i; i = i->next)
if ((mDNSInterfaceID)i == id) return(i->scope_id);
return(0);
}
+#if APPLE_OSX_mDNSResponder
+mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *result, const char *signature, const char *fmt, ...)
+ {
+ if (OSXVers < OSXVers_10_6_SnowLeopard) return;
+
+ static char buffer[512];
+ aslmsg asl_msg = asl_new(ASL_TYPE_MSG);
+
+ if (!asl_msg) { LogMsg("mDNSASLLog: asl_new failed"); return; }
+ if (uuid)
+ {
+ char uuidStr[36];
+ uuid_unparse(*uuid, uuidStr);
+ asl_set (asl_msg, "com.apple.message.uuid", uuidStr);
+ }
+
+ static char domainBase[] = "com.apple.mDNSResponder.%s";
+ mDNS_snprintf (buffer, sizeof(buffer), domainBase, subdomain);
+ asl_set (asl_msg, "com.apple.message.domain", buffer);
+
+ if (result) asl_set(asl_msg, "com.apple.message.result", result);
+ if (signature) asl_set(asl_msg, "com.apple.message.signature", signature);
+
+ va_list ptr;
+ va_start(ptr,fmt);
+ mDNS_vsnprintf(buffer, sizeof(buffer), fmt, ptr);
+ va_end(ptr);
+
+ int old_filter = asl_set_filter(NULL,ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
+ asl_log(NULL, asl_msg, ASL_LEVEL_DEBUG, "%s", buffer);
+ asl_set_filter(NULL, old_filter);
+ asl_free(asl_msg);
+ }
+#endif
+
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - UDP & TCP send & receive
return result;
}
-// NOTE: If InterfaceID is NULL, it means, "send this packet through our anonymous unicast socket"
-// NOTE: If InterfaceID is non-NULL it means, "send this packet through our port 5353 socket on the specified interface"
+// Note: If InterfaceID is NULL, it means, "send this packet through our anonymous unicast socket"
+// Note: If InterfaceID is non-NULL it means, "send this packet through our port 5353 socket on the specified interface"
// OR send via our primary v4 unicast socket
// UPDATE: The UDPSocket *src parameter now allows the caller to specify the source socket
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
// to the NetworkInterfaceInfoOSX structure that holds the active sockets. The mDNSCore code
// doesn't know that and doesn't need to know that -- it just treats InterfaceIDs as opaque identifiers.
NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
- char *ifa_name = info ? info->ifa_name : "unicast";
+ char *ifa_name = info ? info->ifinfo.ifname : "unicast";
struct sockaddr_storage to;
int s = -1, err;
mStatus result = mStatus_NoError;
sin_to->sin_family = AF_INET;
sin_to->sin_port = dstPort.NotAnInteger;
sin_to->sin_addr.s_addr = dst->ip.v4.NotAnInteger;
- s = m->p->permanentsockets.sktv4;
-
- if (src) { s = src->ss.sktv4; debugf("mDNSPlatformSendUDP using port %d %d %d", mDNSVal16(src->ss.port), m->p->permanentsockets.sktv4, s); }
+ s = (src ? src->ss : m->p->permanentsockets).sktv4;
if (info) // Specify outgoing interface
{
if (!mDNSAddrIsDNSMulticast(dst))
{
- #ifdef IP_FORCE_OUT_IFP
- setsockopt(s, IPPROTO_IP, IP_FORCE_OUT_IFP, ifa_name, strlen(ifa_name) + 1);
+ #ifdef IP_BOUND_IF
+ if (info->scope_id == 0)
+ LogInfo("IP_BOUND_IF socket option not set -- info %p (%s) scope_id is zero", info, ifa_name);
+ else
+ setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &info->scope_id, sizeof(info->scope_id));
#else
{
static int displayed = 0;
if (displayed < 1000)
{
displayed++;
- LogOperation("IP_FORCE_OUT_IFP Socket option not defined -- cannot specify interface for unicast packets");
+ LogInfo("IP_BOUND_IF socket option not defined -- cannot specify interface for unicast packets");
}
}
#endif
else
{
err = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &info->ifa_v4addr, sizeof(info->ifa_v4addr));
- if (err < 0) LogMsg("setsockopt - IP_MULTICAST_IF error %.4a %ld errno %d (%s)", &info->ifa_v4addr, err, errno, strerror(errno));
+ if (err < 0 && !m->p->NetworkChanged)
+ LogMsg("setsockopt - IP_MULTICAST_IF error %.4a %d errno %d (%s)", &info->ifa_v4addr, err, errno, strerror(errno));
}
}
}
sin6_to->sin6_flowinfo = 0;
sin6_to->sin6_addr = *(struct in6_addr*)&dst->ip.v6;
sin6_to->sin6_scope_id = info ? info->scope_id : 0;
- s = m->p->permanentsockets.sktv6;
+ s = (src ? src->ss : m->p->permanentsockets).sktv6;
if (info && mDNSAddrIsDNSMulticast(dst)) // Specify outgoing interface
{
err = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &info->scope_id, sizeof(info->scope_id));
- if (err < 0) LogMsg("setsockopt - IPV6_MULTICAST_IF error %ld errno %d (%s)", err, errno, strerror(errno));
+ if (err < 0) LogMsg("setsockopt - IPV6_MULTICAST_IF error %d errno %d (%s)", err, errno, strerror(errno));
}
}
else
return mStatus_BadParamErr;
}
- // Don't send if it would cause dial-on-demand connection initiation.
- // As an optimization, don't bother consulting reachability API / routing
- // table when sending Multicast DNS since we ignore PPP interfaces for mDNS traffic.
- if (!info && !mDNSAddrIsDNSMulticast(dst) && AddrRequiresPPPConnection((struct sockaddr *)&to))
- {
- debugf("mDNSPlatformSendUDP: Surpressing sending to avoid dial-on-demand connection");
- return mStatus_NoError;
- }
-
if (s >= 0)
verbosedebugf("mDNSPlatformSendUDP: sending on InterfaceID %p %5s/%ld to %#a:%d skt %d",
InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s);
if (MessageCount < 1000)
{
MessageCount++;
- LogMsg("mDNSPlatformSendUDP sendto failed to send packet on InterfaceID %p %5s/%ld to %#a:%d skt %d error %d errno %d (%s) %lu",
- InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow));
+ if (errno == EHOSTUNREACH || errno == EADDRNOTAVAIL || errno == ENETDOWN)
+ LogInfo("mDNSPlatformSendUDP sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu",
+ s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow));
+ else
+ LogMsg("mDNSPlatformSendUDP sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu",
+ s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow));
}
result = mStatus_UnknownErr;
}
-#ifdef IP_FORCE_OUT_IFP
+#ifdef IP_BOUND_IF
if (dst->type == mDNSAddrType_IPv4 && info && !mDNSAddrIsDNSMulticast(dst))
- setsockopt(s, IPPROTO_IP, IP_FORCE_OUT_IFP, "", 1);
+ {
+ static const mDNSu32 ifindex = 0;
+ setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
+ }
#endif
return(result);
senderAddr.type = mDNSAddrType_IPv4;
senderAddr.ip.v4.NotAnInteger = s->sin_addr.s_addr;
senderPort.NotAnInteger = s->sin_port;
- //LogOperation("myKQSocketCallBack received IPv4 packet from %#-15a to %#-15a on skt %d %s", &senderAddr, &destAddr, s1, packetifname);
+ //LogInfo("myKQSocketCallBack received IPv4 packet from %#-15a to %#-15a on skt %d %s", &senderAddr, &destAddr, s1, packetifname);
}
else if (from.ss_family == AF_INET6)
{
senderAddr.type = mDNSAddrType_IPv6;
senderAddr.ip.v6 = *(mDNSv6Addr*)&sin6->sin6_addr;
senderPort.NotAnInteger = sin6->sin6_port;
- //LogOperation("myKQSocketCallBack received IPv6 packet from %#-15a to %#-15a on skt %d %s", &senderAddr, &destAddr, s1, packetifname);
+ //LogInfo("myKQSocketCallBack received IPv6 packet from %#-15a to %#-15a on skt %d %s", &senderAddr, &destAddr, s1, packetifname);
}
else
{
return;
}
- // NOTE: When handling multiple packets in a batch, MUST reset InterfaceID before handling each packet
+ // Note: When handling multiple packets in a batch, MUST reset InterfaceID before handling each packet
mDNSInterfaceID InterfaceID = mDNSNULL;
NetworkInterfaceInfo *intf = m->HostInterfaces;
while (intf && strcmp(intf->ifname, packetifname)) intf = intf->next;
else if (mDNSAddrIsDNSMulticast(&destAddr)) continue;
// LogMsg("myKQSocketCallBack got packet from %#a to %#a on interface %#a/%s",
-// &senderAddr, &destAddr, &ss->info->ifinfo.ip, ss->info->ifa_name);
+// &senderAddr, &destAddr, &ss->info->ifinfo.ip, ss->info->ifinfo.ifname);
// mDNSCoreReceive may close the socket we're reading from. We must break out of our
// loop when that happens, or we may try to read from an invalid FD. We do this by
// TCP socket support
+typedef enum
+ {
+ handshake_required,
+ handshake_in_progress,
+ handshake_completed,
+ handshake_to_be_closed
+ } handshakeStatus;
+
struct TCPSocket_struct
{
TCPSocketFlags flags; // MUST BE FIRST FIELD -- mDNSCore expects every TCPSocket_struct to begin with TCPSocketFlags flags
KQueueEntry kqEntry;
#ifndef NO_SECURITYFRAMEWORK
SSLContextRef tlsContext;
+ pthread_t handshake_thread;
#endif /* NO_SECURITYFRAMEWORK */
void *context;
mDNSBool setup;
- mDNSBool handshakecomplete;
mDNSBool connected;
+ handshakeStatus handshake;
+ mDNS *m; // So we can call KQueueLock from the SSLHandshake thread
+ mStatus err;
};
+mDNSlocal void doTcpSocketCallback(TCPSocket *sock)
+ {
+ mDNSBool c = !sock->connected;
+ sock->connected = mDNStrue;
+ sock->callback(sock, sock->context, c, sock->err);
+ // Note: the callback may call CloseConnection here, which frees the context structure!
+ }
+
#ifndef NO_SECURITYFRAMEWORK
mDNSlocal OSStatus tlsWriteSock(SSLConnectionRef connection, const void *data, size_t *dataLength)
if (errno == EAGAIN ) return(errSSLWouldBlock);
if (errno == ENOENT ) return(errSSLClosedGraceful);
if (errno == EPIPE || errno == ECONNRESET) return(errSSLClosedAbort);
- LogMsg("ERROR: tlsWriteSock: error %d %s\n", errno, strerror(errno));
+ LogMsg("ERROR: tlsWriteSock: %d error %d (%s)\n", ((TCPSocket *)connection)->fd, errno, strerror(errno));
return(errSSLClosedAbort);
}
if (ret == 0 || errno == ENOENT ) return(errSSLClosedGraceful);
if ( errno == EAGAIN ) return(errSSLWouldBlock);
if ( errno == ECONNRESET) return(errSSLClosedAbort);
- LogMsg("ERROR: tlsSockRead: error %d %s\n", errno, strerror(errno));
+ LogMsg("ERROR: tlsSockRead: error %d (%s)\n", errno, strerror(errno));
return(errSSLClosedAbort);
}
return(err);
}
+mDNSlocal void *doSSLHandshake(void *ctx)
+ {
+ // Warning: Touching sock without the kqueue lock!
+ // We're protected because sock->handshake == handshake_in_progress
+ TCPSocket *sock = (TCPSocket*)ctx;
+ mDNS * const m = sock->m; // Get m now, as we may free sock if marked to be closed while we're waiting on SSLHandshake
+ mStatus err = SSLHandshake(sock->tlsContext);
+
+ KQueueLock(m);
+ LogInfo("doSSLHandshake %p: got lock", sock); // Log *after* we get the lock
+
+ if (sock->handshake == handshake_to_be_closed)
+ {
+ LogInfo("SSLHandshake completed after close");
+ mDNSPlatformTCPCloseConnection(sock);
+ }
+ else
+ {
+ if (sock->fd != -1) KQueueSet(sock->fd, EV_ADD, EVFILT_READ, &sock->kqEntry);
+ else LogMsg("doSSLHandshake: sock->fd is -1");
+
+ if (err == errSSLWouldBlock)
+ sock->handshake = handshake_required;
+ else
+ {
+ if (err)
+ {
+ LogMsg("SSLHandshake failed: %d", err);
+ SSLDisposeContext(sock->tlsContext);
+ sock->tlsContext = NULL;
+ }
+
+ sock->err = err;
+ sock->handshake = handshake_completed;
+
+ LogInfo("doSSLHandshake: %p calling doTcpSocketCallback", sock);
+ doTcpSocketCallback(sock);
+ }
+ }
+
+ LogInfo("SSLHandshake %p: dropping lock", sock);
+ KQueueUnlock(m, "doSSLHandshake");
+ return NULL;
+ }
+
+mDNSlocal mStatus spawnSSLHandshake(TCPSocket* sock)
+ {
+ LogInfo("spawnSSLHandshake %p: entry", sock);
+ if (sock->handshake != handshake_required) LogMsg("spawnSSLHandshake: handshake status not required: %d", sock->handshake);
+ sock->handshake = handshake_in_progress;
+ KQueueSet(sock->fd, EV_DELETE, EVFILT_READ, &sock->kqEntry);
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ mStatus err = pthread_create(&sock->handshake_thread, &attr, doSSLHandshake, sock);
+ pthread_attr_destroy(&attr);
+ if (err)
+ {
+ LogMsg("Could not start SSLHandshake thread: (%d) %s", err, strerror(err));
+ sock->handshake = handshake_completed;
+ sock->err = err;
+ KQueueSet(sock->fd, EV_ADD, EVFILT_READ, &sock->kqEntry);
+ }
+ LogInfo("spawnSSLHandshake %p: done", sock);
+ return err;
+ }
+
mDNSlocal mDNSBool IsTunnelModeDomain(const domainname *d)
{
static const domainname *mmc = (const domainname*) "\x7" "members" "\x3" "mac" "\x3" "com";
mDNSlocal void tcpKQSocketCallback(__unused int fd, short filter, void *context)
{
TCPSocket *sock = context;
- mStatus err = mStatus_NoError;
+ sock->err = mStatus_NoError;
//if (filter == EVFILT_READ ) LogMsg("myKQSocketCallBack: tcpKQSocketCallback %d is EVFILT_READ", filter);
//if (filter == EVFILT_WRITE) LogMsg("myKQSocketCallBack: tcpKQSocketCallback %d is EVFILT_WRITE", filter);
{
#ifndef NO_SECURITYFRAMEWORK
if (!sock->setup) { sock->setup = mDNStrue; tlsSetupSock(sock, mDNSfalse); }
- if (!sock->handshakecomplete)
+
+ if (sock->handshake == handshake_required) { if (spawnSSLHandshake(sock) == 0) return; }
+ else if (sock->handshake == handshake_in_progress || sock->handshake == handshake_to_be_closed) return;
+ else if (sock->handshake != handshake_completed)
{
- //LogMsg("tcpKQSocketCallback Starting SSLHandshake");
- err = SSLHandshake(sock->tlsContext);
- //if (!err) LogMsg("tcpKQSocketCallback SSLHandshake complete");
- if (!err) sock->handshakecomplete = mDNStrue;
- else if (err == errSSLWouldBlock) return;
- else { LogMsg("KQ SSLHandshake failed: %d", err); SSLDisposeContext(sock->tlsContext); sock->tlsContext = NULL; }
+ if (!sock->err) sock->err = mStatus_UnknownErr;
+ LogMsg("tcpKQSocketCallback called with unexpected SSLHandshake status: %d", sock->handshake);
}
#else
- err = mStatus_UnsupportedErr;
+ sock->err = mStatus_UnsupportedErr;
#endif /* NO_SECURITYFRAMEWORK */
}
-
- mDNSBool c = !sock->connected;
- sock->connected = mDNStrue;
- sock->callback(sock, sock->context, c, err);
- // NOTE: the callback may call CloseConnection here, which frees the context structure!
+
+ doTcpSocketCallback(sock);
}
mDNSexport int KQueueSet(int fd, u_short flags, short filter, const KQueueEntry *const entryRef)
mDNSs32 end = mDNSPlatformRawTime();
(void)task;
if (end - m->p->BigMutexStartTime >= WatchDogReportingThreshold)
- LogOperation("WARNING: %s took %dms to complete", task, end - m->p->BigMutexStartTime);
+ LogInfo("WARNING: %s took %dms to complete", task, end - m->p->BigMutexStartTime);
pthread_mutex_unlock(&m->p->BigMutex);
char wake = 1;
if (send(m->p->WakeKQueueLoopFD, &wake, sizeof(wake), 0) == -1)
- LogMsg("ERROR: KQueueWake: send failed with error code: %d - %s", errno, strerror(errno));
+ LogMsg("ERROR: KQueueWake: send failed with error code: %d (%s)", errno, strerror(errno));
}
mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS *const m, TCPSocketFlags flags, mDNSIPPort *port)
sock->flags = flags;
sock->context = mDNSNULL;
sock->setup = mDNSfalse;
- sock->handshakecomplete = mDNSfalse;
sock->connected = mDNSfalse;
+ sock->handshake = handshake_required;
+ sock->m = m;
+ sock->err = mStatus_NoError;
if (sock->fd == -1)
{
// Bind it
struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
+ mDNSPlatformMemZero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = port->NotAnInteger;
if (setsockopt(sock->fd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)
{ LogMsg("setsockopt IP_RECVIF - %s", strerror(errno)); goto error; }
- memset(&addr, 0, sizeof(addr));
+ mDNSPlatformMemZero(&addr, sizeof(addr));
socklen_t len = sizeof(addr);
if (getsockname(sock->fd, (struct sockaddr*) &addr, &len) < 0)
{ LogMsg("getsockname - %s", strerror(errno)); goto error; }
sock->callback = callback;
sock->context = context;
sock->setup = mDNSfalse;
- sock->handshakecomplete = mDNSfalse;
sock->connected = mDNSfalse;
+ sock->handshake = handshake_required;
+ sock->err = mStatus_NoError;
(void) InterfaceID; //!!!KRS use this if non-zero!!!
saddr.sin_len = sizeof(saddr);
saddr.sin_addr.s_addr = dst->ip.v4.NotAnInteger;
- // Don't send if it would cause dial-on-demand connection initiation.
- if (AddrRequiresPPPConnection((struct sockaddr *)&saddr))
- {
- debugf("mDNSPlatformTCPConnect: Surpressing sending to avoid dial-on-demand connection");
- return mStatus_UnknownErr;
- }
-
sock->kqEntry.KQcallback = tcpKQSocketCallback;
sock->kqEntry.KQcontext = sock;
sock->kqEntry.KQtask = "Outgoing TCP";
if (connect(sock->fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
if (errno == EINPROGRESS) return mStatus_ConnPending;
- LogMsg("ERROR: mDNSPlatformTCPConnect - connect failed: socket %d: Error %d %s", sock->fd, errno, strerror(errno));
+ if (errno == EHOSTUNREACH || errno == EADDRNOTAVAIL || errno == ENETDOWN)
+ LogInfo("ERROR: mDNSPlatformTCPConnect - connect failed: socket %d: Error %d (%s)", sock->fd, errno, strerror(errno));
+ else
+ LogMsg("ERROR: mDNSPlatformTCPConnect - connect failed: socket %d: Error %d (%s)", sock->fd, errno, strerror(errno));
close(sock->fd);
return mStatus_ConnFailed;
}
TCPSocket *sock = mallocL("TCPSocket/mDNSPlatformTCPAccept", sizeof(TCPSocket));
if (!sock) return(mDNSNULL);
- memset(sock, 0, sizeof(*sock));
+ mDNSPlatformMemZero(sock, sizeof(*sock));
sock->fd = fd;
sock->flags = flags;
mDNSexport void mDNSPlatformTCPCloseConnection(TCPSocket *sock)
{
if (sock)
- {
+ {
#ifndef NO_SECURITYFRAMEWORK
if (sock->tlsContext)
{
+ if (sock->handshake == handshake_in_progress) // SSLHandshake thread using this sock (esp. tlsContext)
+ {
+ LogInfo("mDNSPlatformTCPCloseConnection: called while handshake in progress");
+ sock->handshake = handshake_to_be_closed;
+ }
+ if (sock->handshake == handshake_to_be_closed)
+ return;
+
SSLClose(sock->tlsContext);
SSLDisposeContext(sock->tlsContext);
sock->tlsContext = NULL;
if (sock->flags & kTCPSocketFlags_UseTLS)
{
#ifndef NO_SECURITYFRAMEWORK
- if (!sock->handshakecomplete)
- {
- //LogMsg("mDNSPlatformReadTCP Starting SSLHandshake");
- mStatus err = SSLHandshake(sock->tlsContext);
- //if (!err) LogMsg("mDNSPlatformReadTCP SSLHandshake complete");
- if (!err) sock->handshakecomplete = mDNStrue;
- else if (err == errSSLWouldBlock) return(0);
- else { LogMsg("Read SSLHandshake failed: %d", err); SSLDisposeContext(sock->tlsContext); sock->tlsContext = NULL; }
- }
+ if (sock->handshake == handshake_required) { LogMsg("mDNSPlatformReadTCP called while handshake required"); return 0; }
+ else if (sock->handshake == handshake_in_progress) return 0;
+ else if (sock->handshake != handshake_completed) LogMsg("mDNSPlatformReadTCP called with unexpected SSLHandshake status: %d", sock->handshake);
//LogMsg("Starting SSLRead %d %X", sock->fd, fcntl(sock->fd, F_GETFL, 0));
mStatus err = SSLRead(sock->tlsContext, buf, buflen, (size_t*)&nread);
}
// else nread is negative -- see what kind of error we got
else if (errno == ECONNRESET) { nread = 0; *closed = mDNStrue; }
- else if (errno != EAGAIN) { LogMsg("ERROR: mDNSPlatformReadTCP - recv: %d %s", errno, strerror(errno)); nread = -1; }
+ else if (errno != EAGAIN) { LogMsg("ERROR: mDNSPlatformReadTCP - recv: %d (%s)", errno, strerror(errno)); nread = -1; }
else // errno is EAGAIN (EWOULDBLOCK) -- no data available
{
nread = 0;
{
#ifndef NO_SECURITYFRAMEWORK
size_t processed;
+ if (sock->handshake == handshake_required) { LogMsg("mDNSPlatformWriteTCP called while handshake required"); return 0; }
+ if (sock->handshake == handshake_in_progress) return 0;
+ else if (sock->handshake != handshake_completed) LogMsg("mDNSPlatformWriteTCP called with unexpected SSLHandshake status: %d", sock->handshake);
+
mStatus err = SSLWrite(sock->tlsContext, msg, len, &processed);
if (!err) nsent = (int) processed;
// If mDNSIPPort port is zero, then it's a randomly assigned port number, used for sending unicast queries
mDNSlocal mStatus SetupSocket(KQSocketSet *cp, const mDNSIPPort port, u_short sa_family, mDNSIPPort *const outport)
{
- const int ip_tosbits = IPTOS_LOWDELAY | IPTOS_THROUGHPUT;
int *s = (sa_family == AF_INET) ? &cp->sktv4 : &cp->sktv6;
KQueueEntry *k = (sa_family == AF_INET) ? &cp->kqsv4 : &cp->kqsv6;
const int on = 1;
if (skt < 3) { if (errno != EAFNOSUPPORT) LogMsg("SetupSocket: socket error %d errno %d (%s)", skt, errno, strerror(errno)); return(skt); }
// ... with a shared UDP port, if it's for multicast receiving
- if (mDNSSameIPPort(port, MulticastDNSPort)) err = setsockopt(skt, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
+ if (mDNSSameIPPort(port, MulticastDNSPort) || mDNSSameIPPort(port, NATPMPAnnouncementPort)) err = setsockopt(skt, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
if (err < 0) { errstr = "setsockopt - SO_REUSEPORT"; goto fail; }
if (sa_family == AF_INET)
err = setsockopt(skt, IPPROTO_IP, IP_MULTICAST_TTL, &twofivefive, sizeof(twofivefive));
if (err < 0) { errstr = "setsockopt - IP_MULTICAST_TTL"; goto fail; }
- // Mark packets as high-throughput/low-delay (i.e. lowest reliability) to get maximum 802.11 multicast rate
- err = setsockopt(skt, IPPROTO_IP, IP_TOS, &ip_tosbits, sizeof(ip_tosbits));
- if (err < 0) { errstr = "setsockopt - IP_TOS"; goto fail; }
-
// And start listening for packets
struct sockaddr_in listening_sockaddr;
listening_sockaddr.sin_family = AF_INET;
listening_sockaddr.sin_port = port.NotAnInteger; // Pass in opaque ID without any byte swapping
- listening_sockaddr.sin_addr.s_addr = 0; // Want to receive multicasts AND unicasts on this socket
+ listening_sockaddr.sin_addr.s_addr = mDNSSameIPPort(port, NATPMPAnnouncementPort) ? AllSystemsMcast.NotAnInteger : 0;
err = bind(skt, (struct sockaddr *) &listening_sockaddr, sizeof(listening_sockaddr));
if (err) { errstr = "bind"; goto fail; }
if (outport) outport->NotAnInteger = listening_sockaddr.sin_port;
}
else if (sa_family == AF_INET6)
{
+ // NAT-PMP Announcements make no sense on IPv6, so bail early w/o error
+ if (mDNSSameIPPort(port, NATPMPAnnouncementPort)) { if (outport) *outport = zeroIPPort; return mStatus_NoError; }
+
// We want to receive destination addresses and receive interface identifiers
err = setsockopt(skt, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on));
if (err < 0) { errstr = "setsockopt - IPV6_PKTINFO"; goto fail; }
err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &twofivefive, sizeof(twofivefive));
if (err < 0) { errstr = "setsockopt - IPV6_MULTICAST_HOPS"; goto fail; }
- // Note: IPV6_TCLASS appears not to be implemented on OS X right now (or indeed on ANY version of Unix?)
- #ifdef IPV6_TCLASS
- // Mark packets as high-throughput/low-delay (i.e. lowest reliability) to get maximum 802.11 multicast rate
- int tclass = IPTOS_LOWDELAY | IPTOS_THROUGHPUT; // This may not be right (since tclass is not implemented on OS X, I can't test it)
- err = setsockopt(skt, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof(tclass));
- if (err < 0) { errstr = "setsockopt - IPV6_TCLASS"; goto fail; }
- #endif
-
// Want to receive our own packets
err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &on, sizeof(on));
if (err < 0) { errstr = "setsockopt - IPV6_MULTICAST_LOOP"; goto fail; }
fail:
// For "bind" failures, only write log messages for our shared mDNS port, or for binding to zero
if (strcmp(errstr, "bind") || mDNSSameIPPort(port, MulticastDNSPort) || mDNSIPPortIsZero(port))
- LogMsg("%s skt %d port %d error %ld errno %d (%s)", errstr, skt, mDNSVal16(port), err, errno, strerror(errno));
+ LogMsg("%s skt %d port %d error %d errno %d (%s)", errstr, skt, mDNSVal16(port), err, errno, strerror(errno));
- // If we got a "bind" failure with an EADDRINUSE error for our shared mDNS port, display error alert
- if (!strcmp(errstr, "bind") && mDNSSameIPPort(port, MulticastDNSPort) && errno == EADDRINUSE)
- NotifyOfElusiveBug("Setsockopt SO_REUSEPORT failed",
- "Congratulations, you've reproduced an elusive bug.\r"
- "Please contact the current assignee of <rdar://problem/3814904>.\r"
- "Alternatively, you can send email to radar-3387020@group.apple.com. (Note number is different.)\r"
- "If possible, please leave your machine undisturbed so that someone can come to investigate the problem.");
+ // If we got a "bind" failure of EADDRINUSE, inform the caller as it might need to try another random port
+ if (!strcmp(errstr, "bind") && errno == EADDRINUSE)
+ {
+ err = EADDRINUSE;
+ if (mDNSSameIPPort(port, MulticastDNSPort))
+ NotifyOfElusiveBug("Setsockopt SO_REUSEPORT failed",
+ "Congratulations, you've reproduced an elusive bug.\r"
+ "Please contact the current assignee of <rdar://problem/3814904>.\r"
+ "Alternatively, you can send email to radar-3387020@group.apple.com. (Note number is different.)\r"
+ "If possible, please leave your machine undisturbed so that someone can come to investigate the problem.");
+ }
close(skt);
return(err);
mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport)
{
- int i;
mStatus err;
mDNSIPPort port = requestedport;
+ mDNSBool randomizePort = mDNSIPPortIsZero(requestedport);
+ int i = 10000; // Try at most 10000 times to get a unique random port
UDPSocket *p = mallocL("UDPSocket", sizeof(UDPSocket));
if (!p) { LogMsg("mDNSPlatformUDPSocket: memory exhausted"); return(mDNSNULL); }
- memset(p, 0, sizeof(UDPSocket));
+ mDNSPlatformMemZero(p, sizeof(UDPSocket));
p->ss.port = zeroIPPort;
p->ss.m = m;
p->ss.sktv4 = -1;
p->ss.sktv6 = -1;
- for (i=0; i<10000; i++) // Try at most 10000 times to get a unique random port
+ do
{
// The kernel doesn't do cryptographically strong random port allocation, so we do it ourselves here
- if (mDNSIPPortIsZero(requestedport)) port = mDNSOpaque16fromIntVal(0xC000 + mDNSRandom(0x3FFF));
+ if (randomizePort) port = mDNSOpaque16fromIntVal(0xC000 + mDNSRandom(0x3FFF));
err = SetupSocket(&p->ss, port, AF_INET, &p->ss.port);
- if (!err) break;
- }
+ if (!err)
+ {
+ err = SetupSocket(&p->ss, port, AF_INET6, &p->ss.port);
+ if (err) { close(p->ss.sktv4); p->ss.sktv4 = -1; }
+ }
+ i--;
+ } while (err == EADDRINUSE && randomizePort && i);
+
if (err)
{
// In customer builds we don't want to log failures with port 5351, because this is a known issue
// of failing to bind to this port when Internet Sharing has already bound to it
- if (mDNSSameIPPort(requestedport, NATPMPPort))
- LogOperation("mDNSPlatformUDPSocket: SetupSocket %d failed error %ld errno %d (%s)", mDNSVal16(requestedport), err, errno, strerror(errno));
- else LogMsg ("mDNSPlatformUDPSocket: SetupSocket %d failed error %ld errno %d (%s)", mDNSVal16(requestedport), err, errno, strerror(errno));
+ // We also don't want to log about port 5350, due to a known bug when some other
+ // process is bound to it.
+ if (mDNSSameIPPort(requestedport, NATPMPPort) || mDNSSameIPPort(requestedport, NATPMPAnnouncementPort))
+ LogInfo("mDNSPlatformUDPSocket: SetupSocket %d failed error %d errno %d (%s)", mDNSVal16(requestedport), err, errno, strerror(errno));
+ else LogMsg("mDNSPlatformUDPSocket: SetupSocket %d failed error %d errno %d (%s)", mDNSVal16(requestedport), err, errno, strerror(errno));
freeL("UDPSocket", p);
return(mDNSNULL);
}
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
-#pragma mark - Key Management
+#pragma mark - BPF Raw packet sending/receiving
#endif
-#ifndef NO_SECURITYFRAMEWORK
-mDNSlocal CFArrayRef GetCertChain(SecIdentityRef identity)
+#if APPLE_OSX_mDNSResponder
+
+mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
{
- CFMutableArrayRef certChain = NULL;
- if (!identity) { LogMsg("getCertChain: identity is NULL"); return(NULL); }
- SecCertificateRef cert;
- OSStatus err = SecIdentityCopyCertificate(identity, &cert);
- if (err || !cert) LogMsg("getCertChain: SecIdentityCopyCertificate() returned %d", (int) err);
+ if (!InterfaceID) { LogMsg("mDNSPlatformSendRawPacket: No InterfaceID specified"); return; }
+ NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
+ if (info->BPF_fd < 0)
+ LogMsg("mDNSPlatformSendRawPacket: %s BPF_fd %d not ready", info->ifinfo.ifname, info->BPF_fd);
else
{
- SecPolicySearchRef searchRef;
+ //LogMsg("mDNSPlatformSendRawPacket %d bytes on %s", end - (mDNSu8 *)msg, info->ifinfo.ifname);
+ if (write(info->BPF_fd, msg, end - (mDNSu8 *)msg) < 0)
+ LogMsg("mDNSPlatformSendRawPacket: BPF write(%d) failed %d (%s)", info->BPF_fd, errno, strerror(errno));
+ }
+ }
+
+mDNSexport void mDNSPlatformSetLocalARP(const mDNSv4Addr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
+ {
+ if (!InterfaceID) { LogMsg("mDNSPlatformSetLocalARP: No InterfaceID specified"); return; }
+ NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
+ // Manually inject an entry into our local ARP cache.
+ // (We can't do this by sending an ARP broadcast, because the kernel only pays attention to incoming ARP packets, not outgoing.)
+ mDNSBool makearp = mDNSv4AddressIsLinkLocal(tpa);
+ if (!makearp)
+ {
+ NetworkInterfaceInfoOSX *i;
+ for (i = info->m->p->InterfaceList; i; i = i->next)
+ if (i->Exists && i->ifinfo.InterfaceID == InterfaceID && i->ifinfo.ip.type == mDNSAddrType_IPv4)
+ if (((i->ifinfo.ip.ip.v4.NotAnInteger ^ tpa->NotAnInteger) & i->ifinfo.mask.ip.v4.NotAnInteger) == 0)
+ makearp = mDNStrue;
+ }
+ if (!makearp)
+ LogInfo("Don't need ARP entry for %s %.4a %.6a", info->ifinfo.ifname, tpa, tha);
+ else
+ {
+ int result = mDNSSetARP(info->scope_id, tpa->b, tha->b);
+ if (result) LogMsg("Set local ARP entry for %s %.4a %.6a failed: %d", info->ifinfo.ifname, tpa, tha, result);
+ else debugf ("Set local ARP entry for %s %.4a %.6a", info->ifinfo.ifname, tpa, tha);
+ }
+ }
+
+mDNSlocal void CloseBPF(NetworkInterfaceInfoOSX *const i)
+ {
+ LogSPS("%s closing BPF fd %d", i->ifinfo.ifname, i->BPF_fd);
+
+ // Note: MUST NOT close() the underlying native BSD sockets.
+ // CFSocketInvalidate() will do that for us, in its own good time, which may not necessarily be immediately, because
+ // it first has to unhook the sockets from its select() call on its other thread, before it can safely close them.
+ CFRunLoopRemoveSource(i->m->p->CFRunLoop, i->BPF_rls, kCFRunLoopDefaultMode);
+ CFRelease(i->BPF_rls);
+ CFSocketInvalidate(i->BPF_cfs);
+ CFRelease(i->BPF_cfs);
+ i->BPF_fd = -1;
+ }
+
+mDNSlocal void bpf_callback(const CFSocketRef cfs, const CFSocketCallBackType CallBackType, const CFDataRef address, const void *const data, void *const context)
+ {
+ (void)cfs;
+ (void)CallBackType;
+ (void)address;
+ (void)data;
+
+ NetworkInterfaceInfoOSX *const info = (NetworkInterfaceInfoOSX *)context;
+ KQueueLock(info->m);
+
+ // Now we've got the lock, make sure the kqueue thread didn't close the fd out from under us (will not be a problem once the OS X
+ // kernel has a mechanism for dispatching all events to a single thread, but for now we have to guard against this race condition).
+ if (info->BPF_fd < 0) goto exit;
+
+ ssize_t n = read(info->BPF_fd, &info->m->imsg, info->BPF_len);
+ const mDNSu8 *ptr = (const mDNSu8 *)&info->m->imsg;
+ const mDNSu8 *end = (const mDNSu8 *)&info->m->imsg + n;
+ debugf("%3d: bpf_callback got %d bytes on %s", info->BPF_fd, n, info->ifinfo.ifname);
+
+ if (n<0)
+ {
+ LogMsg("Closing %s BPF fd %d due to error %d (%s)", info->ifinfo.ifname, info->BPF_fd, errno, strerror(errno));
+ CloseBPF(info);
+ goto exit;
+ }
+
+ while (ptr < end)
+ {
+ const struct bpf_hdr *bh = (const struct bpf_hdr *)ptr;
+ debugf("%3d: bpf_callback bh_caplen %4d bh_datalen %4d remaining %4d", info->BPF_fd, bh->bh_caplen, bh->bh_datalen, end - (ptr + BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen)));
+ mDNSCoreReceiveRawPacket(info->m, ptr + bh->bh_hdrlen, ptr + bh->bh_hdrlen + bh->bh_caplen, info->ifinfo.InterfaceID);
+ ptr += BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen);
+ }
+exit:
+ KQueueUnlock(info->m, "bpf_callback");
+ }
+
+#define BPF_SetOffset(from, cond, to) (from)->cond = (to) - 1 - (from)
+
+mDNSlocal int CountProxyTargets(mDNS *const m, NetworkInterfaceInfoOSX *x, int *p4, int *p6)
+ {
+ int numv4 = 0, numv6 = 0;
+ AuthRecord *rr;
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == (mDNSInterfaceID)x && rr->AddressProxy.type == mDNSAddrType_IPv4)
+ {
+ if (p4) LogSPS("mDNSPlatformUpdateProxyList: fd %d %-7s IP%2d %.4a", x->BPF_fd, x->ifinfo.ifname, numv4, &rr->AddressProxy.ip.v4);
+ numv4++;
+ }
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == (mDNSInterfaceID)x && rr->AddressProxy.type == mDNSAddrType_IPv6)
+ {
+ if (p6) LogSPS("mDNSPlatformUpdateProxyList: fd %d %-7s IP%2d %.16a", x->BPF_fd, x->ifinfo.ifname, numv6, &rr->AddressProxy.ip.v6);
+ numv6++;
+ }
+
+ if (p4) *p4 = numv4;
+ if (p6) *p6 = numv6;
+ return(numv4 + numv6);
+ }
+
+mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
+ {
+ NetworkInterfaceInfoOSX *x;
+ for (x = m->p->InterfaceList; x; x = x->next) if (x == (NetworkInterfaceInfoOSX *)InterfaceID) break;
+ if (!x) { LogMsg("mDNSPlatformUpdateProxyList: ERROR InterfaceID %p not found", InterfaceID); return; }
+
+ #define MAX_BPF_ADDRS 250
+ int numv4 = 0, numv6 = 0;
+
+ if (CountProxyTargets(m, x, &numv4, &numv6) > MAX_BPF_ADDRS)
+ {
+ LogMsg("mDNSPlatformUpdateProxyList: ERROR Too many address proxy records v4 %d v6 %d", numv4, numv6);
+ if (numv4 > MAX_BPF_ADDRS) numv4 = MAX_BPF_ADDRS;
+ numv6 = MAX_BPF_ADDRS - numv4;
+ }
+
+ LogSPS("mDNSPlatformUpdateProxyList: fd %d %-7s MAC %.6a %d v4 %d v6", x->BPF_fd, x->ifinfo.ifname, &x->ifinfo.MAC, numv4, numv6);
+
+ // Caution: This is a static structure, so we need to be careful that any modifications we make to it
+ // are done in such a way that they work correctly when mDNSPlatformUpdateProxyList is called multiple times
+ static struct bpf_insn filter[17 + MAX_BPF_ADDRS] =
+ {
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), // 0 Read Ethertype (bytes 12,13)
+
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0806, 0, 1), // 1 If Ethertype == ARP goto next, else 3
+ BPF_STMT(BPF_RET + BPF_K, 42), // 2 Return 42-byte ARP
+
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0800, 4, 0), // 3 If Ethertype == IPv4 goto 8 (IPv4 address list check) else next
+
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x86DD, 0, 9), // 4 If Ethertype == IPv6 goto next, else exit
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), // 5 Read Protocol and Hop Limit (bytes 20,21)
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x3AFF, 0, 9), // 6 If (Prot,TTL) == (3A,FF) goto next, else IPv6 address list check
+ BPF_STMT(BPF_RET + BPF_K, 78), // 7 Return 78-byte ND
+
+ // Is IPv4 packet; check if it's addressed to any IPv4 address we're proxying for
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, 30), // 8 Read IPv4 Dst (bytes 30,31,32,33)
+ };
+
+ struct bpf_insn *pc = &filter[9];
+ struct bpf_insn *chk6 = pc + numv4 + 1; // numv4 address checks, plus a "return 0"
+ struct bpf_insn *fail = chk6 + 1 + numv6; // Get v6 Dst LSW, plus numv6 address checks
+ struct bpf_insn *ret4 = fail + 1;
+ struct bpf_insn *ret6 = ret4 + 4;
+
+ static const struct bpf_insn rf = BPF_STMT(BPF_RET + BPF_K, 0); // No match: Return nothing
+
+ static const struct bpf_insn g6 = BPF_STMT(BPF_LD + BPF_W + BPF_ABS, 50); // Read IPv6 Dst LSW (bytes 50,51,52,53)
+
+ static const struct bpf_insn r4a = BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14); // Get IP Header length (normally 20)
+ static const struct bpf_insn r4b = BPF_STMT(BPF_LD + BPF_IMM, 34); // A = 34 (14-byte Ethernet plus 20-byte TCP)
+ static const struct bpf_insn r4c = BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0); // A += IP Header length
+ static const struct bpf_insn r4d = BPF_STMT(BPF_RET + BPF_A, 0); // Success: Return Ethernet + IP + TCP
+
+ static const struct bpf_insn r6a = BPF_STMT(BPF_RET + BPF_K, 94); // Success: Return Eth + IPv6 + TCP + 20 bytes spare
+
+ BPF_SetOffset(&filter[4], jf, fail); // If Ethertype not ARP, IPv4, or IPv6, fail
+ BPF_SetOffset(&filter[6], jf, chk6); // If IPv6 but not ICMPv6, go to IPv6 address list check
+
+ // BPF Byte-Order Note
+ // The BPF API designers apparently thought that programmers would not be smart enough to use htons
+ // and htonl correctly to convert numeric values to network byte order on little-endian machines,
+ // so instead they chose to make the API implicitly byte-swap *ALL* values, even literal byte strings
+ // that shouldn't be byte-swapped, like ASCII text, Ethernet addresses, IP addresses, etc.
+ // As a result, if we put Ethernet addresses and IP addresses in the right byte order, the BPF API
+ // will byte-swap and make them backwards, and then our filter won't work. So, we have to arrange
+ // that on little-endian machines we deliberately put addresses in memory with the bytes backwards,
+ // so that when the BPF API goes through and swaps them all, they end up back as they should be.
+ // In summary, if we byte-swap all the non-numeric fields that shouldn't be swapped, and we *don't*
+ // swap any of the numeric values that *should* be byte-swapped, then the filter will work correctly.
+
+ AuthRecord *rr;
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4)
+ {
+ mDNSv4Addr a = rr->AddressProxy.ip.v4;
+ pc->code = BPF_JMP + BPF_JEQ + BPF_K;
+ BPF_SetOffset(pc, jt, ret4);
+ pc->jf = 0;
+ pc->k = (bpf_u_int32)a.b[0] << 24 | (bpf_u_int32)a.b[1] << 16 | (bpf_u_int32)a.b[2] << 8 | (bpf_u_int32)a.b[3];
+ pc++;
+ }
+ *pc++ = rf;
+
+ if (pc != chk6) LogMsg("mDNSPlatformUpdateProxyList: pc %p != chk6 %p", pc, chk6);
+ *pc++ = g6; // chk6 points here
+
+ for (rr = m->ResourceRecords; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv6)
+ {
+ mDNSv6Addr a = rr->AddressProxy.ip.v6;
+ pc->code = BPF_JMP + BPF_JEQ + BPF_K;
+ BPF_SetOffset(pc, jt, ret6);
+ pc->jf = 0;
+ pc->k = (bpf_u_int32)a.b[12] << 24 | (bpf_u_int32)a.b[13] << 16 | (bpf_u_int32)a.b[14] << 8 | (bpf_u_int32)a.b[15];
+ pc++;
+ }
+
+ if (pc != fail) LogMsg("mDNSPlatformUpdateProxyList: pc %p != fail %p", pc, fail);
+ *pc++ = rf; // fail points here
+
+ if (pc != ret4) LogMsg("mDNSPlatformUpdateProxyList: pc %p != ret4 %p", pc, ret4);
+ *pc++ = r4a; // ret4 points here
+ *pc++ = r4b;
+ *pc++ = r4c;
+ *pc++ = r4d;
+
+ if (pc != ret6) LogMsg("mDNSPlatformUpdateProxyList: pc %p != ret6 %p", pc, ret6);
+ *pc++ = r6a; // ret6 points here
+
+ struct bpf_program prog = { pc - filter, filter };
+
+#if 0
+ // For debugging BPF filter program
+ unsigned int q;
+ for (q=0; q<prog.bf_len; q++)
+ LogSPS("mDNSPlatformUpdateProxyList: %2d { 0x%02x, %d, %d, 0x%08x },", q, prog.bf_insns[q].code, prog.bf_insns[q].jt, prog.bf_insns[q].jf, prog.bf_insns[q].k);
+#endif
+
+ if (!numv4 && !numv6)
+ {
+ LogSPS("mDNSPlatformUpdateProxyList: No need for filter");
+ if (m->timenow == 0) LogMsg("mDNSPlatformUpdateProxyList: m->timenow == 0");
+ // Schedule check to see if we can close this BPF_fd now
+ if (!m->p->NetworkChanged) m->p->NetworkChanged = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2);
+ // prog.bf_len = 0; This seems to panic the kernel
+ }
+
+ if (ioctl(x->BPF_fd, BIOCSETF, &prog) < 0) LogMsg("mDNSPlatformUpdateProxyList: BIOCSETF(%d) failed %d (%s)", prog.bf_len, errno, strerror(errno));
+ else LogSPS("mDNSPlatformUpdateProxyList: BIOCSETF(%d) successful", prog.bf_len);
+ }
+
+mDNSexport void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd)
+ {
+ mDNS_Lock(m);
+
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next) if (i->BPF_fd == -2) break;
+ if (!i) { LogSPS("mDNSPlatformReceiveBPF_fd: No Interfaces awaiting BPF fd %d; closing", fd); close(fd); }
+ else
+ {
+ LogSPS("%s using BPF fd %d", i->ifinfo.ifname, fd);
+
+ struct bpf_version v;
+ if (ioctl(fd, BIOCVERSION, &v) < 0)
+ LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCVERSION failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
+ else if (BPF_MAJOR_VERSION != v.bv_major || BPF_MINOR_VERSION != v.bv_minor)
+ LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCVERSION header %d.%d kernel %d.%d",
+ fd, i->ifinfo.ifname, BPF_MAJOR_VERSION, BPF_MINOR_VERSION, v.bv_major, v.bv_minor);
+
+ if (ioctl(fd, BIOCGBLEN, &i->BPF_len) < 0)
+ LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCGBLEN failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
+
+ if (i->BPF_len > sizeof(m->imsg))
+ {
+ i->BPF_len = sizeof(m->imsg);
+ if (ioctl(fd, BIOCSBLEN, &i->BPF_len) < 0)
+ LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCSBLEN failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
+ else LogSPS("mDNSPlatformReceiveBPF_fd: %d %s BIOCSBLEN %d", i->BPF_len);
+ }
+
+ static const u_int opt_immediate = 1;
+ if (ioctl(fd, BIOCIMMEDIATE, &opt_immediate) < 0)
+ LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCIMMEDIATE failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno));
+
+ struct ifreq ifr;
+ mDNSPlatformMemZero(&ifr, sizeof(ifr));
+ strlcpy(ifr.ifr_name, i->ifinfo.ifname, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, &ifr) < 0)
+ { LogMsg("mDNSPlatformReceiveBPF_fd: %d %s BIOCSETIF failed %d (%s)", fd, i->ifinfo.ifname, errno, strerror(errno)); i->BPF_fd = -3; }
+ else
+ {
+ CFSocketContext myCFSocketContext = { 0, i, NULL, NULL, NULL };
+ i->BPF_fd = fd;
+ i->BPF_cfs = CFSocketCreateWithNative(kCFAllocatorDefault, fd, kCFSocketReadCallBack, bpf_callback, &myCFSocketContext);
+ i->BPF_rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, i->BPF_cfs, 0);
+ CFRunLoopAddSource(i->m->p->CFRunLoop, i->BPF_rls, kCFRunLoopDefaultMode);
+ mDNSPlatformUpdateProxyList(m, (mDNSInterfaceID)i);
+ }
+ }
+
+ mDNS_Unlock(m);
+ }
+
+#endif // APPLE_OSX_mDNSResponder
+
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Key Management
+#endif
+
+#ifndef NO_SECURITYFRAMEWORK
+mDNSlocal CFArrayRef GetCertChain(SecIdentityRef identity)
+ {
+ CFMutableArrayRef certChain = NULL;
+ if (!identity) { LogMsg("getCertChain: identity is NULL"); return(NULL); }
+ SecCertificateRef cert;
+ OSStatus err = SecIdentityCopyCertificate(identity, &cert);
+ if (err || !cert) LogMsg("getCertChain: SecIdentityCopyCertificate() returned %d", (int) err);
+ else
+ {
+ SecPolicySearchRef searchRef;
err = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &searchRef);
if (err || !searchRef) LogMsg("getCertChain: SecPolicySearchCreate() returned %d", (int) err);
else
}
}
-mDNSlocal mDNSBool DDNSSettingEnabled(CFDictionaryRef dict)
+mDNSexport mDNSBool DictionaryIsEnabled(CFDictionaryRef dict)
{
mDNSs32 val;
CFNumberRef state = CFDictionaryGetValue(dict, CFSTR("Enabled"));
if (!state) return mDNSfalse;
- if (!CFNumberGetValue(state, kCFNumberSInt32Type, &val)) { LogMsg("ERROR: DDNSSettingEnabled - CFNumberGetValue"); return mDNSfalse; }
+ if (!CFNumberGetValue(state, kCFNumberSInt32Type, &val))
+ { LogMsg("ERROR: DictionaryIsEnabled - CFNumberGetValue"); return mDNSfalse; }
return val ? mDNStrue : mDNSfalse;
}
{
mDNSEthAddr eth = zeroEthAddr;
SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:GetBSSID"), NULL, NULL);
- if (store)
+ if (!store)
+ LogMsg("GetBSSID: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
+ else
{
CFStringRef entityname = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Interface/%s/AirPort"), ifa_name);
if (entityname)
return(eth);
}
+mDNSlocal int GetMAC(mDNSEthAddr *eth, u_short ifindex)
+ {
+ struct ifaddrs *ifa;
+ for (ifa = myGetIfAddrs(0); ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_LINK)
+ {
+ const struct sockaddr_dl *const sdl = (const struct sockaddr_dl *)ifa->ifa_addr;
+ if (sdl->sdl_index == ifindex)
+ { mDNSPlatformMemCopy(eth->b, sdl->sdl_data + sdl->sdl_nlen, 6); return 0; }
+ }
+ *eth = zeroEthAddr;
+ return -1;
+ }
+
+#ifndef SIOCGIFWAKEFLAGS
+#define SIOCGIFWAKEFLAGS _IOWR('i', 136, struct ifreq) /* get interface wake property flags */
+#endif
+
+#ifndef IF_WAKE_ON_MAGIC_PACKET
+#define IF_WAKE_ON_MAGIC_PACKET 0x01
+#endif
+
+#ifndef ifr_wake_flags
+#define ifr_wake_flags ifr_ifru.ifru_intval
+#endif
+
+mDNSlocal mDNSBool NetWakeInterface(NetworkInterfaceInfoOSX *i)
+ {
+ if (!MulticastInterface(i) ) return(mDNSfalse); // We only use Sleep Proxy Service on multicast-capable interfaces
+ if (i->ifa_flags & IFF_LOOPBACK) return(mDNSfalse); // except loopback
+
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) { LogMsg("NetWakeInterface %s socket failed %s errno %d (%s)", i->ifinfo.ifname, errno, strerror(errno)); return(mDNSfalse); }
+
+ struct ifreq ifr;
+ strlcpy(ifr.ifr_name, i->ifinfo.ifname, sizeof(ifr.ifr_name));
+ if (ioctl(s, SIOCGIFWAKEFLAGS, &ifr) < 0)
+ {
+ // For some strange reason, in /usr/include/sys/errno.h, EOPNOTSUPP is defined to be
+ // 102 when compiling kernel code, and 45 when compiling user-level code. Since this
+ // error code is being returned from the kernel, we need to use the kernel version.
+ #define KERNEL_EOPNOTSUPP 102
+ if (errno != KERNEL_EOPNOTSUPP) // "Operation not supported on socket", the expected result on Leopard and earlier
+ LogMsg("NetWakeInterface SIOCGIFWAKEFLAGS %s errno %d (%s)", i->ifinfo.ifname, errno, strerror(errno));
+ // If on Leopard or earlier, we get EOPNOTSUPP, so in that case
+ // we enable WOL if this interface is not AirPort and "Wake for Network access" is turned on.
+ ifr.ifr_wake_flags = (errno == KERNEL_EOPNOTSUPP && !(i)->BSSID.l[0] && i->m->SystemWakeOnLANEnabled) ? IF_WAKE_ON_MAGIC_PACKET : 0;
+ }
+#if ASSUME_SNOWLEOPARD_INCORRECTLY_REPORTS_AIRPORT_INCAPABLE_OF_WAKE_ON_LAN
+ else
+ {
+ // Call succeeded.
+ // However, on SnowLeopard, it currently indicates incorrectly that AirPort is incapable of Wake-on-LAN.
+ // Therefore, for AirPort interfaces, we just track the system-wide Wake-on-LAN setting.
+ if ((i)->BSSID.l[0]) ifr.ifr_wake_flags = i->m->SystemWakeOnLANEnabled ? IF_WAKE_ON_MAGIC_PACKET : 0;
+ }
+#endif
+
+ close(s);
+
+ // ifr.ifr_wake_flags = IF_WAKE_ON_MAGIC_PACKET; // For testing with MacBook Air, using a USB dongle that doesn't actually support Wake-On-LAN
+
+ LogSPS("%-6s %#-14a %s WOMP", i->ifinfo.ifname, &i->ifinfo.ip, (ifr.ifr_wake_flags & IF_WAKE_ON_MAGIC_PACKET) ? "supports" : "no");
+
+ return((ifr.ifr_wake_flags & IF_WAKE_ON_MAGIC_PACKET) != 0);
+ }
+
// Returns pointer to newly created NetworkInterfaceInfoOSX object, or
// pointer to already-existing NetworkInterfaceInfoOSX object found in list, or
// may return NULL if out of memory (unlikely) or parameters are invalid for some reason
NetworkInterfaceInfoOSX **p;
for (p = &m->p->InterfaceList; *p; p = &(*p)->next)
- if (scope_id == (*p)->scope_id && mDNSSameAddress(&ip, &(*p)->ifinfo.ip) && mDNSSameEthAddress(&bssid, &(*p)->BSSID))
+ if (scope_id == (*p)->scope_id &&
+ mDNSSameAddress(&ip, &(*p)->ifinfo.ip) &&
+ mDNSSameEthAddress(&bssid, &(*p)->BSSID))
{
debugf("AddInterfaceToList: Found existing interface %lu %.6a with address %#a at %p", scope_id, &bssid, &ip, *p);
(*p)->Exists = mDNStrue;
// If interface was not in getifaddrs list last time we looked, but it is now, update 'AppearanceTime' for this record
if ((*p)->LastSeen != utc) (*p)->AppearanceTime = utc;
+
+ // If Wake-on-LAN capability of this interface has changed (e.g. because power cable on laptop has been disconnected)
+ // we may need to start or stop or sleep proxy browse operation
+ const mDNSBool NetWake = NetWakeInterface(*p);
+ if ((*p)->ifinfo.NetWake != NetWake)
+ {
+ (*p)->ifinfo.NetWake = NetWake;
+ // If this interface is already registered with mDNSCore, then we need to start or stop its NetWake browse on-the-fly.
+ // If this interface is not already registered (i.e. it's a dormant interface we had in our list
+ // from when we previously saw it) then we mustn't do that, because mDNSCore doesn't know about it yet.
+ // In this case, the mDNS_RegisterInterface() call will take care of starting the NetWake browse if necessary.
+ if ((*p)->ifinfo.InterfaceID)
+ {
+ mDNS_Lock(m);
+ if (NetWake) mDNS_ActivateNetWake_internal (m, &(*p)->ifinfo);
+ else mDNS_DeactivateNetWake_internal(m, &(*p)->ifinfo);
+ mDNS_Unlock(m);
+ }
+ }
+
return(*p);
}
debugf("AddInterfaceToList: Making new interface %lu %.6a with address %#a at %p", scope_id, &bssid, &ip, i);
if (!i) return(mDNSNULL);
mDNSPlatformMemZero(i, sizeof(NetworkInterfaceInfoOSX));
- i->ifa_name = (char *)mallocL("NetworkInterfaceInfoOSX name", strlen(ifa->ifa_name) + 1);
- if (!i->ifa_name) { freeL("NetworkInterfaceInfoOSX", i); return(mDNSNULL); }
- strcpy(i->ifa_name, ifa->ifa_name); // This is safe because we know we allocated i->ifa_name with sufficient space
-
i->ifinfo.InterfaceID = mDNSNULL;
i->ifinfo.ip = ip;
i->ifinfo.mask = mask;
strlcpy(i->ifinfo.ifname, ifa->ifa_name, sizeof(i->ifinfo.ifname));
i->ifinfo.ifname[sizeof(i->ifinfo.ifname)-1] = 0;
- i->ifinfo.Advertise = m->AdvertiseLocalAddresses;
+ // We can be configured to disable multicast advertisement, but we want to to support
+ // local-only services, which need a loopback address record.
+ i->ifinfo.Advertise = m->DivertMulticastAdvertisements ? ((ifa->ifa_flags & IFF_LOOPBACK) ? mDNStrue : mDNSfalse) : m->AdvertiseLocalAddresses;
i->ifinfo.McastTxRx = mDNSfalse; // For now; will be set up later at the end of UpdateInterfaceList
i->next = mDNSNULL;
+ i->m = m;
i->Exists = mDNStrue;
- i->AppearanceTime = utc; // Brand new interface; AppearanceTime is now
- i->LastSeen = utc;
i->Flashing = mDNSfalse;
i->Occulting = mDNSfalse;
+ i->AppearanceTime = utc; // Brand new interface; AppearanceTime is now
+ i->LastSeen = utc;
+ i->ifa_flags = ifa->ifa_flags;
i->scope_id = scope_id;
i->BSSID = bssid;
i->sa_family = ifa->ifa_addr->sa_family;
- i->ifa_flags = ifa->ifa_flags;
+ i->BPF_fd = -1;
+ i->BPF_len = 0;
+
+ // Do this AFTER i->BSSID has been set up
+ i->ifinfo.NetWake = NetWakeInterface(i);
+ GetMAC(&i->ifinfo.MAC, scope_id);
+ if (i->ifinfo.NetWake && !i->ifinfo.MAC.l[0])
+ LogMsg("AddInterfaceToList: Bad MAC address %.6a for %d %s %#a", &i->ifinfo.MAC, scope_id, i->ifinfo.ifname, &ip);
*p = i;
return(i);
#define kRacoonPort 4500
-static mDNSBool AnonymousRacoonConfig = mDNSfalse;
+static DomainAuthInfo* AnonymousRacoonConfig = mDNSNULL;
#ifndef NO_SECURITYFRAMEWORK
static CFMutableDictionaryRef domainStatusDict = NULL;
// MUST be called with lock held
-mDNSlocal void RemoveAutoTunnelDomainStatus(const DomainAuthInfo *const info)
+mDNSlocal void RemoveAutoTunnelDomainStatus(const mDNS *const m, const DomainAuthInfo *const info)
{
char buffer[1024];
CFStringRef domain;
- LogOperation("RemoveAutoTunnelDomainStatus: %##s", info->domain.c);
+ LogInfo("RemoveAutoTunnelDomainStatus: %##s", info->domain.c);
if (!domainStatusDict) { LogMsg("RemoveAutoTunnelDomainStatus: No domainStatusDict"); return; }
if (CFDictionaryContainsKey(domainStatusDict, domain))
{
CFDictionaryRemoveValue(domainStatusDict, domain);
- mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, domainStatusDict);
+ if (!m->ShutdownTime) mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, mDNSNULL, domainStatusDict);
}
CFRelease(domain);
}
#endif // ndef NO_SECURITYFRAMEWORK
+mDNSlocal mStatus CheckQuestionForStatus(const DNSQuestion *const q)
+ {
+ if (q->LongLived)
+ {
+ if (q->nta || (q->servAddr.type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsOnes(q->servAddr.ip.v4)))
+ return mStatus_NoSuchRecord;
+ else if (q->state == LLQ_Poll)
+ return mStatus_PollingMode;
+ else if (q->state != LLQ_Established && !q->DuplicateOf)
+ return mStatus_TransientErr;
+ }
+
+ return mStatus_NoError;
+}
+
// MUST be called with lock held
mDNSlocal void UpdateAutoTunnelDomainStatus(const mDNS *const m, const DomainAuthInfo *const info)
{
}
}
}
+ if (tun || llq)
+ {
+ mDNSu32 code = m->LastNATMapResultCode;
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &code);
+ if (!num)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LastNATMapResultCode");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("LastNATMapResultCode"), num);
+ CFRelease(num);
+ }
+ }
if (!llq && !tun)
{
status = mStatus_NotInitializedErr;
mDNS_snprintf(buffer, sizeof(buffer), "Neither LLQ nor AutoTunnel NAT port mapping is currently active");
- }
+ }
else if ((llq && llq->Result == mStatus_DoubleNAT) || (tun && tun->Result == mStatus_DoubleNAT))
{
status = mStatus_DoubleNAT;
mDNS_snprintf(buffer, sizeof(buffer), "Double NAT: Router is reporting an external address");
}
+ else if ((llq && llq->Result == mStatus_NATPortMappingDisabled) || (tun && tun->Result == mStatus_NATPortMappingDisabled) ||
+ (m->LastNATMapResultCode == NATErr_Refused && ((llq && !llq->Result && mDNSIPPortIsZero(llq->ExternalPort)) || (tun && !tun->Result && mDNSIPPortIsZero(tun->ExternalPort)))))
+ {
+ status = mStatus_NATPortMappingDisabled;
+ mDNS_snprintf(buffer, sizeof(buffer), "NAT-PMP is disabled on the router");
+ }
else if ((llq && llq->Result) || (tun && tun->Result))
{
status = mStatus_NATTraversal;
}
else
{
- DNSQuestion* q;
+ DNSQuestion* q, *worst_q = mDNSNULL;
for (q = m->Questions; q; q=q->next)
- if (q->LongLived && q->AuthInfo == info && q->state == LLQ_Poll)
+ if (q->AuthInfo == info)
{
- status = mStatus_PollingMode;
- mDNS_snprintf(buffer, sizeof(buffer), "Query polling %##s", q->qname.c);
- break;
+ mStatus newStatus = CheckQuestionForStatus(q);
+ if (newStatus == mStatus_NoSuchRecord) { status = newStatus; worst_q = q; break; }
+ else if (newStatus == mStatus_PollingMode) { status = newStatus; worst_q = q; }
+ else if (newStatus == mStatus_TransientErr && status == mStatus_NoError) { status = newStatus; worst_q = q; }
}
- if (status == mStatus_NoError)
- for (q = m->Questions; q; q=q->next)
- if (q->LongLived && q->AuthInfo == info && q->state != LLQ_Established && !q->DuplicateOf)
- {
- status = mStatus_TransientErr;
- mDNS_snprintf(buffer, sizeof(buffer), "Query not yet established %##s", q->qname.c);
- break;
- }
- if (status == mStatus_NoError) mDNS_snprintf(buffer, sizeof(buffer), "Success");
+
+ if (status == mStatus_NoError) mDNS_snprintf(buffer, sizeof(buffer), "Success");
+ else if (status == mStatus_NoSuchRecord) mDNS_snprintf(buffer, sizeof(buffer), "GetZoneData %s: %##s", worst_q->nta ? "not yet complete" : "failed", worst_q->qname.c);
+ else if (status == mStatus_PollingMode) mDNS_snprintf(buffer, sizeof(buffer), "Query polling %##s", worst_q->qname.c);
+ else if (status == mStatus_TransientErr) mDNS_snprintf(buffer, sizeof(buffer), "Query not yet established %##s", worst_q->qname.c);
}
num = CFNumberCreate(NULL, kCFNumberSInt32Type, &status);
!CFEqual(dict, (CFMutableDictionaryRef)CFDictionaryGetValue(domainStatusDict, domain)))
{
CFDictionarySetValue(domainStatusDict, domain, dict);
- mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, domainStatusDict);
+ if (!m->ShutdownTime)
+ {
+ static char statusBuf[16];
+ mDNS_snprintf(statusBuf, sizeof(statusBuf), "%d", (int)status);
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.domainstatus", status ? "failure" : "success", statusBuf, "");
+ mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, mDNSNULL, domainStatusDict);
+ }
}
CFRelease(domain);
CFRelease(dict);
- LogOperation("UpdateAutoTunnelDomainStatus: %s", buffer);
+ debugf("UpdateAutoTunnelDomainStatus: %s", buffer);
#endif // def NO_SECURITYFRAMEWORK
}
DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, p->RR_SRV.resrec.name);
if (AuthInfo && AuthInfo->AutoTunnel && !AuthInfo->deltime) return(mDNStrue);
}
+
+ AuthRecord *r;
+ for (r = m->ResourceRecords; r; r = r->next)
+ if (r->resrec.rrtype == kDNSType_SRV)
+ {
+ DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, r->resrec.name);
+ if (AuthInfo && AuthInfo->AutoTunnel && !AuthInfo->deltime) return(mDNStrue);
+ }
+
return(mDNSfalse);
}
if (info->AutoTunnelNAT.clientContext && !info->AutoTunnelNAT.Result && !mDNSIPPortIsZero(info->AutoTunnelNAT.ExternalPort) && AutoTunnelUnregistered(info))
{
mStatus err;
- LogOperation("RegisterAutoTunnelRecords %##s (%#s)", info->domain.c, m->hostlabel.c);
+ LogInfo("RegisterAutoTunnelRecords %##s (%#s)", info->domain.c, m->hostlabel.c);
// 1. Set up our address record for the internal tunnel address
// (User-visible user-friendly host name, used as target in AutoTunnel SRV records)
info->AutoTunnelHostRecord.resrec.rdata->u.ipv6 = m->AutoTunnelHostAddr;
info->AutoTunnelHostRecord.resrec.RecordType = kDNSRecordTypeKnownUnique;
err = mDNS_Register(m, &info->AutoTunnelHostRecord);
- if (err) LogMsg("RegisterAutoTunnelRecords error %d registering AutoTunnelHostRecord %##s", err, info->AutoTunnelHostRecord.namestorage.c);
+ if (err) LogMsg("RegisterAutoTunnelRecords error %d registering AutoTunnelHostRecord %##s", err, info->AutoTunnelHostRecord.namestorage.c);
// 2. Set up device info record
ConstructServiceName(&info->AutoTunnelDeviceInfo.namestorage, &m->nicelabel, &DeviceInfoName, &info->domain);
err = mDNS_Register(m, &info->AutoTunnelService);
if (err) LogMsg("RegisterAutoTunnelRecords error %d registering AutoTunnelService %##s", err, info->AutoTunnelService.namestorage.c);
- LogOperation("AutoTunnel server listening for connections on %##s[%.4a]:%d:%##s[%.16a]",
+ LogInfo("AutoTunnel server listening for connections on %##s[%.4a]:%d:%##s[%.16a]",
info->AutoTunnelTarget.namestorage.c, &m->AdvertisedV4.ip.v4, mDNSVal16(info->AutoTunnelNAT.IntPort),
info->AutoTunnelHostRecord.namestorage.c, &m->AutoTunnelHostAddr);
}
mDNSlocal void DeregisterAutoTunnelRecords(mDNS *m, DomainAuthInfo *info)
{
- LogOperation("DeregisterAutoTunnelRecords %##s", info->domain.c);
+ LogInfo("DeregisterAutoTunnelRecords %##s", info->domain.c);
if (info->AutoTunnelService.resrec.RecordType > kDNSRecordTypeDeregistering)
{
mStatus err = mDNS_Deregister(m, &info->AutoTunnelService);
DomainAuthInfo *info = (DomainAuthInfo *)rr->RecordContext;
if (result == mStatus_MemFree)
{
- LogOperation("AutoTunnelRecordCallback MemFree %s", ARDisplayString(m, rr));
+ LogInfo("AutoTunnelRecordCallback MemFree %s", ARDisplayString(m, rr));
// Reset the host record namestorage to force high-level PTR/SRV/TXT to deregister
if (rr == &info->AutoTunnelHostRecord)
{
}
}
+// Determine whether we need racoon to accept incoming connections
+mDNSlocal void UpdateConfigureServer(mDNS *m)
+ {
+ DomainAuthInfo *info;
+
+ for (info = m->AuthInfoList; info; info = info->next)
+ if (info->AutoTunnel && !info->deltime && !mDNSIPPortIsZero(info->AutoTunnelNAT.ExternalPort))
+ break;
+
+ if (info != AnonymousRacoonConfig)
+ {
+ AnonymousRacoonConfig = info;
+ // Create or revert configuration file, and start (or SIGHUP) Racoon
+ (void)mDNSConfigureServer(AnonymousRacoonConfig ? kmDNSUp : kmDNSDown, AnonymousRacoonConfig ? &AnonymousRacoonConfig->domain : mDNSNULL);
+ }
+ }
+
mDNSlocal void AutoTunnelNATCallback(mDNS *m, NATTraversalInfo *n)
{
DomainAuthInfo *info = (DomainAuthInfo *)n->clientContext;
- LogOperation("AutoTunnelNATCallback Result %d %.4a Internal %d External %d %#s.%##s",
+ LogInfo("AutoTunnelNATCallback Result %d %.4a Internal %d External %d %#s.%##s",
n->Result, &n->ExternalAddress, mDNSVal16(n->IntPort), mDNSVal16(n->ExternalPort), m->hostlabel.c, info->domain.c);
m->NextSRVUpdate = NonZeroTime(m->timenow);
DeregisterAutoTunnelRecords(m,info);
RegisterAutoTunnelRecords(m,info);
+
+ UpdateConfigureServer(m);
- // Determine whether we need racoon to accept incoming connections
- for (info = m->AuthInfoList; info; info = info->next)
- if (info->AutoTunnel && !info->deltime && !mDNSIPPortIsZero(info->AutoTunnelNAT.ExternalPort))
- break;
- mDNSBool needRacoonConfig = info != mDNSNULL;
- if (needRacoonConfig != AnonymousRacoonConfig)
- {
- AnonymousRacoonConfig = needRacoonConfig;
- // Create or revert configuration file, and start (or SIGHUP) Racoon
- (void)mDNSConfigureServer(AnonymousRacoonConfig ? kmDNSUp : kmDNSDown, info ? info->b64keydata : "");
- }
-
UpdateAutoTunnelDomainStatus(m, (DomainAuthInfo *)n->clientContext);
}
{
if (rr->resrec.RecordType == kDNSRecordTypeDeregistering)
{
- LogOperation("Aborting deregistration of %s", ARDisplayString(m, rr));
+ LogInfo("Aborting deregistration of %s", ARDisplayString(m, rr));
CompleteDeregistration(m, rr);
}
else if (rr->resrec.RecordType != kDNSRecordTypeUnregistered)
// Must be called with the lock held
mDNSexport void SetupLocalAutoTunnelInterface_internal(mDNS *const m)
{
- LogOperation("SetupLocalAutoTunnelInterface");
+ LogInfo("SetupLocalAutoTunnelInterface");
// 1. Configure the local IPv6 address
if (!m->AutoTunnelHostAddrActive)
{
m->AutoTunnelHostAddrActive = mDNStrue;
- LogOperation("Setting up AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
+ LogInfo("Setting up AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
(void)mDNSAutoTunnelInterfaceUpDown(kmDNSUp, m->AutoTunnelHostAddr.b);
}
mDNSlocal mStatus AutoTunnelSetKeys(ClientTunnel *tun, mDNSBool AddNew)
{
- return(mDNSAutoTunnelSetKeys(AddNew ? kmDNSAutoTunnelSetKeysReplace : kmDNSAutoTunnelSetKeysDelete, tun->loc_inner.b, tun->loc_outer.b, kRacoonPort, tun->rmt_inner.b, tun->rmt_outer.b, mDNSVal16(tun->rmt_outer_port), tun->b64keydata));
+ return(mDNSAutoTunnelSetKeys(AddNew ? kmDNSAutoTunnelSetKeysReplace : kmDNSAutoTunnelSetKeysDelete, tun->loc_inner.b, tun->loc_outer.b, kRacoonPort, tun->rmt_inner.b, tun->rmt_outer.b, mDNSVal16(tun->rmt_outer_port), SkipLeadingLabels(&tun->dstname, 1)));
}
// If the EUI-64 part of the IPv6 ULA matches, then that means the two addresses point to the same machine
{
if (q->NoAnswer == NoAnswer_Suspended && q->qtype == qtype && q->AuthInfo && q->AuthInfo->AutoTunnel && SameDomainName(&q->qname, d))
{
- LogOperation("Restart %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ LogInfo("Restart %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
mDNSQuestionCallback *tmp = q->QuestionCallback;
q->QuestionCallback = AutoTunnelCallback; // Set QuestionCallback to suppress another call back to AddNewClientTunnel
mDNS_StopQuery(m, q);
mDNS_StartQuery(m, q);
q->QuestionCallback = tmp; // Restore QuestionCallback back to the real value
if (!success) q->NoAnswer = NoAnswer_Fail;
- // When we call mDNS_StopQuery, it's possible for other subbordinate questions like the GetZoneData query to be cancelled too.
+ // When we call mDNS_StopQuery, it's possible for other subordinate questions like the GetZoneData query to be cancelled too.
// In general we have to assume that the question list might have changed in arbitrary ways.
// This code is itself called from a question callback, so the m->CurrentQuestion mechanism is
// already in use. The safest solution is just to go back to the start of the list and start again.
while (*p != tun && *p) p = &(*p)->next;
if (*p) *p = tun->next;
ReissueBlockedQuestions(m, &tun->dstname, success);
- LogOperation("UnlinkAndReissueBlockedQuestions: Disposing ClientTunnel %p", tun);
+ LogInfo("UnlinkAndReissueBlockedQuestions: Disposing ClientTunnel %p", tun);
freeL("ClientTunnel", tun);
}
mDNSexport void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
ClientTunnel *tun = (ClientTunnel *)question->QuestionContext;
- LogOperation("AutoTunnelCallback tun %p AddRecord %d rdlength %d qtype %d", tun, AddRecord, answer->rdlength, question->qtype);
+ LogInfo("AutoTunnelCallback tun %p AddRecord %d rdlength %d qtype %d", tun, AddRecord, answer->rdlength, question->qtype);
if (!AddRecord) return;
mDNS_StopQuery(m, question);
if (!answer->rdlength)
{
- LogOperation("AutoTunnelCallback NXDOMAIN %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+ LogInfo("AutoTunnelCallback NXDOMAIN %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+ static char msgbuf[16];
+ mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s lookup", DNSTypeName(question->qtype));
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.config", "failure", msgbuf, "");
UnlinkAndReissueBlockedQuestions(m, tun, mDNSfalse);
return;
}
{
if (mDNSSameIPv6Address(answer->rdata->u.ipv6, m->AutoTunnelHostAddr))
{
- LogOperation("AutoTunnelCallback: suppressing tunnel to self %.16a", &answer->rdata->u.ipv6);
+ LogInfo("AutoTunnelCallback: suppressing tunnel to self %.16a", &answer->rdata->u.ipv6);
UnlinkAndReissueBlockedQuestions(m, tun, mDNStrue);
return;
}
tun->rmt_inner = answer->rdata->u.ipv6;
- LogOperation("AutoTunnelCallback: dst host %.16a", &tun->rmt_inner);
+ LogInfo("AutoTunnelCallback: dst host %.16a", &tun->rmt_inner);
AssignDomainName(&question->qname, (const domainname*) "\x0B" "_autotunnel" "\x04" "_udp");
AppendDomainName(&question->qname, &tun->dstname);
question->qtype = kDNSType_SRV;
}
else if (question->qtype == kDNSType_SRV)
{
- LogOperation("AutoTunnelCallback: SRV target name %##s", answer->rdata->u.srv.target.c);
+ LogInfo("AutoTunnelCallback: SRV target name %##s", answer->rdata->u.srv.target.c);
AssignDomainName(&tun->q.qname, &answer->rdata->u.srv.target);
tun->rmt_outer_port = answer->rdata->u.srv.port;
question->qtype = kDNSType_A;
else if (question->qtype == kDNSType_A)
{
ClientTunnel *old = mDNSNULL;
- LogOperation("AutoTunnelCallback: SRV target addr %.4a", &answer->rdata->u.ipv4);
+ LogInfo("AutoTunnelCallback: SRV target addr %.4a", &answer->rdata->u.ipv4);
question->ThisQInterval = -1; // So we know this tunnel setup has completed
tun->rmt_outer = answer->rdata->u.ipv4;
tun->loc_inner = m->AutoTunnelHostAddr;
if (!mDNSSameClientTunnel(&(*p)->rmt_inner, &tun->rmt_inner)) p = &(*p)->next;
else
{
- LogOperation("Found existing AutoTunnel for %##s %.16a", tun->dstname.c, &tun->rmt_inner);
+ LogInfo("Found existing AutoTunnel for %##s %.16a", tun->dstname.c, &tun->rmt_inner);
old = *p;
*p = old->next;
if (old->q.ThisQInterval >= 0) mDNS_StopQuery(m, &old->q);
!mDNSSameIPv4Address(old->rmt_outer, tun->rmt_outer) ||
!mDNSSameIPPort(old->rmt_outer_port, tun->rmt_outer_port))
{
- LogOperation("Deleting existing AutoTunnel for %##s %.16a", tun->dstname.c, &tun->rmt_inner);
+ LogInfo("Deleting existing AutoTunnel for %##s %.16a", tun->dstname.c, &tun->rmt_inner);
AutoTunnelSetKeys(old, mDNSfalse);
}
else needSetKeys = mDNSfalse;
- LogOperation("AutoTunnelCallback: Disposing ClientTunnel %p", tun);
+ LogInfo("AutoTunnelCallback: Disposing ClientTunnel %p", tun);
freeL("ClientTunnel", old);
}
}
- if (needSetKeys) LogOperation("New AutoTunnel for %##s %.16a", tun->dstname.c, &tun->rmt_inner);
+ if (needSetKeys) LogInfo("New AutoTunnel for %##s %.16a", tun->dstname.c, &tun->rmt_inner);
if (m->AutoTunnelHostAddr.b[0]) { mDNS_Lock(m); SetupLocalAutoTunnelInterface_internal(m); mDNS_Unlock(m); };
mStatus result = needSetKeys ? AutoTunnelSetKeys(tun, mDNStrue) : mStatus_NoError;
+ static char msgbuf[32];
+ mDNS_snprintf(msgbuf, sizeof(msgbuf), "Tunnel setup - %d", result);
+ mDNSASLLog((uuid_t *)&m->asl_uuid, "autotunnel.config", result ? "failure" : "success", msgbuf, "");
// Kick off any questions that were held pending this tunnel setup
ReissueBlockedQuestions(m, &tun->dstname, (result == mStatus_NoError) ? mDNStrue : mDNSfalse);
}
p->rmt_inner = zerov6Addr;
p->rmt_outer = zerov4Addr;
p->rmt_outer_port = zeroIPPort;
- mDNS_snprintf(p->b64keydata, sizeof(p->b64keydata), "%s", q->AuthInfo->b64keydata);
p->next = m->TunnelClients;
m->TunnelClients = p; // We intentionally build list in reverse order
p->q.QuestionCallback = AutoTunnelCallback;
p->q.QuestionContext = p;
- LogOperation("AddNewClientTunnel start tun %p %##s (%s)%s", p, &q->qname.c, DNSTypeName(q->qtype), q->LongLived ? " LongLived" : "");
+ LogInfo("AddNewClientTunnel start tun %p %##s (%s)%s", p, &q->qname.c, DNSTypeName(q->qtype), q->LongLived ? " LongLived" : "");
mDNS_StartQuery_internal(m, &p->q);
}
#pragma mark - Power State & Configuration Change Management
#endif
-mDNSlocal void GenerateDefaultName(const mDNSEthAddr PrimaryMAC, char *buffer, mDNSu32 length)
-{
- char hwName[32];
- size_t hwNameLen = sizeof(hwName);
-
- hwName[0] = 0;
- if (sysctlbyname("hw.model", &hwName, &hwNameLen, NULL, 0) == 0)
- {
- // hw.model contains a number like iMac6,1. We want the "iMac" part.
- hwName[sizeof(hwName) - 1] = 0;
- char *ptr;
- for (ptr = hwName; *ptr != 0; ptr++)
- {
- if (*ptr >= '0' && *ptr <= '9') *ptr = 0;
- if (*ptr == ',') break;
- }
- // Prototype model names do not contain commas, do not use prototype names
- if (*ptr != ',') hwName[0] = 0;
- }
-
- if (hwName[0] == 0) strlcpy(hwName, "Device", sizeof(hwName));
-
- mDNS_snprintf(buffer, length, "%s-%02X%02X%02X%02X%02X%02X", hwName,
- PrimaryMAC.b[0], PrimaryMAC.b[1], PrimaryMAC.b[2], PrimaryMAC.b[3], PrimaryMAC.b[4], PrimaryMAC.b[5]);
-}
-
mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
{
mDNSBool foundav4 = mDNSfalse;
struct ifaddrs *ifa = myGetIfAddrs(1);
struct ifaddrs *v4Loopback = NULL;
struct ifaddrs *v6Loopback = NULL;
- mDNSEthAddr PrimaryMAC = zeroEthAddr;
char defaultname[64];
#ifndef NO_IPV6
int InfoSocket = socket(AF_INET6, SOCK_DGRAM, 0);
if (InfoSocket < 3 && errno != EAFNOSUPPORT) LogMsg("UpdateInterfaceList: InfoSocket error %d errno %d (%s)", InfoSocket, errno, strerror(errno));
#endif
- if (m->SleepState) ifa = NULL;
+ if (m->SleepState == SleepState_Sleeping) ifa = NULL;
while (ifa)
{
if (ifa->ifa_addr->sa_family == AF_LINK)
{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
- if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == sizeof(PrimaryMAC) && mDNSSameEthAddress(&PrimaryMAC, &zeroEthAddr))
- mDNSPlatformMemCopy(PrimaryMAC.b, sdl->sdl_data + sdl->sdl_nlen, 6);
+ if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == sizeof(m->PrimaryMAC) && mDNSSameEthAddress(&m->PrimaryMAC, &zeroEthAddr))
+ mDNSPlatformMemCopy(m->PrimaryMAC.b, sdl->sdl_data + sdl->sdl_nlen, 6);
}
if (ifa->ifa_flags & IFF_UP && ifa->ifa_addr)
else
{
NetworkInterfaceInfoOSX *i = AddInterfaceToList(m, ifa, utc);
- if (i && MulticastInterface(i))
+ if (i && MulticastInterface(i) && i->ifinfo.Advertise)
{
if (ifa->ifa_addr->sa_family == AF_INET) foundav4 = mDNStrue;
else foundav6 = mDNStrue;
ifa = ifa->ifa_next;
}
- // For efficiency, we don't register a loopback interface when other interfaces of that family are available
+ // For efficiency, we don't register a loopback interface when other interfaces of that family are available and advertising
if (!foundav4 && v4Loopback) AddInterfaceToList(m, v4Loopback, utc);
if (!foundav6 && v6Loopback) AddInterfaceToList(m, v6Loopback, utc);
#endif
// If we haven't set up AutoTunnelHostAddr yet, do it now
- if (!mDNSSameEthAddress(&PrimaryMAC, &zeroEthAddr) && m->AutoTunnelHostAddr.b[0] == 0)
+ if (!mDNSSameEthAddress(&m->PrimaryMAC, &zeroEthAddr) && m->AutoTunnelHostAddr.b[0] == 0)
{
m->AutoTunnelHostAddr.b[0x0] = 0xFD; // Required prefix for "locally assigned" ULA (See RFC 4193)
m->AutoTunnelHostAddr.b[0x1] = mDNSRandom(255);
m->AutoTunnelHostAddr.b[0x5] = mDNSRandom(255);
m->AutoTunnelHostAddr.b[0x6] = mDNSRandom(255);
m->AutoTunnelHostAddr.b[0x7] = mDNSRandom(255);
- m->AutoTunnelHostAddr.b[0x8] = PrimaryMAC.b[0] ^ 0x02; // See RFC 3513, Appendix A for explanation
- m->AutoTunnelHostAddr.b[0x9] = PrimaryMAC.b[1];
- m->AutoTunnelHostAddr.b[0xA] = PrimaryMAC.b[2];
+ m->AutoTunnelHostAddr.b[0x8] = m->PrimaryMAC.b[0] ^ 0x02; // See RFC 3513, Appendix A for explanation
+ m->AutoTunnelHostAddr.b[0x9] = m->PrimaryMAC.b[1];
+ m->AutoTunnelHostAddr.b[0xA] = m->PrimaryMAC.b[2];
m->AutoTunnelHostAddr.b[0xB] = 0xFF;
m->AutoTunnelHostAddr.b[0xC] = 0xFE;
- m->AutoTunnelHostAddr.b[0xD] = PrimaryMAC.b[3];
- m->AutoTunnelHostAddr.b[0xE] = PrimaryMAC.b[4];
- m->AutoTunnelHostAddr.b[0xF] = PrimaryMAC.b[5];
+ m->AutoTunnelHostAddr.b[0xD] = m->PrimaryMAC.b[3];
+ m->AutoTunnelHostAddr.b[0xE] = m->PrimaryMAC.b[4];
+ m->AutoTunnelHostAddr.b[0xF] = m->PrimaryMAC.b[5];
m->AutoTunnelLabel.c[0] = mDNS_snprintf((char*)m->AutoTunnelLabel.c+1, 254, "AutoTunnel-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
m->AutoTunnelHostAddr.b[0x8], m->AutoTunnelHostAddr.b[0x9], m->AutoTunnelHostAddr.b[0xA], m->AutoTunnelHostAddr.b[0xB],
m->AutoTunnelHostAddr.b[0xC], m->AutoTunnelHostAddr.b[0xD], m->AutoTunnelHostAddr.b[0xE], m->AutoTunnelHostAddr.b[0xF]);
- LogOperation("m->AutoTunnelLabel %#s", m->AutoTunnelLabel.c);
+ LogInfo("m->AutoTunnelLabel %#s", m->AutoTunnelLabel.c);
}
- GenerateDefaultName(PrimaryMAC, defaultname, sizeof(defaultname));
+ mDNS_snprintf(defaultname, sizeof(defaultname), "%.*s-%02X%02X%02X%02X%02X%02X", HINFO_HWstring_prefixlen, HINFO_HWstring,
+ m->PrimaryMAC.b[0], m->PrimaryMAC.b[1], m->PrimaryMAC.b[2], m->PrimaryMAC.b[3], m->PrimaryMAC.b[4], m->PrimaryMAC.b[5]);
// Set up the nice label
domainlabel nicelabel;
GetUserSpecifiedFriendlyComputerName(&nicelabel);
if (nicelabel.c[0] == 0)
{
- LogMsg("Couldn't read user-specified Computer Name; using default “%s” instead", defaultname);
+ debugf("Couldn’t read user-specified Computer Name; using default “%s” instead", defaultname);
MakeDomainLabelFromLiteralString(&nicelabel, defaultname);
}
GetUserSpecifiedLocalHostName(&hostlabel);
if (hostlabel.c[0] == 0)
{
- LogMsg("Couldn't read user-specified local hostname; using default “%s.local” instead", defaultname);
+ debugf("Couldn’t read user-specified Local Hostname; using default “%s.local” instead", defaultname);
MakeDomainLabelFromLiteralString(&hostlabel, defaultname);
}
else
{
if (m->p->usernicelabel.c[0]) // Don't show message first time through, when we first read name from prefs on boot
- LogMsg("User updated Computer Name from %#s to %#s", m->p->usernicelabel.c, nicelabel.c);
+ LogMsg("User updated Computer Name from “%#s” to “%#s”", m->p->usernicelabel.c, nicelabel.c);
m->p->usernicelabel = m->nicelabel = nicelabel;
namechange = mDNStrue;
}
else
{
if (m->p->userhostlabel.c[0]) // Don't show message first time through, when we first read name from prefs on boot
- LogMsg("User updated Local Hostname from %#s to %#s", m->p->userhostlabel.c, hostlabel.c);
+ LogMsg("User updated Local Hostname from “%#s” to “%#s”", m->p->userhostlabel.c, hostlabel.c);
m->p->userhostlabel = m->hostlabel = hostlabel;
mDNS_SetFQDN(m);
namechange = mDNStrue;
if (info->AutoTunnelNAT.clientContext && !mDNSIPv4AddressIsOnes(info->AutoTunnelNAT.ExternalAddress))
AutoTunnelNATCallback(m, &info->AutoTunnelNAT);
}
-#endif
+#endif // APPLE_OSX_mDNSResponder
return(mStatus_NoError);
}
-#if LogAllOperations || MDNS_DEBUGMSGS
// Returns number of leading one-bits in mask: 0-32 for IPv4, 0-128 for IPv6
// Returns -1 if all the one-bits are not contiguous
mDNSlocal int CountMaskBits(mDNSAddr *mask)
while (i < bytes) if (mask->ip.v6.b[i++]) return(-1);
return(bits);
}
-#endif
// returns count of non-link local V4 addresses registered
mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
if (i->Exists)
{
NetworkInterfaceInfo *const n = &i->ifinfo;
- NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifa_name, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
- if (!primary) LogMsg("SetupActiveInterfaces ERROR! SearchForInterfaceByName didn't find %s", i->ifa_name);
+ NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifinfo.ifname, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
+ if (!primary) LogMsg("SetupActiveInterfaces ERROR! SearchForInterfaceByName didn't find %s", i->ifinfo.ifname);
if (n->InterfaceID && n->InterfaceID != (mDNSInterfaceID)primary) // Sanity check
{
if (!n->InterfaceID)
{
- // NOTE: If n->InterfaceID is set, that means we've called mDNS_RegisterInterface() for this interface,
+ // Note: If n->InterfaceID is set, that means we've called mDNS_RegisterInterface() for this interface,
// so we need to make sure we call mDNS_DeregisterInterface() before disposing it.
// If n->InterfaceID is NOT set, then we haven't registered it and we should not try to deregister it
n->InterfaceID = (mDNSInterfaceID)primary;
i->Occulting = !(i->ifa_flags & IFF_LOOPBACK) && (utc - i->LastSeen > 0 && utc - i->LastSeen < 60);
mDNS_RegisterInterface(m, n, i->Flashing && i->Occulting);
- if (!mDNSAddressIsLinkLocal(&i->ifinfo.ip)) count++;
- LogOperation("SetupActiveInterfaces: Registered %5s(%lu) %.6a InterfaceID %p %#a/%d%s%s%s",
- i->ifa_name, i->scope_id, &i->BSSID, primary, &n->ip, CountMaskBits(&n->mask),
+ if (!mDNSAddressIsLinkLocal(&n->ip)) count++;
+ LogInfo("SetupActiveInterfaces: Registered %5s(%lu) %.6a InterfaceID %p %#a/%d%s%s%s",
+ i->ifinfo.ifname, i->scope_id, &i->BSSID, primary, &n->ip, CountMaskBits(&n->mask),
i->Flashing ? " (Flashing)" : "",
i->Occulting ? " (Occulting)" : "",
n->InterfaceActive ? " (Primary)" : "");
if (!n->McastTxRx)
- debugf("SetupActiveInterfaces: No Tx/Rx on %5s(%lu) %.6a InterfaceID %p %#a", i->ifa_name, i->scope_id, &i->BSSID, primary, &n->ip);
+ debugf("SetupActiveInterfaces: No Tx/Rx on %5s(%lu) %.6a InterfaceID %p %#a", i->ifinfo.ifname, i->scope_id, &i->BSSID, primary, &n->ip);
else
{
if (i->sa_family == AF_INET)
{
struct ip_mreq imr;
- primary->ifa_v4addr.s_addr = i->ifinfo.ip.ip.v4.NotAnInteger;
+ primary->ifa_v4addr.s_addr = n->ip.ip.v4.NotAnInteger;
imr.imr_multiaddr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
imr.imr_interface = primary->ifa_v4addr;
// because by the time we get the configuration change notification, the interface is already gone,
// so attempts to unsubscribe fail with EADDRNOTAVAIL (errno 49 "Can't assign requested address").
// <rdar://problem/5585972> IP_ADD_MEMBERSHIP fails for previously-connected removable interfaces
- if (SearchForInterfaceByName(m, i->ifa_name, AF_INET) == i)
+ if (SearchForInterfaceByName(m, i->ifinfo.ifname, AF_INET) == i)
{
- LogOperation("SetupActiveInterfaces: %5s(%lu) Doing precautionary IP_DROP_MEMBERSHIP for %.4a on %.4a", i->ifa_name, i->scope_id, &imr.imr_multiaddr, &imr.imr_interface);
+ LogInfo("SetupActiveInterfaces: %5s(%lu) Doing precautionary IP_DROP_MEMBERSHIP for %.4a on %.4a", i->ifinfo.ifname, i->scope_id, &imr.imr_multiaddr, &imr.imr_interface);
mStatus err = setsockopt(m->p->permanentsockets.sktv4, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(imr));
- if (err < 0 && (errno != EADDRNOTAVAIL || LogAllOperations))
- LogMsg("setsockopt - IP_DROP_MEMBERSHIP error %ld errno %d (%s)", err, errno, strerror(errno));
+ if (err < 0 && (errno != EADDRNOTAVAIL))
+ LogMsg("setsockopt - IP_DROP_MEMBERSHIP error %d errno %d (%s)", err, errno, strerror(errno));
}
- LogOperation("SetupActiveInterfaces: %5s(%lu) joining IPv4 mcast group %.4a on %.4a", i->ifa_name, i->scope_id, &imr.imr_multiaddr, &imr.imr_interface);
+ LogInfo("SetupActiveInterfaces: %5s(%lu) joining IPv4 mcast group %.4a on %.4a", i->ifinfo.ifname, i->scope_id, &imr.imr_multiaddr, &imr.imr_interface);
mStatus err = setsockopt(m->p->permanentsockets.sktv4, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr));
// Joining same group twice can give "Address already in use" error -- no need to report that
- if (err < 0 && (errno != EADDRINUSE || LogAllOperations))
- LogMsg("setsockopt - IP_ADD_MEMBERSHIP error %ld errno %d (%s) group %.4a on %.4a", err, errno, strerror(errno), &imr.imr_multiaddr, &imr.imr_interface);
+ if (err < 0 && (errno != EADDRINUSE))
+ LogMsg("setsockopt - IP_ADD_MEMBERSHIP error %d errno %d (%s) group %.4a on %.4a", err, errno, strerror(errno), &imr.imr_multiaddr, &imr.imr_interface);
}
#ifndef NO_IPV6
if (i->sa_family == AF_INET6)
i6mr.ipv6mr_interface = primary->scope_id;
i6mr.ipv6mr_multiaddr = *(struct in6_addr*)&AllDNSLinkGroup_v6.ip.v6;
- if (SearchForInterfaceByName(m, i->ifa_name, AF_INET6) == i)
+ if (SearchForInterfaceByName(m, i->ifinfo.ifname, AF_INET6) == i)
{
- LogOperation("SetupActiveInterfaces: %5s(%lu) Doing precautionary IPV6_LEAVE_GROUP for %.16a on %u", i->ifa_name, i->scope_id, &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
+ LogInfo("SetupActiveInterfaces: %5s(%lu) Doing precautionary IPV6_LEAVE_GROUP for %.16a on %u", i->ifinfo.ifname, i->scope_id, &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
mStatus err = setsockopt(m->p->permanentsockets.sktv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &i6mr, sizeof(i6mr));
- if (err < 0 && (errno != EADDRNOTAVAIL || LogAllOperations))
- LogMsg("setsockopt - IPV6_LEAVE_GROUP error %ld errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
+ if (err < 0 && (errno != EADDRNOTAVAIL))
+ LogMsg("setsockopt - IPV6_LEAVE_GROUP error %d errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
}
- LogOperation("SetupActiveInterfaces: %5s(%lu) joining IPv6 mcast group %.16a on %u", i->ifa_name, i->scope_id, &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
+ LogInfo("SetupActiveInterfaces: %5s(%lu) joining IPv6 mcast group %.16a on %u", i->ifinfo.ifname, i->scope_id, &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
mStatus err = setsockopt(m->p->permanentsockets.sktv6, IPPROTO_IPV6, IPV6_JOIN_GROUP, &i6mr, sizeof(i6mr));
// Joining same group twice can give "Address already in use" error -- no need to report that
- if (err < 0 && (errno != EADDRINUSE || LogAllOperations))
- LogMsg("setsockopt - IPV6_JOIN_GROUP error %ld errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
+ if (err < 0 && (errno != EADDRINUSE))
+ LogMsg("setsockopt - IPV6_JOIN_GROUP error %d errno %d (%s) group %.16a on %u", err, errno, strerror(errno), &i6mr.ipv6mr_multiaddr, i6mr.ipv6mr_interface);
}
#endif
}
}
}
+
return count;
}
for (i = m->p->InterfaceList; i; i = i->next)
{
// If this interface is no longer active, or its InterfaceID is changing, deregister it
- NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifa_name, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
+ NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifinfo.ifname, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
if (i->ifinfo.InterfaceID)
if (i->Exists == 0 || i->Exists == 2 || i->ifinfo.InterfaceID != (mDNSInterfaceID)primary)
{
i->Flashing = !(i->ifa_flags & IFF_LOOPBACK) && (utc - i->AppearanceTime < 60);
- LogOperation("ClearInactiveInterfaces: Deregistering %5s(%lu) %.6a InterfaceID %p %#a/%d%s%s%s",
- i->ifa_name, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID,
+ LogInfo("ClearInactiveInterfaces: Deregistering %5s(%lu) %.6a InterfaceID %p %#a/%d%s%s%s",
+ i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID,
&i->ifinfo.ip, CountMaskBits(&i->ifinfo.mask),
i->Flashing ? " (Flashing)" : "",
i->Occulting ? " (Occulting)" : "",
mDNS_DeregisterInterface(m, &i->ifinfo, i->Flashing && i->Occulting);
if (!mDNSAddressIsLinkLocal(&i->ifinfo.ip)) count++;
i->ifinfo.InterfaceID = mDNSNULL;
- // NOTE: If i->ifinfo.InterfaceID is set, that means we've called mDNS_RegisterInterface() for this interface,
+ // Note: If i->ifinfo.InterfaceID is set, that means we've called mDNS_RegisterInterface() for this interface,
// so we need to make sure we call mDNS_DeregisterInterface() before disposing it.
// If i->ifinfo.InterfaceID is NOT set, then it's not registered and we should not call mDNS_DeregisterInterface() on it.
{
if (i->LastSeen == utc) i->LastSeen = utc - 1;
mDNSBool delete = (NumCacheRecordsForInterfaceID(m, (mDNSInterfaceID)i) == 0) && (utc - i->LastSeen >= 60);
- LogOperation("ClearInactiveInterfaces: %-13s %5s(%lu) %.6a InterfaceID %p %#a/%d Age %d%s", delete ? "Deleting" : "Holding",
- i->ifa_name, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID,
+ LogInfo("ClearInactiveInterfaces: %-13s %5s(%lu) %.6a InterfaceID %p %#a/%d Age %d%s", delete ? "Deleting" : "Holding",
+ i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID,
&i->ifinfo.ip, CountMaskBits(&i->ifinfo.mask), utc - i->LastSeen,
i->ifinfo.InterfaceActive ? " (Primary)" : "");
+#if APPLE_OSX_mDNSResponder
+ if (i->BPF_fd >= 0) CloseBPF(i);
+#endif // APPLE_OSX_mDNSResponder
if (delete)
{
*p = i->next;
- if (i->ifa_name) freeL("NetworkInterfaceInfoOSX name", i->ifa_name);
freeL("NetworkInterfaceInfoOSX", i);
continue; // After deleting this object, don't want to do the "p = &i->next;" thing at the end of the loop
}
}
}
+mDNSlocal int compare_dns_configs(const void *aa, const void *bb)
+ {
+ dns_resolver_t *a = *(dns_resolver_t**)aa;
+ dns_resolver_t *b = *(dns_resolver_t**)bb;
+
+ return (a->search_order < b->search_order) ? -1 : (a->search_order == b->search_order) ? 0 : 1;
+ }
+
mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains, DNameListElem **BrowseDomains)
{
int i;
if (RegDomains ) *RegDomains = NULL;
if (BrowseDomains) *BrowseDomains = NULL;
- LogOperation("mDNSPlatformSetDNSConfig%s%s%s%s%s",
- setservers ? " setservers" : "",
- setsearch ? " setsearch" : "",
- fqdn ? " fqdn" : "",
- RegDomains ? " RegDomains" : "",
- BrowseDomains ? " BrowseDomains" : "");
+ LogInfo("mDNSPlatformSetDNSConfig:%s%s%s%s%s",
+ setservers ? " setservers" : "",
+ setsearch ? " setsearch" : "",
+ fqdn ? " fqdn" : "",
+ RegDomains ? " RegDomains" : "",
+ BrowseDomains ? " BrowseDomains" : "");
// Add the inferred address-based configuration discovery domains
// (should really be in core code I think, not platform-specific)
if (setsearch)
{
- struct ifaddrs *ifa = myGetIfAddrs(1);
+ struct ifaddrs *ifa = mDNSNULL;
+ struct sockaddr_in saddr;
+ mDNSPlatformMemZero(&saddr, sizeof(saddr));
+ saddr.sin_len = sizeof(saddr);
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0;
+ saddr.sin_addr.s_addr = *(in_addr_t *)&m->Router.ip.v4;
+
+ // Don't add any reverse-IP search domains if doing the WAB bootstrap queries would cause dial-on-demand connection initiation
+ if (!AddrRequiresPPPConnection((struct sockaddr *)&saddr)) ifa = myGetIfAddrs(1);
+
while (ifa)
{
mDNSAddr a, n;
// Apparently this is expected behaviour -- "not a bug".
// Accordingly, we suppress syslog messages for the first three minutes after boot.
// If we are still getting failures after three minutes, then we log them.
- if (mDNSMacOSXSystemBuildNumber(NULL) > 7 && (mDNSu32)mDNSPlatformRawTime() > (mDNSu32)(mDNSPlatformOneSecond * 180))
- LogMsg("GetDNSConfig: Error: dns_configuration_copy returned NULL");
+ if (OSXVers > OSXVers_10_3_Panther && (mDNSu32)mDNSPlatformRawTime() > (mDNSu32)(mDNSPlatformOneSecond * 180))
+ LogMsg("mDNSPlatformSetDNSConfig: Error: dns_configuration_copy returned NULL");
}
else
{
- LogOperation("mDNSPlatformSetDNSConfig: config->n_resolver = %d", config->n_resolver);
+ LogInfo("mDNSPlatformSetDNSConfig: config->n_resolver = %d", config->n_resolver);
+ if (setsearch && config->n_resolver)
+ {
+ // Due to the vagaries of Apple's SystemConfiguration and dnsinfo.h APIs, if there are no search domains
+ // listed, then you're supposed to interpret the "domain" field as also being the search domain, but if
+ // there *are* search domains listed, then you're supposed to ignore the "domain" field completely and
+ // instead use the search domain list as the sole authority for what domains to search and in what order
+ // (and the domain from the "domain" field will also appear somewhere in that list).
+ // Also, all search domains get added to the search list for resolver[0], so the domains and/or
+ // search lists for other resolvers in the list need to be ignored.
+ if (config->resolver[0]->n_search == 0) mDNS_AddSearchDomain_CString(config->resolver[0]->domain);
+ else for (i = 0; i < config->resolver[0]->n_search; i++) mDNS_AddSearchDomain_CString(config->resolver[0]->search[i]);
+ }
+
+#if APPLE_OSX_mDNSResponder
+ // Record the so-called "primary" domain, which we use as a hint to tell if the user is on a network set up
+ // by someone using Microsoft Active Directory using "local" as a private internal top-level domain
+ if (config->n_resolver && config->resolver[0]->domain && config->resolver[0]->n_nameserver && config->resolver[0]->nameserver[0])
+ MakeDomainNameFromDNSNameString(&ActiveDirectoryPrimaryDomain, config->resolver[0]->domain);
+ else ActiveDirectoryPrimaryDomain.c[0] = 0;
+ //MakeDomainNameFromDNSNameString(&ActiveDirectoryPrimaryDomain, "test.local");
+ ActiveDirectoryPrimaryDomainLabelCount = CountLabels(&ActiveDirectoryPrimaryDomain);
+ if (config->n_resolver && config->resolver[0]->n_nameserver && SameDomainName(SkipLeadingLabels(&ActiveDirectoryPrimaryDomain, ActiveDirectoryPrimaryDomainLabelCount - 1), &localdomain))
+ SetupAddr(&ActiveDirectoryPrimaryDomainServer, config->resolver[0]->nameserver[0]);
+ else
+ {
+ AssignDomainName(&ActiveDirectoryPrimaryDomain, (const domainname *)"");
+ ActiveDirectoryPrimaryDomainLabelCount = 0;
+ ActiveDirectoryPrimaryDomainServer = zeroAddr;
+ }
+#endif
+
if (setservers)
{
+ // For the "default" resolver ("resolver #1") the "domain" value is bogus and we need to ignore it.
+ // e.g. the default resolver's "domain" value might say "apple.com", which indicates that this resolver
+ // is only for names that fall under "apple.com", but that's not correct. Actually the default resolver is
+ // for all names not covered by a more specific resolver (i.e. its domain should be ".", the root domain).
+ if (config->n_resolver && config->resolver[0]->domain)
+ config->resolver[0]->domain[0] = 0; // don't stop pointing at the memory, just change the first byte
+
+ qsort(config->resolver, config->n_resolver, sizeof(dns_resolver_t*), compare_dns_configs);
+
for (i = 0; i < config->n_resolver; i++)
{
- int j, n;
+ int n;
dns_resolver_t *r = config->resolver[i];
- // Ignore dnsinfo entries for mDNS domains (indicated by the fact that the resolver port is 5353, the mDNS port)
+ mDNSInterfaceID interface = mDNSInterface_Any;
+ int disabled = 0;
+
+ // On Tiger, dnsinfo entries for mDNS domains have port 5353, the mDNS port. Ignore them.
// Note: Unlike the BSD Sockets APIs (where TCP and UDP port numbers are universally in network byte order)
// in Apple's "dnsinfo.h" API the port number is declared to be a "uint16_t in host byte order"
- if (r->port == 5353) continue;
- if (r->search_order == DEFAULT_SEARCH_ORDER || !r->domain || !*r->domain) d.c[0] = 0; // we ignore domain for "default" resolver
- else if (!MakeDomainNameFromDNSNameString(&d, r->domain)) { LogMsg("RegisterSplitDNS: bad domain %s", r->domain); continue; }
-
- for (j = 0; j < config->n_resolver; j++) // check if this is the lowest-weighted server for the domain
+ // We also don't need to do any more work if there are no nameserver addresses
+ if (r->port == 5353 || r->n_nameserver == 0) continue;
+
+ if (!r->domain || !*r->domain) d.c[0] = 0;
+ else if (!MakeDomainNameFromDNSNameString(&d, r->domain)) { LogMsg("mDNSPlatformSetDNSConfig: bad domain %s", r->domain); continue; }
+
+ // DNS server option parsing
+ if (r->options != NULL)
{
- dns_resolver_t *p = config->resolver[j];
- if (p->port == 5353) continue; // Note: dns_resolver_t port is defined to be "uint16_t in host byte order"
- if (p->search_order <= r->search_order)
+ char *nextOption = r->options;
+ char *currentOption = NULL;
+ while ((currentOption = strsep(&nextOption, " ")) != NULL && currentOption[0] != 0)
{
- domainname tmp;
- if (p->search_order == DEFAULT_SEARCH_ORDER || !p->domain || !*p->domain) tmp.c[0] = '\0';
- else if (!MakeDomainNameFromDNSNameString(&tmp, p->domain)) { LogMsg("RegisterSplitDNS: bad domain %s", p->domain); continue; }
- if (SameDomainName(&d, &tmp))
- if (p->search_order < r->search_order || j < i) break; // if equal weights, pick first in list, otherwise pick lower-weight (p)
+ // The option may be in the form of interface=xxx where xxx is an interface name.
+ if (strncmp(currentOption, kInterfaceSpecificOption, sizeof(kInterfaceSpecificOption) - 1) == 0)
+ {
+ NetworkInterfaceInfoOSX *ni;
+ char ifname[IF_NAMESIZE+1];
+ mDNSu32 ifindex = 0;
+ // If something goes wrong finding the interface, create the server entry anyhow but mark it as disabled.
+ // This allows us to block these special queries from going out on the wire.
+ strlcpy(ifname, currentOption + sizeof(kInterfaceSpecificOption)-1, sizeof(ifname));
+ ifindex = if_nametoindex(ifname);
+ if (ifindex == 0) { disabled = 1; LogMsg("RegisterSplitDNS: interfaceSpecific - interface %s not found", ifname); continue; }
+ LogInfo("%s: Interface-specific entry: %s on %s (%d)", __FUNCTION__, r->domain, ifname, ifindex);
+ // Find the interface, can't use mDNSPlatformInterfaceIDFromInterfaceIndex
+ // because that will call mDNSMacOSXNetworkChanged if the interface doesn't exist
+ for (ni = m->p->InterfaceList; ni; ni = ni->next)
+ if (ni->ifinfo.InterfaceID && ni->scope_id == ifindex) break;
+ if (ni != NULL) interface = ni->ifinfo.InterfaceID;
+ if (interface == mDNSNULL) { disabled = 1; LogMsg("RegisterSplitDNS: interfaceSpecific - index %d (%s) not found", ifindex, ifname); continue; }
+ }
}
}
- if (j < config->n_resolver) // found a lower-weighted resolver for this domain
- debugf("Rejecting DNS server in slot %d domain %##s (slot %d outranks)", i, d.c, j);
- else
- {
- mDNSInterfaceID interface = mDNSInterface_Any;
- int disabled = 0;
-
- // DNS server option parsing
- if (r->options != NULL)
+
+ for (n = 0; n < r->n_nameserver; n++)
+ if (r->nameserver[n]->sa_family == AF_INET || r->nameserver[n]->sa_family == AF_INET6)
{
- char *nextOption = r->options;
- char *currentOption = NULL;
- while ((currentOption = strsep(&nextOption, " ")) != NULL && currentOption[0] != 0)
+ mDNSAddr saddr;
+ // mDNSAddr saddr = { mDNSAddrType_IPv4, { { { 192, 168, 1, 1 } } } }; // for testing
+ if (SetupAddr(&saddr, r->nameserver[n])) LogMsg("RegisterSplitDNS: bad IP address");
+ else
{
- // The option may be in the form of interface=xxx where xxx is an interface name.
- if (strncmp(currentOption, kInterfaceSpecificOption, sizeof(kInterfaceSpecificOption) - 1) == 0)
+ DNSServer *s = mDNS_AddDNSServer(m, &d, interface, &saddr, r->port ? mDNSOpaque16fromIntVal(r->port) : UnicastDNSPort);
+ if (s)
{
- NetworkInterfaceInfoOSX *ni;
- char ifname[IF_NAMESIZE+1];
- mDNSu32 ifindex = 0;
- // If something goes wrong finding the interface, create the server entry anyhow but mark it as disabled.
- // This allows us to block these special queries from going out on the wire.
- strlcpy(ifname, currentOption + sizeof(kInterfaceSpecificOption)-1, sizeof(ifname));
- ifindex = if_nametoindex(ifname);
- if (ifindex == 0) { disabled = 1; LogMsg("RegisterSplitDNS: interfaceSpecific - interface %s not found", ifname); continue; }
- LogOperation("%s: Interface-specific entry: %s on %s (%d)", __FUNCTION__, r->domain, ifname, ifindex);
- // Find the interface, can't use mDNSPlatformInterfaceIDFromInterfaceIndex
- // because that will call mDNSMacOSXNetworkChanged if the interface doesn't exist
- for (ni = m->p->InterfaceList; ni; ni = ni->next)
- if (ni->ifinfo.InterfaceID && ni->scope_id == ifindex) break;
- if (ni != NULL) interface = ni->ifinfo.InterfaceID;
- if (interface == mDNSNULL) { disabled = 1; LogMsg("RegisterSplitDNS: interfaceSpecific - index %d (%s) not found", ifindex, ifname); continue; }
+ if (disabled) s->teststate = DNSServer_Disabled;
+ LogInfo("Added dns server %#a:%d for domain %##s from slot %d,%d", &s->addr, mDNSVal16(s->port), d.c, i, n);
}
}
}
- for (n = 0; n < r->n_nameserver; n++)
- if (r->nameserver[n]->sa_family == AF_INET && (interface || disabled || !AddrRequiresPPPConnection(r->nameserver[n])))
- {
- mDNSAddr saddr;
- // mDNSAddr saddr = { mDNSAddrType_IPv4, { { { 192, 168, 1, 1 } } } }; // for testing
- debugf("Adding dns server from slot %d %#a for domain %##s", i, &saddr, d.c);
- if (SetupAddr(&saddr, r->nameserver[n])) LogMsg("RegisterSplitDNS: bad IP address");
- else
- {
- DNSServer *s = mDNS_AddDNSServer(m, &d, interface, &saddr, r->port ? mDNSOpaque16fromIntVal(r->port) : UnicastDNSPort);
- if (s && disabled) s->teststate = DNSServer_Disabled;
- }
- }
- }
+
}
}
- if (setsearch)
- {
- // Due to the vagaries of Apple's SystemConfiguration and dnsinfo.h APIs, if there are no search domains
- // listed, then you're supposed to interpret the "domain" field as also being the search domain, but if
- // there *are* search domains listed, then you're supposed to ignore the "domain" field completely and
- // instead use the search domain list as the sole authority for what domains to search and in what order
- // (and the domain from the "domain" field will also appear somewhere in that list).
- // Also, all search domains get added to the search list for resolver[0], so the domains and/or
- // search lists for other resolvers in the list need to be ignored.
- if (config->resolver[0]->n_search == 0) mDNS_AddSearchDomain_CString(config->resolver[0]->domain);
- else for (i = 0; i < config->resolver[0]->n_search; i++) mDNS_AddSearchDomain_CString(config->resolver[0]->search[i]);
- }
+
dns_configuration_free(config);
setservers = mDNSfalse; // Done these now -- no need to fetch the same data from SCDynamicStore
setsearch = mDNSfalse;
#endif // MDNS_NO_DNSINFO
SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:mDNSPlatformSetDNSConfig"), NULL, NULL);
- if (store)
+ if (!store)
+ LogMsg("mDNSPlatformSetDNSConfig: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
+ else
{
CFDictionaryRef ddnsdict = SCDynamicStoreCopyValue(store, NetworkChangedKey_DynamicDNS);
if (ddnsdict)
{
// for now, we only look at the first array element. if we ever support multiple configurations, we will walk the list
CFDictionaryRef fqdnDict = CFArrayGetValueAtIndex(fqdnArray, 0);
- if (fqdnDict && DDNSSettingEnabled(fqdnDict))
+ if (fqdnDict && DictionaryIsEnabled(fqdnDict))
{
CFStringRef name = CFDictionaryGetValue(fqdnDict, CFSTR("Domain"));
if (name)
if (regArray && CFArrayGetCount(regArray) > 0)
{
CFDictionaryRef regDict = CFArrayGetValueAtIndex(regArray, 0);
- if (regDict && DDNSSettingEnabled(regDict))
+ if (regDict && DictionaryIsEnabled(regDict))
{
CFStringRef name = CFDictionaryGetValue(regDict, CFSTR("Domain"));
if (name)
for (i = 0; i < CFArrayGetCount(browseArray); i++)
{
CFDictionaryRef browseDict = CFArrayGetValueAtIndex(browseArray, i);
- if (browseDict && DDNSSettingEnabled(browseDict))
+ if (browseDict && DictionaryIsEnabled(browseDict))
{
CFStringRef name = CFDictionaryGetValue(browseDict, CFSTR("Domain"));
if (name)
CFDictionaryGetKeysAndValues(btmm, key, val);
for (i = 0; i < size; i++)
{
- LogOperation("BackToMyMac %d", i);
+ LogInfo("BackToMyMac %d", i);
if (!CFStringGetCString(key[i], buf, sizeof(buf), kCFStringEncodingUTF8))
LogMsg("Can't read BackToMyMac %d key %s", i, buf);
else
LogMsg("Can't read BackToMyMac %d val %s", i, buf);
else if (MakeDomainNameFromDNSNameString(&d, buf) && d.c[0])
{
- LogOperation("BackToMyMac %d %d %##s", i, uid, d.c);
+ LogInfo("BackToMyMac %d %d %##s", i, uid, d.c);
AppendDNameListElem(&RegDomains, uid, &d);
}
}
CFArrayRef values = CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses);
if (values)
{
+ LogInfo("DNS Server Address values: %d", CFArrayGetCount(values));
for (i = 0; i < CFArrayGetCount(values); i++)
{
CFStringRef s = CFArrayGetValueAtIndex(values, i);
mDNSAddr addr = { mDNSAddrType_IPv4, { { { 0 } } } };
if (s && CFStringGetCString(s, buf, 256, kCFStringEncodingUTF8) &&
inet_aton(buf, (struct in_addr *) &addr.ip.v4))
+ {
+ LogInfo("Adding DNS server from dict: %s", buf);
mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, &addr, UnicastDNSPort);
+ }
}
}
+ else LogInfo("No DNS Server Address values");
}
if (setsearch)
{
(void)m; // Unused
SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:mDNSPlatformGetPrimaryInterface"), NULL, NULL);
- if (!store) LogMsg("mDNSPlatformGetPrimaryInterface: SCDynamicStoreCreate failed");
+ if (!store)
+ LogMsg("mDNSPlatformGetPrimaryInterface: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
else
{
CFDictionaryRef dict = SCDynamicStoreCopyValue(store, NetworkChangedKey_IPv4);
saddr.sin_port = 0;
inet_aton(buf, &saddr.sin_addr);
- if (AddrRequiresPPPConnection((struct sockaddr *)&saddr)) debugf("Ignoring router %s (requires PPP connection)", buf);
- else *(in_addr_t *)&r->ip.v4 = saddr.sin_addr.s_addr;
+ *(in_addr_t *)&r->ip.v4 = saddr.sin_addr.s_addr;
}
}
mDNSexport void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
{
- LogOperation("mDNSPlatformDynDNSHostNameStatusChanged %d %##s", status, dname->c);
+ LogInfo("mDNSPlatformDynDNSHostNameStatusChanged %d %##s", status, dname->c);
char uname[MAX_ESCAPED_DOMAIN_NAME]; // Max legal C-string name, including terminating NUL
ConvertDomainNameToCString(dname, uname);
else
{
const CFNumberRef StatusVals[1] = { CFNumberCreate(NULL, kCFNumberSInt32Type, &status) };
- if (!StatusVals[0]) LogMsg("SetDDNSNameStatus: CFNumberCreate(%ld) failed", status);
+ if (!StatusVals[0]) LogMsg("SetDDNSNameStatus: CFNumberCreate(%d) failed", status);
else
{
- const CFDictionaryRef HostVals[1] = { CFDictionaryCreate(NULL, (void*)StatusKeys, (void*)StatusVals, 1, NULL, NULL) };
+ const CFDictionaryRef HostVals[1] = { CFDictionaryCreate(NULL, (void*)StatusKeys, (void*)StatusVals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) };
if (HostVals[0])
{
- const CFDictionaryRef StateVals[1] = { CFDictionaryCreate(NULL, (void*)HostKeys, (void*)HostVals, 1, NULL, NULL) };
+ const CFDictionaryRef StateVals[1] = { CFDictionaryCreate(NULL, (void*)HostKeys, (void*)HostVals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) };
if (StateVals[0])
{
- CFDictionaryRef StateDict = CFDictionaryCreate(NULL, (void*)StateKeys, (void*)StateVals, 1, NULL, NULL);
+ CFDictionaryRef StateDict = CFDictionaryCreate(NULL, (void*)StateKeys, (void*)StateVals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (StateDict)
{
- mDNSDynamicStoreSetConfig(kmDNSDynamicConfig, StateDict);
+ mDNSDynamicStoreSetConfig(kmDNSDynamicConfig, mDNSNULL, StateDict);
CFRelease(StateDict);
}
CFRelease(StateVals[0]);
#else
mDNSBool haveAutoTunnels = mDNSfalse;
- LogOperation("SetDomainSecrets");
+ LogInfo("SetDomainSecrets");
// Rather than immediately deleting all keys now, we mark them for deletion in ten seconds.
// In the case where the user simultaneously removes their DDNS host name and the key
ClientTunnel *client;
for (client = m->TunnelClients; client; client = client->next)
{
- LogOperation("SetDomainSecrets: tunnel to %##s marked for deletion", client->dstname.c);
+ LogInfo("SetDomainSecrets: tunnel to %##s marked for deletion", client->dstname.c);
client->MarkedForDeletion = mDNStrue;
}
}
-#endif APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
// String Array used to write list of private domains to Dynamic Store
CFMutableArrayRef sa = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
for (client = m->TunnelClients; client; client = client->next)
if (FoundInList == GetAuthInfoForName_internal(m, &client->dstname))
{
- LogOperation("SetDomainSecrets: tunnel to %##s no longer marked for deletion", client->dstname.c);
+ LogInfo("SetDomainSecrets: tunnel to %##s no longer marked for deletion", client->dstname.c);
client->MarkedForDeletion = mDNSfalse;
- // If the key has changed, reconfigure the tunnel
- if (strncmp(stringbuf, client->b64keydata, sizeof(client->b64keydata)))
- {
- mDNSBool queryNotInProgress = client->q.ThisQInterval < 0;
- LogOperation("SetDomainSecrets: secret changed for tunnel %##s %s", client->dstname.c, queryNotInProgress ? "reconfiguring" : "query in progress");
- if (queryNotInProgress) AutoTunnelSetKeys(client, mDNSfalse);
- mDNS_snprintf(client->b64keydata, sizeof(client->b64keydata), "%s", stringbuf);
- if (queryNotInProgress) AutoTunnelSetKeys(client, mDNStrue);
- }
}
}
- mDNSBool keyChanged = FoundInList && FoundInList->AutoTunnel ? strncmp(stringbuf, FoundInList->b64keydata, sizeof(FoundInList->b64keydata)) : mDNSfalse;
-
-#endif APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
// Uncomment the line below to view the keys as they're read out of the system keychain
// DO NOT SHIP CODE THIS WAY OR YOU'LL LEAK SECRET DATA INTO A PUBLICLY READABLE FILE!
- //LogOperation("SetDomainSecrets: %##s %##s %s", &domain.c, &keyname.c, stringbuf);
+ //LogInfo("SetDomainSecrets: %##s %##s %s", &domain.c, &keyname.c, stringbuf);
// If didn't find desired domain in the list, make a new entry
ptr = FoundInList;
if (!ptr) { LogMsg("SetDomainSecrets: No memory"); continue; }
}
- LogOperation("SetDomainSecrets: %d of %d %##s", i, ArrayCount, &domain);
+ LogInfo("SetDomainSecrets: %d of %d %##s", i, ArrayCount, &domain);
if (mDNS_SetSecretForDomain(m, ptr, &domain, &keyname, stringbuf, IsTunnelModeDomain(&domain)) == mStatus_BadParamErr)
{
if (!FoundInList) mDNSPlatformMemFree(ptr); // If we made a new DomainAuthInfo here, and it turned out bad, dispose it immediately
}
#if APPLE_OSX_mDNSResponder
- if (keyChanged && AnonymousRacoonConfig)
- {
- LogOperation("SetDomainSecrets: secret changed for %##s", &domain);
- (void)mDNSConfigureServer(kmDNSUp, stringbuf);
- }
-
if (ptr->AutoTunnel) UpdateAutoTunnelDomainStatus(m, ptr);
-#endif APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
ConvertDomainNameToCString(&domain, stringbuf);
CFStringRef cfs = CFStringCreateWithCString(NULL, stringbuf, kCFStringEncodingUTF8);
}
CFRelease(secrets);
}
- mDNSDynamicStoreSetConfig(kmDNSPrivateConfig, sa);
+ mDNSDynamicStoreSetConfig(kmDNSPrivateConfig, mDNSNULL, sa);
CFRelease(sa);
- #if APPLE_OSX_mDNSResponder
+#if APPLE_OSX_mDNSResponder
{
// clean up ClientTunnels
ClientTunnel **pp = &m->TunnelClients;
if ((*pp)->MarkedForDeletion)
{
ClientTunnel *cur = *pp;
- LogOperation("SetDomainSecrets: removing client %p %##s from list", cur, cur->dstname.c);
+ LogInfo("SetDomainSecrets: removing client %p %##s from list", cur, cur->dstname.c);
if (cur->q.ThisQInterval >= 0) mDNS_StopQuery(m, &cur->q);
AutoTunnelSetKeys(cur, mDNSfalse);
*pp = cur->next;
freeL("ClientTunnel", cur);
}
- else
+ else
pp = &(*pp)->next;
}
}
info->AutoTunnelNAT.clientContext = mDNSNULL;
}
- RemoveAutoTunnelDomainStatus(info);
+ RemoveAutoTunnelDomainStatus(m, info);
}
info = info->next;
}
if (!haveAutoTunnels && !m->TunnelClients && m->AutoTunnelHostAddrActive)
{
// remove interface if no autotunnel servers and no more client tunnels
- LogOperation("SetDomainSecrets: Bringing tunnel interface DOWN");
+ LogInfo("SetDomainSecrets: Bringing tunnel interface DOWN");
m->AutoTunnelHostAddrActive = mDNSfalse;
(void)mDNSAutoTunnelInterfaceUpDown(kmDNSDown, m->AutoTunnelHostAddr.b);
- memset(m->AutoTunnelHostAddr.b, 0, sizeof(m->AutoTunnelHostAddr.b));
- }
-
- if (!haveAutoTunnels && AnonymousRacoonConfig)
- {
- LogMsg("SetDomainSecrets: Resetting AnonymousRacoonConfig to false");
- AnonymousRacoonConfig = mDNSfalse;
- (void)mDNSConfigureServer(kmDNSDown, "");
+ mDNSPlatformMemZero(m->AutoTunnelHostAddr.b, sizeof(m->AutoTunnelHostAddr.b));
}
+ UpdateConfigureServer(m);
+
if (m->AutoTunnelHostAddr.b[0])
if (TunnelClients(m) || TunnelServers(m))
SetupLocalAutoTunnelInterface_internal(m);
}
- #endif APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
#endif /* NO_SECURITYFRAMEWORK */
}
CFArrayAppendValue(sa, CFSTR("a.e.f.ip6.arpa"));
CFArrayAppendValue(sa, CFSTR("b.e.f.ip6.arpa"));
- mDNSDynamicStoreSetConfig(kmDNSMulticastConfig, sa);
+ mDNSDynamicStoreSetConfig(kmDNSMulticastConfig, mDNSNULL, sa);
CFRelease(sa);
}
+mDNSlocal void GetCurrentPMSetting(const CFStringRef name, mDNSs32 *val)
+ {
+#if USE_IOPMCOPYACTIVEPMPREFERENCES
+ CFTypeRef blob = NULL;
+ CFStringRef str = NULL;
+ CFDictionaryRef odict = NULL;
+ CFDictionaryRef idict = NULL;
+ CFNumberRef number = NULL;
+
+ blob = IOPSCopyPowerSourcesInfo();
+ if (!blob) { LogMsg("GetCurrentPMSetting: IOPSCopyPowerSourcesInfo failed!"); goto end; }
+
+ odict = IOPMCopyActivePMPreferences();
+ if (!odict) { LogMsg("GetCurrentPMSetting: IOPMCopyActivePMPreferences failed!"); goto end; }
+
+ str = IOPSGetProvidingPowerSourceType(blob);
+ if (!str) { LogMsg("GetCurrentPMSetting: IOPSGetProvidingPowerSourceType failed!"); goto end; }
+
+ idict = CFDictionaryGetValue(odict, str);
+ if (!idict)
+ {
+ char buf[256];
+ if (!CFStringGetCString(str, buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
+ LogMsg("GetCurrentPMSetting: CFDictionaryGetValue (%s) failed!", buf);
+ goto end;
+ }
+
+ number = CFDictionaryGetValue(idict, name);
+ if (!number || CFGetTypeID(number) != CFNumberGetTypeID() || !CFNumberGetValue(number, kCFNumberSInt32Type, val))
+ *val = 0;
+end:
+ if (blob) CFRelease(blob);
+ if (odict) CFRelease(odict);
+
+#else
+
+ SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:GetCurrentPMSetting"), NULL, NULL);
+ if (!store) LogMsg("GetCurrentPMSetting: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
+ else
+ {
+ CFDictionaryRef dict = SCDynamicStoreCopyValue(store, CFSTR("State:/IOKit/PowerManagement/CurrentSettings"));
+ if (!dict) LogSPS("GetCurrentPMSetting: Could not get IOPM CurrentSettings dict");
+ else
+ {
+ CFNumberRef number = CFDictionaryGetValue(dict, name);
+ if (!number || CFGetTypeID(number) != CFNumberGetTypeID() || !CFNumberGetValue(number, kCFNumberSInt32Type, val))
+ *val = 0;
+ CFRelease(dict);
+ }
+ CFRelease(store);
+ }
+
+#endif
+ }
+
+#if APPLE_OSX_mDNSResponder
+
+static CFMutableDictionaryRef spsStatusDict = NULL;
+static const CFStringRef kMetricRef = CFSTR("Metric");
+
+mDNSlocal void SPSStatusPutNumber(CFMutableDictionaryRef dict, const mDNSu8* const ptr, CFStringRef key)
+ {
+ mDNSu8 tmp = (ptr[0] - '0') * 10 + ptr[1] - '0';
+ CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt8Type, &tmp);
+ if (!num)
+ LogMsg("SPSStatusPutNumber: Could not create CFNumber");
+ else
+ {
+ CFDictionarySetValue(dict, key, num);
+ CFRelease(num);
+ }
+ }
+
+mDNSlocal CFMutableDictionaryRef SPSCreateDict(const mDNSu8* const ptr)
+ {
+ CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (!dict) { LogMsg("SPSCreateDict: Could not create CFDictionary dict"); return dict; }
+
+ char buffer[1024];
+ buffer[mDNS_snprintf(buffer, sizeof(buffer), "%##s", ptr) - 1] = 0;
+ CFStringRef spsname = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!spsname) { LogMsg("SPSCreateDict: Could not create CFString spsname full"); CFRelease(dict); return NULL; }
+ CFDictionarySetValue(dict, CFSTR("FullName"), spsname);
+ CFRelease(spsname);
+
+ if (ptr[0] >= 2) SPSStatusPutNumber(dict, ptr + 1, CFSTR("Type"));
+ if (ptr[0] >= 5) SPSStatusPutNumber(dict, ptr + 4, CFSTR("Portability"));
+ if (ptr[0] >= 8) SPSStatusPutNumber(dict, ptr + 7, CFSTR("MarginalPower"));
+ if (ptr[0] >= 11) SPSStatusPutNumber(dict, ptr +10, CFSTR("TotalPower"));
+
+ mDNSu32 tmp = SPSMetric(ptr);
+ CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt32Type, &tmp);
+ if (!num)
+ LogMsg("SPSCreateDict: Could not create CFNumber");
+ else
+ {
+ CFDictionarySetValue(dict, kMetricRef, num);
+ CFRelease(num);
+ }
+
+ if (ptr[0] >= 12)
+ {
+ memcpy(buffer, ptr + 13, ptr[0] - 12);
+ buffer[ptr[0] - 12] = 0;
+ spsname = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!spsname) { LogMsg("SPSCreateDict: Could not create CFString spsname"); CFRelease(dict); return NULL; }
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("PrettyName"), spsname);
+ CFRelease(spsname);
+ }
+ }
+
+ return dict;
+ }
+
+mDNSlocal CFComparisonResult CompareSPSEntries(const void *val1, const void *val2, void *context)
+ {
+ (void)context;
+ return CFNumberCompare((CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)val1, kMetricRef),
+ (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)val2, kMetricRef),
+ NULL);
+ }
+
+mDNSlocal void UpdateSPSStatus(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
+ {
+ (void)m;
+ NetworkInterfaceInfo* info = (NetworkInterfaceInfo*)question->QuestionContext;
+ debugf("UpdateSPSStatus: %s %##s %s %s", info->ifname, question->qname.c, AddRecord ? "Add" : "Rmv", answer ? RRDisplayString(m, answer) : "<null>");
+
+ if (answer && SPSMetric(answer->rdata->u.name.c) > 999999) return; // Ignore instances with invalid names
+
+ if (!spsStatusDict)
+ {
+ spsStatusDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (!spsStatusDict) { LogMsg("UpdateSPSStatus: Could not create CFDictionary spsStatusDict"); return; }
+ }
+
+ CFStringRef ifname = CFStringCreateWithCString(NULL, info->ifname, kCFStringEncodingUTF8);
+ if (!ifname) { LogMsg("UpdateSPSStatus: Could not create CFString ifname"); return; }
+
+ CFMutableArrayRef array = NULL;
+
+ if (!CFDictionaryGetValueIfPresent(spsStatusDict, ifname, (const void**) &array))
+ {
+ array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ if (!array) { LogMsg("UpdateSPSStatus: Could not create CFMutableArray"); CFRelease(ifname); return; }
+ CFDictionarySetValue(spsStatusDict, ifname, array);
+ CFRelease(array); // let go of our reference, now that the dict has one
+ }
+ else
+ if (!array) { LogMsg("UpdateSPSStatus: Could not get CFMutableArray for %s", info->ifname); CFRelease(ifname); return; }
+
+ if (!answer) // special call that means the question has been stopped (because the interface is going away)
+ CFArrayRemoveAllValues(array);
+ else
+ {
+ CFMutableDictionaryRef dict = SPSCreateDict(answer->rdata->u.name.c);
+ if (!dict) { CFRelease(ifname); return; }
+
+ if (AddRecord)
+ {
+ if (!CFArrayContainsValue(array, CFRangeMake(0, CFArrayGetCount(array)), dict))
+ {
+ int i=0;
+ for (i=0; i<CFArrayGetCount(array); i++)
+ if (CompareSPSEntries(CFArrayGetValueAtIndex(array, i), dict, NULL) != kCFCompareLessThan)
+ break;
+ CFArrayInsertValueAtIndex(array, i, dict);
+ }
+ else LogMsg("UpdateSPSStatus: %s array already contains %##s", info->ifname, answer->rdata->u.name.c);
+ }
+ else
+ {
+ CFIndex i = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), dict);
+ if (i != -1) CFArrayRemoveValueAtIndex(array, i);
+ else LogMsg("UpdateSPSStatus: %s array does not contain %##s", info->ifname, answer->rdata->u.name.c);
+ }
+
+ CFRelease(dict);
+ }
+
+ if (!m->ShutdownTime) mDNSDynamicStoreSetConfig(kmDNSSleepProxyServersState, info->ifname, array);
+
+ CFRelease(ifname);
+ }
+
+mDNSlocal mDNSs32 GetSystemSleepTimerSetting(void)
+ {
+ mDNSs32 val = -1;
+ SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder:GetSystemSleepTimerSetting"), NULL, NULL);
+ if (!store)
+ LogMsg("GetSystemSleepTimerSetting: SCDynamicStoreCreate failed: %s", SCErrorString(SCError()));
+ else
+ {
+ CFDictionaryRef dict = SCDynamicStoreCopyValue(store, CFSTR("State:/IOKit/PowerManagement/CurrentSettings"));
+ if (dict)
+ {
+ CFNumberRef number = CFDictionaryGetValue(dict, CFSTR("System Sleep Timer"));
+ if (number) CFNumberGetValue(number, kCFNumberSInt32Type, &val);
+ CFRelease(dict);
+ }
+ CFRelease(store);
+ }
+ return val;
+ }
+
+mDNSlocal void SetSPS(mDNS *const m)
+ {
+ SCPreferencesSynchronize(m->p->SCPrefs);
+ CFDictionaryRef dict = SCPreferencesGetValue(m->p->SCPrefs, CFSTR("NAT"));
+ mDNSBool natenabled = (dict && (CFGetTypeID(dict) == CFDictionaryGetTypeID()) && DictionaryIsEnabled(dict));
+ mDNSu8 sps = natenabled ? 50 : (OfferSleepProxyService && GetSystemSleepTimerSetting() == 0) ? OfferSleepProxyService : 0;
+
+ // For devices that are not running NAT, but are set to never sleep, we may choose to act
+ // as a Sleep Proxy, but only for non-portable Macs (Portability > 35 means nominal weight < 3kg)
+ if (sps > 50 && SPMetricPortability > 35) sps = 0;
+
+ // If we decide to let laptops act as Sleep Proxy, we should do it only when running on AC power, not on battery
+
+ // For devices that are unable to sleep at all to save power (e.g. the current Apple TV hardware)
+ // it makes sense for them to offer low-priority Sleep Proxy service on the network.
+ // We rate such a device as metric 70 ("Incidentally Available Hardware")
+ if (SPMetricMarginalPower == 10 && (!sps || sps > 70)) sps = 70;
+
+ mDNSCoreBeSleepProxyServer(m, sps, SPMetricPortability, SPMetricMarginalPower, SPMetricTotalPower);
+ }
+
+mDNSlocal void InternetSharingChanged(SCPreferencesRef prefs, SCPreferencesNotification notificationType, void *context)
+ {
+ (void)prefs; // Parameter not used
+ (void)notificationType; // Parameter not used
+ mDNS *const m = (mDNS *const)context;
+ KQueueLock(m);
+ mDNS_Lock(m);
+
+ // Tell platform layer to open or close its BPF fds
+ if (!m->p->NetworkChanged ||
+ m->p->NetworkChanged - NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2) < 0)
+ {
+ m->p->NetworkChanged = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2);
+ LogInfo("InternetSharingChanged: Set NetworkChanged to %d (%d)", m->p->NetworkChanged - m->timenow, m->p->NetworkChanged);
+ }
+
+ mDNS_Unlock(m);
+ KQueueUnlock(m, "InternetSharingChanged");
+ }
+
+mDNSlocal mStatus WatchForInternetSharingChanges(mDNS *const m)
+ {
+ SCPreferencesRef SCPrefs = SCPreferencesCreate(NULL, CFSTR("mDNSResponder:WatchForInternetSharingChanges"), CFSTR("com.apple.nat.plist"));
+ if (!SCPrefs) { LogMsg("SCPreferencesCreate failed: %s", SCErrorString(SCError())); return(mStatus_NoMemoryErr); }
+
+ SCPreferencesContext context = { 0, m, NULL, NULL, NULL };
+ if (!SCPreferencesSetCallback(SCPrefs, InternetSharingChanged, &context))
+ { LogMsg("SCPreferencesSetCallback failed: %s", SCErrorString(SCError())); CFRelease(SCPrefs); return(mStatus_NoMemoryErr); }
+
+ if (!SCPreferencesScheduleWithRunLoop(SCPrefs, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
+ { LogMsg("SCPreferencesScheduleWithRunLoop failed: %s", SCErrorString(SCError())); CFRelease(SCPrefs); return(mStatus_NoMemoryErr); }
+
+ m->p->SCPrefs = SCPrefs;
+ return(mStatus_NoError);
+ }
+
+#endif // APPLE_OSX_mDNSResponder
+
+static io_service_t g_rootdomain = MACH_PORT_NULL;
+
+mDNSlocal mDNSBool SystemWakeForNetworkAccess(void)
+ {
+ mDNSs32 val = 0;
+ CFBooleanRef clamshellStop = NULL;
+ mDNSBool retnow = mDNSfalse;
+
+ GetCurrentPMSetting(CFSTR("Wake On LAN"), &val);
+ LogSPS("SystemWakeForNetworkAccess: Wake On LAN: %d", val);
+ if (!val) return mDNSfalse;
+
+ if (!g_rootdomain) g_rootdomain = IORegistryEntryFromPath(MACH_PORT_NULL, kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
+ if (!g_rootdomain) { LogMsg("SystemWakeForNetworkAccess: IORegistryEntryFromPath failed; assuming no clamshell so can WOMP"); return mDNStrue; }
+
+ clamshellStop = (CFBooleanRef)IORegistryEntryCreateCFProperty(g_rootdomain, CFSTR(kAppleClamshellStateKey), kCFAllocatorDefault, 0);
+ if (!clamshellStop) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellStateKey does not exist; assuming no clamshell so can WOMP"); return mDNStrue; }
+ retnow = clamshellStop == kCFBooleanFalse;
+ CFRelease(clamshellStop);
+ if (retnow) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellStateKey is false; clamshell is open so can WOMP"); return mDNStrue; }
+
+ clamshellStop = (CFBooleanRef)IORegistryEntryCreateCFProperty(g_rootdomain, CFSTR(kAppleClamshellCausesSleepKey), kCFAllocatorDefault, 0);
+ if (!clamshellStop) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellCausesSleepKey does not exist; assuming no clamshell so can WOMP"); return mDNStrue; }
+ retnow = clamshellStop == kCFBooleanFalse;
+ CFRelease(clamshellStop);
+ if (retnow) { LogSPS("SystemWakeForNetworkAccess: kAppleClamshellCausesSleepKey is false; clamshell is closed but can WOMP"); return mDNStrue; }
+
+ LogSPS("SystemWakeForNetworkAccess: clamshell is closed and can't WOMP");
+ return mDNSfalse;
+ }
+
mDNSexport void mDNSMacOSXNetworkChanged(mDNS *const m)
{
- LogOperation("*** Network Configuration Change *** (%d)%s",
+ LogInfo("*** Network Configuration Change *** (%d)%s",
m->p->NetworkChanged ? mDNS_TimeNow(m) - m->p->NetworkChanged : 0,
m->p->NetworkChanged ? "" : " (no scheduled configuration change)");
m->p->NetworkChanged = 0; // If we received a network change event and deferred processing, we're now dealing with it
mDNSs32 utc = mDNSPlatformUTC();
+ m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
MarkAllInterfacesInactive(m, utc);
UpdateInterfaceList(m, utc);
ClearInactiveInterfaces(m, utc);
SetupActiveInterfaces(m, utc);
- #if APPLE_OSX_mDNSResponder
+#if APPLE_OSX_mDNSResponder
+
+ if (m->AutoTunnelHostAddr.b[0])
{
- if (m->AutoTunnelHostAddr.b[0])
+ mDNS_Lock(m);
+ if (TunnelClients(m) || TunnelServers(m))
+ SetupLocalAutoTunnelInterface_internal(m);
+ mDNS_Unlock(m);
+ }
+
+ // Scan to find client tunnels whose questions have completed,
+ // but whose local inner/outer addresses have changed since the tunnel was set up
+ ClientTunnel *p;
+ for (p = m->TunnelClients; p; p = p->next)
+ if (p->q.ThisQInterval < 0)
{
- mDNS_Lock(m);
- if (TunnelClients(m) || TunnelServers(m))
- SetupLocalAutoTunnelInterface_internal(m);
- mDNS_Unlock(m);
- }
-
- // Scan to find client tunnels whose questions have completed,
- // but whose local inner/outer addresses have changed since the tunnel was set up
- ClientTunnel *p;
- for (p = m->TunnelClients; p; p = p->next)
- if (p->q.ThisQInterval < 0)
+ mDNSAddr tmpSrc = zeroAddr;
+ mDNSAddr tmpDst = { mDNSAddrType_IPv4, {{{0}}} };
+ tmpDst.ip.v4 = p->rmt_outer;
+ mDNSPlatformSourceAddrForDest(&tmpSrc, &tmpDst);
+ if (!mDNSSameIPv6Address(p->loc_inner, m->AutoTunnelHostAddr) ||
+ !mDNSSameIPv4Address(p->loc_outer, tmpSrc.ip.v4))
{
- mDNSAddr tmpSrc = zeroAddr;
- mDNSAddr tmpDst = { mDNSAddrType_IPv4, {{{0}}} };
- tmpDst.ip.v4 = p->rmt_outer;
- mDNSPlatformSourceAddrForDest(&tmpSrc, &tmpDst);
- if (!mDNSSameIPv6Address(p->loc_inner, m->AutoTunnelHostAddr) ||
- !mDNSSameIPv4Address(p->loc_outer, tmpSrc.ip.v4))
- {
- AutoTunnelSetKeys(p, mDNSfalse);
- p->loc_inner = m->AutoTunnelHostAddr;
- p->loc_outer = tmpSrc.ip.v4;
- AutoTunnelSetKeys(p, mDNStrue);
- }
+ AutoTunnelSetKeys(p, mDNSfalse);
+ p->loc_inner = m->AutoTunnelHostAddr;
+ p->loc_outer = tmpSrc.ip.v4;
+ AutoTunnelSetKeys(p, mDNStrue);
}
+ }
+
+ SetSPS(m);
+
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ {
+ if (!m->SPSSocket) // Not being Sleep Proxy Server; close any open BPF fds
+ {
+ if (i->BPF_fd >= 0 && CountProxyTargets(m, i, mDNSNULL, mDNSNULL) == 0) CloseBPF(i);
+ }
+ else // else, we're Sleep Proxy Server; open BPF fds
+ {
+ if (i->Exists && i->ifinfo.InterfaceID == (mDNSInterfaceID)i && !(i->ifa_flags & IFF_LOOPBACK) && i->BPF_fd == -1)
+ { LogSPS("%s requesting BPF", i->ifinfo.ifname); i->BPF_fd = -2; mDNSRequestBPF(); }
+ }
}
- #endif APPLE_OSX_mDNSResponder
+
+#endif // APPLE_OSX_mDNSResponder
uDNS_SetupDNSConfig(m);
+ mDNS_ConfigChanged(m);
+ }
- if (m->MainCallback)
- m->MainCallback(m, mStatus_ConfigChanged);
+// Called with KQueueLock & mDNS lock
+mDNSlocal void SetNetworkChanged(mDNS *const m, mDNSs32 delay)
+ {
+ if (!m->p->NetworkChanged || m->p->NetworkChanged - NonZeroTime(m->timenow + delay) < 0)
+ {
+ m->p->NetworkChanged = NonZeroTime(m->timenow + delay);
+ LogInfo("SetNetworkChanged: setting network changed to %d (%d)", delay, m->p->NetworkChanged);
+ }
}
+
mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
{
(void)store; // Parameter not used
- (void)changedKeys; // Parameter not used
mDNS *const m = (mDNS *const)context;
KQueueLock(m);
mDNS_Lock(m);
- mDNSs32 delay = mDNSPlatformOneSecond; // Start off assuming a one-second delay
+ mDNSs32 delay = mDNSPlatformOneSecond * 2; // Start off assuming a two-second delay
int c = CFArrayGetCount(changedKeys); // Count changes
CFRange range = { 0, c };
int c1 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Hostnames ) != 0);
int c2 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_Computername) != 0);
int c3 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DynamicDNS ) != 0);
- if (c && c - c1 - c2 - c3 == 0) delay = mDNSPlatformOneSecond/20; // If these were the only changes, shorten delay
+ int c4 = (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS ) != 0);
+ if (c && c - c1 - c2 - c3 - c4 == 0) delay = mDNSPlatformOneSecond/10; // If these were the only changes, shorten delay
-#if LogAllOperations
- int i;
- for (i=0; i<c; i++)
+ if (mDNS_LoggingEnabled)
{
- char buf[256];
- if (!CFStringGetCString(CFArrayGetValueAtIndex(changedKeys, i), buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
- LogOperation("*** NetworkChanged SC key: %s", buf);
- }
- LogOperation("*** NetworkChanged *** %d change%s %s%s%sdelay %d",
- c, c>1?"s":"",
- c1 ? "(Local Hostname) " : "",
- c2 ? "(Computer Name) " : "",
- c3 ? "(DynamicDNS) " : "",
- delay);
-#endif
-
- if (!m->p->NetworkChanged ||
- m->p->NetworkChanged - NonZeroTime(m->timenow + delay) < 0)
- m->p->NetworkChanged = NonZeroTime(m->timenow + delay);
-
- // If we have a global DNS change, then disregard delay and reconfigure immediately
- if (CFArrayContainsValue(changedKeys, range, NetworkChangedKey_DNS) != 0) m->p->NetworkChanged = NonZeroTime(m->timenow);
+ int i;
+ for (i=0; i<c; i++)
+ {
+ char buf[256];
+ if (!CFStringGetCString(CFArrayGetValueAtIndex(changedKeys, i), buf, sizeof(buf), kCFStringEncodingUTF8)) buf[0] = 0;
+ LogInfo("*** NetworkChanged SC key: %s", buf);
+ }
+ LogInfo("*** NetworkChanged *** %d change%s %s%s%s%sdelay %d",
+ c, c>1?"s":"",
+ c1 ? "(Local Hostname) " : "",
+ c2 ? "(Computer Name) " : "",
+ c3 ? "(DynamicDNS) " : "",
+ c4 ? "(DNS) " : "",
+ delay);
+ }
+ SetNetworkChanged(m, delay);
+
// KeyChain frequently fails to notify clients of change events. To work around this
// we set a timer and periodically poll to detect if any changes have occurred.
// Without this Back To My Mac just does't work for a large number of users.
// See <rdar://problem/5124399> Not getting Keychain Changed events when enabling BTMM
if (c3 || CFArrayContainsValue(changedKeys, range, NetworkChangedKey_BackToMyMac))
{
- LogOperation("*** NetworkChanged *** starting KeyChainBugTimer");
+ LogInfo("*** NetworkChanged *** starting KeyChainBugTimer");
m->p->KeyChainBugTimer = NonZeroTime(m->timenow + delay);
m->p->KeyChainBugInterval = mDNSPlatformOneSecond;
}
- if (!m->SuppressSending ||
- m->SuppressSending - m->p->NetworkChanged < 0)
- m->SuppressSending = m->p->NetworkChanged;
-
mDNS_Unlock(m);
+
+ // If DNS settings changed, immediately force a reconfig (esp. cache flush)
+ if (c4) mDNSMacOSXNetworkChanged(m);
+
KQueueUnlock(m, "NetworkChanged");
}
CFArrayAppendValue(keys, NetworkChangedKey_DNS);
CFArrayAppendValue(keys, NetworkChangedKey_DynamicDNS);
CFArrayAppendValue(keys, NetworkChangedKey_BackToMyMac);
+ CFArrayAppendValue(keys, CFSTR("State:/IOKit/PowerManagement/CurrentSettings")); // should remove as part of <rdar://problem/6751656>
CFArrayAppendValue(patterns, pattern1);
CFArrayAppendValue(patterns, pattern2);
CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/[^/]+/AirPort"));
return(err);
}
+#if 0 // <rdar://problem/6751656>
+mDNSlocal void PMChanged(void *context)
+ {
+ mDNS *const m = (mDNS *const)context;
+
+ KQueueLock(m);
+ mDNS_Lock(m);
+
+ LogSPS("PMChanged");
+
+ SetNetworkChanged(m, mDNSPlatformOneSecond * 2);
+
+ mDNS_Unlock(m);
+ KQueueUnlock(m, "PMChanged");
+ }
+
+mDNSlocal mStatus WatchForPMChanges(mDNS *const m)
+ {
+ m->p->PMRLS = IOPMPrefsNotificationCreateRunLoopSource(PMChanged, m);
+ if (!m->p->PMRLS) { LogMsg("IOPMPrefsNotificationCreateRunLoopSource failed!"); return mStatus_UnknownErr; }
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), m->p->PMRLS, kCFRunLoopDefaultMode);
+
+ return mStatus_NoError;
+ }
+#endif
+
+#ifndef KEV_DL_WAKEFLAGS_CHANGED
+#define KEV_DL_WAKEFLAGS_CHANGED 17
+#endif
+
+mDNSlocal void SysEventCallBack(int s1, short __unused filter, void *context)
+ {
+ mDNS *const m = (mDNS *const)context;
+
+ mDNS_Lock(m);
+
+ struct { struct kern_event_msg k; char extra[256]; } msg;
+ int bytes = recv(s1, &msg, sizeof(msg), 0);
+ if (bytes < 0)
+ LogMsg("SysEventCallBack: recv error %d errno %d (%s)", bytes, errno, strerror(errno));
+ else
+ {
+ LogInfo("SysEventCallBack got %d bytes size %d %X %s %X %s %X %s id %d code %d %s",
+ bytes, msg.k.total_size,
+ msg.k.vendor_code , msg.k.vendor_code == KEV_VENDOR_APPLE ? "KEV_VENDOR_APPLE" : "?",
+ msg.k.kev_class , msg.k.kev_class == KEV_NETWORK_CLASS ? "KEV_NETWORK_CLASS" : "?",
+ msg.k.kev_subclass, msg.k.kev_subclass == KEV_DL_SUBCLASS ? "KEV_DL_SUBCLASS" : "?",
+ msg.k.id, msg.k.event_code,
+ msg.k.event_code == KEV_DL_SIFFLAGS ? "KEV_DL_SIFFLAGS" :
+ msg.k.event_code == KEV_DL_SIFMETRICS ? "KEV_DL_SIFMETRICS" :
+ msg.k.event_code == KEV_DL_SIFMTU ? "KEV_DL_SIFMTU" :
+ msg.k.event_code == KEV_DL_SIFPHYS ? "KEV_DL_SIFPHYS" :
+ msg.k.event_code == KEV_DL_SIFMEDIA ? "KEV_DL_SIFMEDIA" :
+ msg.k.event_code == KEV_DL_SIFGENERIC ? "KEV_DL_SIFGENERIC" :
+ msg.k.event_code == KEV_DL_ADDMULTI ? "KEV_DL_ADDMULTI" :
+ msg.k.event_code == KEV_DL_DELMULTI ? "KEV_DL_DELMULTI" :
+ msg.k.event_code == KEV_DL_IF_ATTACHED ? "KEV_DL_IF_ATTACHED" :
+ msg.k.event_code == KEV_DL_IF_DETACHING ? "KEV_DL_IF_DETACHING" :
+ msg.k.event_code == KEV_DL_IF_DETACHED ? "KEV_DL_IF_DETACHED" :
+ msg.k.event_code == KEV_DL_LINK_OFF ? "KEV_DL_LINK_OFF" :
+ msg.k.event_code == KEV_DL_LINK_ON ? "KEV_DL_LINK_ON" :
+ msg.k.event_code == KEV_DL_PROTO_ATTACHED ? "KEV_DL_PROTO_ATTACHED" :
+ msg.k.event_code == KEV_DL_PROTO_DETACHED ? "KEV_DL_PROTO_DETACHED" :
+ msg.k.event_code == KEV_DL_LINK_ADDRESS_CHANGED ? "KEV_DL_LINK_ADDRESS_CHANGED" :
+ msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED ? "KEV_DL_WAKEFLAGS_CHANGED" : "?");
+
+ if (msg.k.event_code == KEV_DL_WAKEFLAGS_CHANGED) SetNetworkChanged(m, mDNSPlatformOneSecond * 2);
+ }
+
+ mDNS_Unlock(m);
+ }
+
+mDNSlocal mStatus WatchForSysEvents(mDNS *const m)
+ {
+ m->p->SysEventNotifier = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
+ if (m->p->SysEventNotifier < 0)
+ { LogMsg("WatchForNetworkChanges: socket failed %s errno %d (%s)", errno, strerror(errno)); return(mStatus_NoMemoryErr); }
+
+ struct kev_request kev_req = { KEV_VENDOR_APPLE, KEV_NETWORK_CLASS, KEV_DL_SUBCLASS };
+ int err = ioctl(m->p->SysEventNotifier, SIOCSKEVFILT, &kev_req);
+ if (err < 0)
+ {
+ LogMsg("WatchForNetworkChanges: SIOCSKEVFILT failed %s errno %d (%s)", errno, strerror(errno));
+ close(m->p->SysEventNotifier);
+ m->p->SysEventNotifier = -1;
+ return(mStatus_UnknownErr);
+ }
+
+ m->p->SysEventKQueue.KQcallback = SysEventCallBack;
+ m->p->SysEventKQueue.KQcontext = m;
+ m->p->SysEventKQueue.KQtask = "System Event Notifier";
+ KQueueSet(m->p->SysEventNotifier, EV_ADD, EVFILT_READ, &m->p->SysEventKQueue);
+
+ return(mStatus_NoError);
+ }
+
#ifndef NO_SECURITYFRAMEWORK
mDNSlocal OSStatus KeychainChanged(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void *context)
{
- LogOperation("*** Keychain Changed ***");
+ LogInfo("*** Keychain Changed ***");
mDNS *const m = (mDNS *const)context;
SecKeychainRef skc;
OSStatus err = SecKeychainCopyDefault(&skc);
}
if (relevant)
{
- LogMsg("*** Keychain Changed *** KeychainEvent=%d %s",
+ LogInfo("*** Keychain Changed *** KeychainEvent=%d %s",
keychainEvent,
- keychainEvent == kSecAddEvent ? "kSecAddEvent" :
- keychainEvent == kSecDeleteEvent ? "kSecDeleteEvent" :
- keychainEvent == kSecUpdateEvent ? "kSecUpdateEvent" : "<Unknown>");
+ keychainEvent == kSecAddEvent ? "kSecAddEvent" :
+ keychainEvent == kSecDeleteEvent ? "kSecDeleteEvent" :
+ keychainEvent == kSecUpdateEvent ? "kSecUpdateEvent" : "<Unknown>");
// We're running on the CFRunLoop (Mach port) thread, not the kqueue thread, so we need to grab the KQueueLock before proceeding
KQueueLock(m);
mDNS_Lock(m);
#endif
#ifndef NO_IOPOWER
+mDNSlocal void PowerOn(mDNS *const m)
+ {
+ mDNSCoreMachineSleep(m, false); // Will set m->SleepState = SleepState_Awake;
+ if (m->p->WakeAtUTC)
+ {
+ long utc = mDNSPlatformUTC();
+ mDNSPowerRequest(-1,-1); // Need to explicitly clear any previous power requests -- they're not cleared automatically on wake
+ if (m->p->WakeAtUTC - utc > 30) LogInfo("PowerChanged PowerOn %d seconds early, assuming not maintenance wake", m->p->WakeAtUTC - utc);
+ else if (utc - m->p->WakeAtUTC > 30) LogInfo("PowerChanged PowerOn %d seconds late, assuming not maintenance wake", utc - m->p->WakeAtUTC);
+ else
+ {
+ mDNSs32 i = 20;
+ //int result = mDNSPowerRequest(0, i);
+ //if (result == kIOReturnNotReady) do i += (i<20) ? 1 : ((i+3)/4); while (mDNSPowerRequest(0, i) == kIOReturnNotReady);
+ LogMsg("PowerChanged: Waking for network maintenance operations %d seconds early; re-sleeping in %d seconds", m->p->WakeAtUTC - utc, i);
+ m->p->RequestReSleep = mDNS_TimeNow(m) + i * mDNSPlatformOneSecond;
+ }
+ }
+ }
+
mDNSlocal void PowerChanged(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
{
mDNS *const m = (mDNS *const)refcon;
KQueueLock(m);
(void)service; // Parameter not used
- LogOperation("PowerChanged %X %lX", messageType, messageArgument);
+ debugf("PowerChanged %X %lX", messageType, messageArgument);
+
+ // Make sure our m->SystemWakeOnLANEnabled value correctly reflects the current system setting
+ m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
+
switch(messageType)
{
- case kIOMessageCanSystemPowerOff: debugf ("PowerChanged kIOMessageCanSystemPowerOff (no action)"); break; // E0000240
- case kIOMessageSystemWillPowerOff: LogOperation("PowerChanged kIOMessageSystemWillPowerOff");
- mDNSCoreMachineSleep(m, true); mDNSMacOSXNetworkChanged(m); break; // E0000250
- case kIOMessageSystemWillNotPowerOff: debugf ("PowerChanged kIOMessageSystemWillNotPowerOff (no action)"); break; // E0000260
- case kIOMessageCanSystemSleep: debugf ("PowerChanged kIOMessageCanSystemSleep (no action)"); break; // E0000270
- case kIOMessageSystemWillSleep: LogOperation("PowerChanged kIOMessageSystemWillSleep");
- mDNSCoreMachineSleep(m, true); mDNSMacOSXNetworkChanged(m); break; // E0000280
- case kIOMessageSystemWillNotSleep: debugf ("PowerChanged kIOMessageSystemWillNotSleep (no action)"); break; // E0000290
- case kIOMessageSystemHasPoweredOn: LogOperation("PowerChanged kIOMessageSystemHasPoweredOn");
+ case kIOMessageCanSystemPowerOff: LogInfo("PowerChanged kIOMessageCanSystemPowerOff (no action)"); break; // E0000240
+ case kIOMessageSystemWillPowerOff: LogInfo("PowerChanged kIOMessageSystemWillPowerOff"); // E0000250
+ mDNSCoreMachineSleep(m, true);
+ if (m->SleepState == SleepState_Sleeping) mDNSMacOSXNetworkChanged(m);
+ break;
+ case kIOMessageSystemWillNotPowerOff: LogInfo("PowerChanged kIOMessageSystemWillNotPowerOff (no action)"); break; // E0000260
+ case kIOMessageCanSystemSleep: LogInfo("PowerChanged kIOMessageCanSystemSleep (no action)"); break; // E0000270
+ case kIOMessageSystemWillSleep: LogInfo("PowerChanged kIOMessageSystemWillSleep"); // E0000280
+ mDNSCoreMachineSleep(m, true);
+ break;
+ case kIOMessageSystemWillNotSleep: LogInfo("PowerChanged kIOMessageSystemWillNotSleep (no action)"); break; // E0000290
+ case kIOMessageSystemHasPoweredOn: LogInfo("PowerChanged kIOMessageSystemHasPoweredOn"); // E0000300
// If still sleeping (didn't get 'WillPowerOn' message for some reason?) wake now
- if (m->SleepState) mDNSCoreMachineSleep(m, false);
- // Just to be safe, also make sure our interface list is fully up to date, in case we
- // haven't yet received the System Configuration Framework "network changed" event that
- // we expect to receive some time shortly after the kIOMessageSystemWillPowerOn message
- mDNSMacOSXNetworkChanged(m); break; // E0000300
- case kIOMessageSystemWillRestart: debugf ("PowerChanged kIOMessageSystemWillRestart (no action)"); break; // E0000310
- case kIOMessageSystemWillPowerOn: LogOperation("PowerChanged kIOMessageSystemWillPowerOn");
+ if (m->SleepState)
+ {
+ LogMsg("PowerChanged kIOMessageSystemHasPoweredOn: ERROR m->SleepState %d", m->SleepState);
+ PowerOn(m);
+ }
+ // Just to be safe, schedule a mDNSMacOSXNetworkChanged(), in case we never received
+ // the System Configuration Framework "network changed" event that we expect
+ // to receive some time shortly after the kIOMessageSystemWillPowerOn message
+ mDNS_Lock(m);
+ if (!m->p->NetworkChanged ||
+ m->p->NetworkChanged - NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2) < 0)
+ m->p->NetworkChanged = NonZeroTime(m->timenow + mDNSPlatformOneSecond * 2);
+ mDNS_Unlock(m);
+
+ break;
+ case kIOMessageSystemWillRestart: LogInfo("PowerChanged kIOMessageSystemWillRestart (no action)"); break; // E0000310
+ case kIOMessageSystemWillPowerOn: LogInfo("PowerChanged kIOMessageSystemWillPowerOn"); // E0000320
+
+ // On Leopard and earlier, on wake from sleep, instead of reporting link state down, Apple
+ // Ethernet drivers report "hardware incapable of detecting link state", which the kernel
+ // interprets as "should assume we have networking", which results in the first 4-5 seconds
+ // of packets vanishing into a black hole. To work around this, on wake from sleep,
+ // we block for five seconds to let Ethernet come up, and then resume normal operation.
+ if (OSXVers < OSXVers_10_6_SnowLeopard)
+ {
+ sleep(5);
+ LogMsg("Running on Mac OS X version 10.%d earlier than 10.6; "
+ "PowerChanged did sleep(5) to wait for Ethernet hardware", OSXVers - OSXVers_Base);
+ }
+
// Make sure our interface list is cleared to the empty state, then tell mDNSCore to wake
- mDNSMacOSXNetworkChanged(m); mDNSCoreMachineSleep(m, false); break; // E0000320
- default: LogOperation("PowerChanged unknown message %X", messageType); break;
+ if (m->SleepState != SleepState_Sleeping)
+ {
+ LogMsg("kIOMessageSystemWillPowerOn: ERROR m->SleepState %d", m->SleepState);
+ m->SleepState = SleepState_Sleeping;
+ mDNSMacOSXNetworkChanged(m);
+ }
+ PowerOn(m);
+ break;
+ default: LogInfo("PowerChanged unknown message %X", messageType); break;
}
- if (!m->p->SleepLimit && messageType == kIOMessageSystemWillSleep)
+ if (messageType == kIOMessageSystemWillSleep) m->p->SleepCookie = (long)messageArgument;
+ else IOAllowPowerChange(m->p->PowerConnection, (long)messageArgument);
+
+ KQueueUnlock(m, "PowerChanged Sleep/Wake");
+ }
+
+#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+mDNSlocal void SnowLeopardPowerChanged(void *refcon, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities eventDescriptor)
+ {
+ mDNS *const m = (mDNS *const)refcon;
+ KQueueLock(m);
+ LogSPS("SnowLeopardPowerChanged %X %X %X%s%s%s%s%s",
+ connection, token, eventDescriptor,
+ eventDescriptor & kIOPMSystemPowerStateCapabilityCPU ? " CPU" : "",
+ eventDescriptor & kIOPMSystemPowerStateCapabilityVideo ? " Video" : "",
+ eventDescriptor & kIOPMSystemPowerStateCapabilityAudio ? " Audio" : "",
+ eventDescriptor & kIOPMSystemPowerStateCapabilityNetwork ? " Network" : "",
+ eventDescriptor & kIOPMSystemPowerStateCapabilityDisk ? " Disk" : "");
+
+ // Make sure our m->SystemWakeOnLANEnabled value correctly reflects the current system setting
+ m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
+
+ if (eventDescriptor & kIOPMSystemPowerStateCapabilityCPU)
{
- m->p->SleepLimit = NonZeroTime(mDNS_TimeNow(m) + mDNSPlatformOneSecond * 5);
- m->p->SleepCookie = (long)messageArgument;
+ // CPU Waking. Note: Can get this message repeatedly, as other subsystems power up or down.
+ if (m->SleepState == SleepState_Sleeping) PowerOn(m);
+ IOPMConnectionAcknowledgeEvent(connection, token);
}
else
- IOAllowPowerChange(m->p->PowerConnection, (long)messageArgument);
+ {
+ // CPU sleeping. Should not get this repeatedly -- once we're told that the CPU is halting
+ // we should hear nothing more until we're told that the CPU has started executing again.
+ if (m->SleepState) LogMsg("SnowLeopardPowerChanged: Sleep Error %X m->SleepState %d", eventDescriptor, m->SleepState);
+ //sleep(5);
+ //mDNSMacOSXNetworkChanged(m);
+ mDNSCoreMachineSleep(m, true);
+ //if (m->SleepState == SleepState_Sleeping) mDNSMacOSXNetworkChanged(m);
+ m->p->SleepCookie = token;
+ }
- KQueueUnlock(m, "Sleep/Wake");
+ KQueueUnlock(m, "SnowLeopardPowerChanged Sleep/Wake");
}
+#endif
+
#endif /* NO_IOPOWER */
#if COMPILER_LIKES_PRAGMA_MARK
CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
-// Major version 6 is 10.2.x (Jaguar)
-// Major version 7 is 10.3.x (Panther)
-// Major version 8 is 10.4.x (Tiger)
+// Major version 6 is 10.2.x (Jaguar)
+// Major version 7 is 10.3.x (Panther)
+// Major version 8 is 10.4.x (Tiger)
+// Major version 9 is 10.5.x (Leopard)
+// Major version 10 is 10.6.x (SnowLeopard)
mDNSexport int mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring)
{
int major = 0, minor = 0;
CFStringRef cfbuildver = CFDictionaryGetValue(vers, _kCFSystemVersionBuildVersionKey);
if (cfprodname) CFStringGetCString(cfprodname, prodname, sizeof(prodname), kCFStringEncodingUTF8);
if (cfprodvers) CFStringGetCString(cfprodvers, prodvers, sizeof(prodvers), kCFStringEncodingUTF8);
- if (cfbuildver) CFStringGetCString(cfbuildver, buildver, sizeof(buildver), kCFStringEncodingUTF8);
- sscanf(buildver, "%d%c%d", &major, &letter, &minor);
+ if (cfbuildver && CFStringGetCString(cfbuildver, buildver, sizeof(buildver), kCFStringEncodingUTF8))
+ sscanf(buildver, "%d%c%d", &major, &letter, &minor);
CFRelease(vers);
}
if (!major) { major=8; LogMsg("Note: No Major Build Version number found; assuming 8"); }
mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
{
mStatus err;
+ m->p->CFRunLoop = CFRunLoopGetCurrent();
+
+ char HINFO_SWstring[256] = "";
+ OSXVers = mDNSMacOSXSystemBuildNumber(HINFO_SWstring);
// In 10.4, mDNSResponder is launched very early in the boot process, while other subsystems are still in the process of starting up.
// If we can't read the user's preferences, then we sleep a bit and try again, for up to five seconds before we give up.
m->hostlabel.c[0] = 0;
- char *HINFO_HWstring = "Macintosh";
- char HINFO_HWstring_buffer[256];
int get_model[2] = { CTL_HW, HW_MODEL };
size_t len_model = sizeof(HINFO_HWstring_buffer);
- if (sysctl(get_model, 2, HINFO_HWstring_buffer, &len_model, NULL, 0) == 0)
+ // Names that contain no commas are prototype model names, so we ignore those
+ if (sysctl(get_model, 2, HINFO_HWstring_buffer, &len_model, NULL, 0) == 0 && strchr(HINFO_HWstring_buffer, ','))
HINFO_HWstring = HINFO_HWstring_buffer;
+ HINFO_HWstring_prefixlen = strcspn(HINFO_HWstring, "0123456789");
- char HINFO_SWstring[256] = "";
- if (mDNSMacOSXSystemBuildNumber(HINFO_SWstring) < 7) m->KnownBugs |= mDNS_KnownBug_PhantomInterfaces;
- if (mDNSPlatformInit_CanReceiveUnicast()) m->CanReceiveUnicastOn5353 = mDNStrue;
+ if (OSXVers < OSXVers_10_3_Panther ) m->KnownBugs |= mDNS_KnownBug_PhantomInterfaces;
+ if (OSXVers >= OSXVers_10_6_SnowLeopard ) m->KnownBugs |= mDNS_KnownBug_LossySyslog;
+ if (mDNSPlatformInit_CanReceiveUnicast()) m->CanReceiveUnicastOn5353 = mDNStrue;
mDNSu32 hlen = mDNSPlatformStrLen(HINFO_HWstring);
mDNSu32 slen = mDNSPlatformStrLen(HINFO_SWstring);
m->p->usernicelabel.c[0] = 0;
m->p->NotifyUser = 0;
m->p->KeyChainBugTimer = 0;
- m->p->SleepLimit = 0;
+ m->p->WakeAtUTC = 0;
+ m->p->RequestReSleep = 0;
+
+#if APPLE_OSX_mDNSResponder
+ uuid_generate(m->asl_uuid);
+#endif
m->AutoTunnelHostAddr.b[0] = 0; // Zero out AutoTunnelHostAddr so UpdateInterfaceList() know it has to set it up
- mDNSs32 utc = mDNSPlatformUTC();
- UpdateInterfaceList(m, utc);
- SetupActiveInterfaces(m, utc);
-
NetworkChangedKey_IPv4 = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
NetworkChangedKey_IPv6 = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6);
NetworkChangedKey_Hostnames = SCDynamicStoreKeyCreateHostNames(NULL);
err = WatchForNetworkChanges(m);
if (err) { LogMsg("mDNSPlatformInit_setup: WatchForNetworkChanges failed %d", err); return(err); }
+#if 0 // <rdar://problem/6751656>
+ err = WatchForPMChanges(m);
+ if (err) { LogMsg("mDNSPlatformInit_setup: WatchForPMChanges failed %d", err); return(err); }
+#endif
+
+ err = WatchForSysEvents(m);
+ if (err) { LogMsg("mDNSPlatformInit_setup: WatchForSysEvents failed %d", err); return(err); }
+
+ mDNSs32 utc = mDNSPlatformUTC();
+ m->SystemWakeOnLANEnabled = SystemWakeForNetworkAccess();
+ UpdateInterfaceList(m, utc);
+ SetupActiveInterfaces(m, utc);
+
// Explicitly ensure that our Keychain operations utilize the system domain.
#ifndef NO_SECURITYFRAMEWORK
SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
#endif
#ifndef NO_IOPOWER
- m->p->PowerConnection = IORegisterForSystemPower(m, &m->p->PowerPortRef, PowerChanged, &m->p->PowerNotifier);
- if (!m->p->PowerConnection) { LogMsg("mDNSPlatformInit_setup: IORegisterForSystemPower failed"); return(-1); }
- else CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(m->p->PowerPortRef), kCFRunLoopDefaultMode);
+
+#ifndef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+ LogMsg("Note: Compiled without SnowLeopard Fine-Grained Power Management support");
+#else
+ IOPMConnection c;
+ IOReturn iopmerr = IOPMConnectionCreate(CFSTR("mDNSResponder"), kIOPMSystemPowerStateCapabilityCPU, &c);
+ if (iopmerr) LogMsg("IOPMConnectionCreate failed %d", iopmerr);
+ else
+ {
+ iopmerr = IOPMConnectionSetNotification(c, m, SnowLeopardPowerChanged);
+ if (iopmerr) LogMsg("IOPMConnectionSetNotification failed %d", iopmerr);
+ else
+ {
+ iopmerr = IOPMConnectionScheduleWithRunLoop(c, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ if (iopmerr) LogMsg("IOPMConnectionScheduleWithRunLoop failed %d", iopmerr);
+ }
+ }
+ m->p->IOPMConnection = iopmerr ? mDNSNULL : c;
+ if (iopmerr) // If IOPMConnectionCreate unavailable or failed, proceed with old-style power notification code below
+#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+ {
+ m->p->PowerConnection = IORegisterForSystemPower(m, &m->p->PowerPortRef, PowerChanged, &m->p->PowerNotifier);
+ if (!m->p->PowerConnection) { LogMsg("mDNSPlatformInit_setup: IORegisterForSystemPower failed"); return(-1); }
+ else CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(m->p->PowerPortRef), kCFRunLoopDefaultMode);
+ }
#endif /* NO_IOPOWER */
+#if APPLE_OSX_mDNSResponder
+ // Note: We use SPMetricPortability > 35 to indicate a laptop of some kind
+ // SPMetricPortability <= 35 means nominally a non-portable machine (i.e. Mac mini or better)
+ // An Apple TV does not actually weigh 3kg, but we assign it a 'nominal' mass of 3kg to indicate that it's treated as being relatively less portable than a laptop
+ if (!strncasecmp(HINFO_HWstring, "Xserve", 6)) { SPMetricPortability = 25 /* 30kg */; SPMetricMarginalPower = 84 /* 250W */; SPMetricTotalPower = 85 /* 300W */; }
+ else if (!strncasecmp(HINFO_HWstring, "RackMac", 7)) { SPMetricPortability = 25 /* 30kg */; SPMetricMarginalPower = 84 /* 250W */; SPMetricTotalPower = 85 /* 300W */; }
+ else if (!strncasecmp(HINFO_HWstring, "MacPro", 6)) { SPMetricPortability = 27 /* 20kg */; SPMetricMarginalPower = 84 /* 250W */; SPMetricTotalPower = 85 /* 300W */; }
+ else if (!strncasecmp(HINFO_HWstring, "PowerMac", 8)) { SPMetricPortability = 27 /* 20kg */; SPMetricMarginalPower = 82 /* 160W */; SPMetricTotalPower = 83 /* 200W */; }
+ else if (!strncasecmp(HINFO_HWstring, "iMac", 4)) { SPMetricPortability = 30 /* 10kg */; SPMetricMarginalPower = 77 /* 50W */; SPMetricTotalPower = 78 /* 60W */; }
+ else if (!strncasecmp(HINFO_HWstring, "Macmini", 7)) { SPMetricPortability = 33 /* 5kg */; SPMetricMarginalPower = 73 /* 20W */; SPMetricTotalPower = 74 /* 25W */; }
+ else if (!strncasecmp(HINFO_HWstring, "AppleTV", 7)) { SPMetricPortability = 35 /* 3kg */; SPMetricMarginalPower = 10 /* 0W */; SPMetricTotalPower = 73 /* 20W */; }
+ else if (!strncasecmp(HINFO_HWstring, "MacBook", 7)) { SPMetricPortability = 37 /* 2kg */; SPMetricMarginalPower = 71 /* 13W */; SPMetricTotalPower = 72 /* 15W */; }
+ else if (!strncasecmp(HINFO_HWstring, "PowerBook",9)) { SPMetricPortability = 37 /* 2kg */; SPMetricMarginalPower = 71 /* 13W */; SPMetricTotalPower = 72 /* 15W */; }
+ LogSPS("HW_MODEL: %.*s (%s) Portability %d Marginal Power %d Total Power %d",
+ HINFO_HWstring_prefixlen, HINFO_HWstring, HINFO_HWstring, SPMetricPortability, SPMetricMarginalPower, SPMetricTotalPower);
+
+ err = WatchForInternetSharingChanges(m);
+ if (err) { LogMsg("WatchForInternetSharingChanges failed %d", err); return(err); }
+#endif // APPLE_OSX_mDNSResponder
+
return(mStatus_NoError);
}
LogMsg("Note: Compiled without Apple-specific Split-DNS support");
#endif
+ // Adding interfaces will use this flag, so set it now.
+ m->DivertMulticastAdvertisements = !m->AdvertiseLocalAddresses;
+
+#if APPLE_OSX_mDNSResponder
+ m->SPSBrowseCallback = UpdateSPSStatus;
+#endif
+
mStatus result = mDNSPlatformInit_setup(m);
// We don't do asynchronous initialization on OS X, so by the time we get here the setup will already
m->p->Store = NULL;
m->p->StoreRLS = NULL;
}
+
+ if (m->p->PMRLS)
+ {
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m->p->PMRLS, kCFRunLoopDefaultMode);
+ CFRunLoopSourceInvalidate(m->p->PMRLS);
+ CFRelease(m->p->PMRLS);
+ m->p->PMRLS = NULL;
+ }
+
+ if (m->p->SysEventNotifier >= 0) { close(m->p->SysEventNotifier); m->p->SysEventNotifier = -1; }
mDNSs32 utc = mDNSPlatformUTC();
MarkAllInterfacesInactive(m, utc);
ClearInactiveInterfaces(m, utc);
CloseSocketSet(&m->p->permanentsockets);
- #if APPLE_OSX_mDNSResponder
+#if APPLE_OSX_mDNSResponder
// clean up tunnels
while (m->TunnelClients)
{
ClientTunnel *cur = m->TunnelClients;
- LogOperation("mDNSPlatformClose: removing client tunnel %p %##s from list", cur, cur->dstname.c);
+ LogInfo("mDNSPlatformClose: removing client tunnel %p %##s from list", cur, cur->dstname.c);
if (cur->q.ThisQInterval >= 0) mDNS_StopQuery(m, &cur->q);
AutoTunnelSetKeys(cur, mDNSfalse);
m->TunnelClients = cur->next;
if (AnonymousRacoonConfig)
{
- AnonymousRacoonConfig = mDNSfalse;
- LogOperation("mDNSPlatformClose: Deconfiguring autotunnel");
- (void)mDNSConfigureServer(kmDNSDown, "");
+ AnonymousRacoonConfig = mDNSNULL;
+ LogInfo("mDNSPlatformClose: Deconfiguring autotunnel");
+ (void)mDNSConfigureServer(kmDNSDown, mDNSNULL);
}
if (m->AutoTunnelHostAddrActive && m->AutoTunnelHostAddr.b[0])
{
m->AutoTunnelHostAddrActive = mDNSfalse;
- LogOperation("mDNSPlatformClose: Removing AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
+ LogInfo("mDNSPlatformClose: Removing AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
(void)mDNSAutoTunnelInterfaceUpDown(kmDNSDown, m->AutoTunnelHostAddr.b);
}
- #endif // APPLE_OSX_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
}
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - General Platform Support Layer functions
#endif
-mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
+mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
{
- return(mach_absolute_time());
+ return(arc4random());
}
mDNSexport mDNSs32 mDNSPlatformOneSecond = 1000;
last_mach_absolute_time = this_mach_absolute_time;
// Only show "mach_absolute_time went backwards" notice on 10.4 (build 8xyyy) or later.
// (This bug happens all the time on 10.3, and we know that's not going to be fixed.)
- if (mDNSMacOSXSystemBuildNumber(NULL) >= 8)
+ if (OSXVers >= OSXVers_10_4_Tiger)
NotifyOfElusiveBug("mach_absolute_time went backwards!",
"This error occurs from time to time, often on newly released hardware, "
"and usually the exact cause is different in each instance.\r\r"
mDNSexport mDNSu32 mDNSPlatformStrLen ( const void *src) { return(strlen((char*)src)); }
mDNSexport void mDNSPlatformMemCopy( void *dst, const void *src, mDNSu32 len) { memcpy(dst, src, len); }
mDNSexport mDNSBool mDNSPlatformMemSame(const void *dst, const void *src, mDNSu32 len) { return(memcmp(dst, src, len) == 0); }
-mDNSexport void mDNSPlatformMemZero( void *dst, mDNSu32 len) { bzero(dst, len); }
+mDNSexport void mDNSPlatformMemZero( void *dst, mDNSu32 len) { memset(dst, 0, len); }
#if !(APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING)
mDNSexport void * mDNSPlatformMemAllocate(mDNSu32 len) { return(mallocL("mDNSPlatformMemAllocate", len)); }
#endif
Change History (most recent first):
$Log: mDNSMacOSX.h,v $
+Revision 1.104 2009/06/25 23:36:56 cheshire
+To facilitate testing, added command-line switch "-OfferSleepProxyService"
+to re-enable the previously-supported mode of operation where we offer
+sleep proxy service on desktop Macs that are set to never sleep.
+
+Revision 1.103 2009/04/11 00:20:13 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.102 2009/04/06 22:14:02 cheshire
+Need to include IOKit/pwr_mgt/IOPM.h to build for AppleTV
+
+Revision 1.101 2009/04/02 22:21:17 mcguire
+<rdar://problem/6577409> Adopt IOPM APIs
+
+Revision 1.100 2009/02/12 20:57:26 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.99 2009/02/11 02:31:05 cheshire
+Move SystemWakeForNetworkAccessEnabled into mDNS structure so it's accessible to mDNSCore routines
+
+Revision 1.98 2009/02/07 02:52:19 cheshire
+<rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+
+Revision 1.97 2009/02/02 22:13:01 cheshire
+Added SystemWakeForNetworkAccessEnabled setting
+
+Revision 1.96 2009/01/17 04:13:57 cheshire
+Added version symbols for Cheetah and Puma
+
+Revision 1.95 2009/01/16 02:32:55 cheshire
+Added SysEventNotifier and SysEventKQueue in mDNS_PlatformSupport_struct
+
+Revision 1.94 2009/01/15 22:24:53 cheshire
+Removed unused ifa_name field from NetworkInterfaceInfoOSX_struct
+
+Revision 1.93 2008/12/10 19:30:01 cheshire
+Added symbolic names for the various OS X versions
+
+Revision 1.92 2008/10/31 23:49:38 mkrochma
+Increased sizecheck limit
+
+Revision 1.91 2008/10/31 22:48:27 cheshire
+Added SCPreferencesRef to mDNS_PlatformSupport_struct
+
+Revision 1.90 2008/10/30 01:04:35 cheshire
+Added WakeAtUTC and SleepTime fields to mDNS_PlatformSupport_struct
+
+Revision 1.89 2008/10/29 18:38:33 mcguire
+Increase sizecheck limits to account for CFRunLoop added to mDNS_PlatformSupport_struct in 64bit builds
+
+Revision 1.88 2008/10/28 20:33:56 cheshire
+Added CFRunLoopRef in mDNS_PlatformSupport_struct, to hold reference to our main thread's CFRunLoop
+
+Revision 1.87 2008/10/28 18:32:09 cheshire
+Added CFSocketRef and CFRunLoopSourceRef in NetworkInterfaceInfoOSX_struct
+
+Revision 1.86 2008/10/22 23:23:53 cheshire
+Moved definition of OSXVers from daemon.c into mDNSMacOSX.c
+
+Revision 1.85 2008/10/21 00:12:00 cheshire
+Added BPF-related fields in NetworkInterfaceInfoOSX_struct
+
+Revision 1.84 2008/10/14 20:20:44 cheshire
+Increase sizecheck limits to account for DNSQuestions added to NetworkInterfaceInfo_struct
+
+Revision 1.83 2008/10/07 21:41:57 mcguire
+Increase sizecheck limits to account for DNSQuestion added to NetworkInterfaceInfo_struct in 64bit builds
+
+Revision 1.82 2008/10/07 15:56:24 cheshire
+Increase sizecheck limits to account for DNSQuestion added to NetworkInterfaceInfo_struct
+
+Revision 1.81 2008/10/03 00:26:25 cheshire
+Export DictionaryIsEnabled() so it's callable from other files
+
+Revision 1.80 2008/10/02 22:47:01 cheshire
+<rdar://problem/6134215> Sleep Proxy: Mac with Internet Sharing should also offer Sleep Proxy service
+Added SCPreferencesRef so we can track whether Internet Sharing is on or off
+
Revision 1.79 2008/07/30 00:55:56 mcguire
<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
Additional fixes so that we know when a socket has been closed while in a loop reading from it
#endif
#include <SystemConfiguration/SystemConfiguration.h>
+#include <IOKit/pwr_mgt/IOPM.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "mDNSEmbeddedAPI.h" // for domain name structure
{
NetworkInterfaceInfo ifinfo; // MUST be the first element in this structure
NetworkInterfaceInfoOSX *next;
- mDNSu32 Exists; // 1 = currently exists in getifaddrs list; 0 = doesn't
+ mDNS *m;
+ mDNSu8 Exists; // 1 = currently exists in getifaddrs list; 0 = doesn't
// 2 = exists, but McastTxRx state changed
+ mDNSu8 Flashing; // Set if interface appeared for less than 60 seconds and then vanished
+ mDNSu8 Occulting; // Set if interface vanished for less than 60 seconds and then came back
mDNSs32 AppearanceTime; // Time this interface appeared most recently in getifaddrs list
// i.e. the first time an interface is seen, AppearanceTime is set.
// If an interface goes away temporarily and then comes back then
// AppearanceTime is updated to the time of the most recent appearance.
mDNSs32 LastSeen; // If Exists==0, last time this interface appeared in getifaddrs list
- mDNSBool Flashing; // Set if interface appeared for less than 60 seconds and then vanished
- mDNSBool Occulting; // Set if interface vanished for less than 60 seconds and then came back
- char *ifa_name; // Memory for this is allocated using malloc
unsigned int ifa_flags;
struct in_addr ifa_v4addr;
mDNSu32 scope_id; // interface index / IPv6 scope ID
mDNSEthAddr BSSID; // BSSID of 802.11 base station, if applicable
u_short sa_family;
+ int BPF_fd; // -1 uninitialized; -2 requested BPF; -3 failed
+ u_int BPF_len;
+ CFSocketRef BPF_cfs;
+ CFRunLoopSourceRef BPF_rls;
};
struct mDNS_PlatformSupport_struct
// See <rdar://problem/5124399> Not getting Keychain Changed events when enabling BTMM
mDNSs32 KeyChainBugTimer;
mDNSs32 KeyChainBugInterval;
-
+
+ CFRunLoopRef CFRunLoop;
SCDynamicStoreRef Store;
CFRunLoopSourceRef StoreRLS;
+ CFRunLoopSourceRef PMRLS;
+ int SysEventNotifier;
+ KQueueEntry SysEventKQueue;
IONotificationPortRef PowerPortRef;
io_connect_t PowerConnection;
io_object_t PowerNotifier;
- mDNSs32 SleepLimit; // Set when we get kIOMessageSystemWillSleep notification
+#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+ IOPMConnection IOPMConnection;
+#endif
+ SCPreferencesRef SCPrefs;
long SleepCookie; // Cookie we need to pass to IOAllowPowerChange()
+ long WakeAtUTC;
+ mDNSs32 RequestReSleep;
pthread_mutex_t BigMutex;
mDNSs32 BigMutexStartTime;
int WakeKQueueLoopFD;
};
+extern int OfferSleepProxyService;
+extern int OSXVers;
+#define OSXVers_Base 4
+#define OSXVers_10_0_Cheetah 4
+#define OSXVers_10_1_Puma 5
+#define OSXVers_10_2_Jaguar 6
+#define OSXVers_10_3_Panther 7
+#define OSXVers_10_4_Tiger 8
+#define OSXVers_10_5_Leopard 9
+#define OSXVers_10_6_SnowLeopard 10
+
extern int KQueueFD;
extern void NotifyOfElusiveBug(const char *title, const char *msg); // Both strings are UTF-8 text
extern void KQueueLock(mDNS *const m);
extern void KQueueUnlock(mDNS *const m, const char const *task);
+extern mDNSBool DictionaryIsEnabled(CFDictionaryRef dict);
+
// If any event takes more than WatchDogReportingThreshold milliseconds to be processed, we log a warning message
// General event categories are:
// o Mach client request initiated / terminated
// what's causing the problem, we may need to subdivide some categories into finer-grained
// sub-categories (e.g. "Idle task processing" covers a pretty broad range of sub-tasks).
-#if LogAllOperations
-#define WatchDogReportingThreshold 50
-#else
-#define WatchDogReportingThreshold 250
-#endif
+extern int WatchDogReportingThreshold;
struct CompileTimeAssertionChecks_mDNSMacOSX
{
// 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_NetworkInterfaceInfoOSX[(sizeof(NetworkInterfaceInfoOSX) <= 4456) ? 1 : -1];
- char sizecheck_mDNS_PlatformSupport [(sizeof(mDNS_PlatformSupport) <= 368) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfoOSX[(sizeof(NetworkInterfaceInfoOSX) <= 7000) ? 1 : -1];
+ char sizecheck_mDNS_PlatformSupport [(sizeof(mDNS_PlatformSupport) <= 476) ? 1 : -1];
};
#ifdef __cplusplus
-start
_start
-_dyld_func_lookup
-main
-LogMsg
-mDNS_vsnprintf
-WriteLogMsg
-LogMsgIdent
-KQueueSet
-mDNSMacOSXSystemBuildNumber
-mDNS_Init
-mDNSPlatformTimeInit
-mDNSRandom
-mDNSPlatformRandomSeed
-mDNSPlatformRawTime
-mDNSPlatformInit
-GetUserSpecifiedLocalHostName
-mDNS_snprintf
-SetupSocket
-UpdateInterfaceList
-myGetIfAddrs
-AddInterfaceToList
-SetupAddr
-mDNSSameAddress
-mDNS_SetFQDN
-AppendDomainLabel
-AppendLiteralLabelString
-SameDomainNameCS
-mDNS_Lock
-mDNSPlatformLock
-DomainNameLengthLimit
-mDNSPlatformMemCopy
-mDNS_Unlock
-mDNSPlatformUnlock
-SetupActiveInterfaces
-mDNS_RegisterInterface
-AdvertiseInterface
-mDNS_SetupResourceRecord
-MakeDomainNameFromDNSNameString
-AppendDNSNameString
-mDNS_Register_internal
-InitializeLastAPTime
-SetNextAnnounceProbeTime
-GetRDLength
-ValidateRData
-DomainNameHashValue
-RDataHashValue
-SetTargetToHostName
-SameDomainName
-SetNewRData
-CompressedDomainNameLength
-AcknowledgeRecord
-IdenticalResourceRecord
-SetDomainSecrets
-mDNSKeychainGetSecrets
-getHelperPort
-proxy_mDNSKeychainGetSecrets
-mDNSDynamicStoreSetConfig
-proxy_mDNSDynamicStoreSetConfig
-mDNSCoreInitComplete
-mDNS_StatusCallback
-mDNSPlatformMemSame
-uDNS_SetupDNSConfig
-mDNSPlatformSetDNSConfig
-dns_configuration_copy
-_dns_configuration_server_port
-shared_dns_infoGet
-dns_configuration_free
-mDNSPlatformGetPrimaryInterface
-mDNS_SetPrimaryInterfaceInfo
-udsserver_init
-mDNSPlatformMemZero
-mDNSPlatformStrCopy
-udsSupportAddFDToEventLoop
-mDNS_GetDomains
-AppendDomainName
-mDNS_StartQuery
-mDNS_StartQuery_internal
-CheckForSoonToExpireRecords
-FindDuplicateQuestion
-GetAuthInfoForName
-RegisterLocalOnlyDomainEnumPTR
-mDNSPlatformMemAllocate
-mDNS_Register
-AddAutoBrowseDomain
-udsserver_automatic_browse_domain_changed
-machserver_automatic_browse_domain_changed
-udsserver_handle_configchange
-UpdateDeviceInfoRecord
-KQueueLoop
-mDNS_TimeNow
-mDNS_Execute
-uDNS_Execute
-mDNSv4AddrIsRFC1918
-udsserver_idle
-NetworkChanged
-KQueueLock
-KQueueUnlock
-KQWokenFlushBytes
-connect_callback
-NewRequest
-request_callback
-read_msg
-ConvertHeaderBytes
-handle_enum_request
-get_uint32
-mDNSPlatformInterfaceIDfromInterfaceIndex
-uDNS_RegisterSearchDomains
-put_uint32
-send_all
-mDNSMacOSXNetworkChanged
-ClearInactiveInterfaces
-GetFirstActiveInterface
-InitializeDNSMessage
-putQuestion
-putDomainNameAsLabels
-FindCompressionPointer
-PutResourceRecordTTLWithLimit
-putRData
-mDNSSendDNSMessage
-mDNSPlatformSendUDP
-mDNSAddrIsDNSMulticast
-myKQSocketCallBack
-mDNSCoreReceive
-AddressIsLocalSubnet
-getQuestion
-getDomainName
-ResourceRecordAnswersQuestion
-LocateAuthorities
-GetLargeResourceRecord
-PacketRRConflict
-SameRData
-SameRDataBody
-AddAdditionalsToResponseList
-SendResponses
-mDNSCoreReceiveResponse
-uDNS_recvLLQResponse
-LocateAnswers
-CreateNewCacheEntry
-GetCacheEntity
-SetNextCacheCheckTime
-CacheRecordDeferredAdd
-IdenticalSameNameRecord
-mDNS_HostNameCallback
-SameResourceRecordSignature
-AnswerLocalQuestions
-AnswerLocalOnlyQuestionWithResourceRecord
-enum_result_callback
-ConvertDomainNameToCString_withescape
-ConvertDomainLabelToCString_withescape
-create_reply
-put_string
-CheckCacheExpiration
-AbortUnlinkAndFree
-abort_request
-enum_termination_callback
-mDNS_StopQuery
-mDNS_StopQuery_internal
-udsSupportRemoveFDFromEventLoop
-get_string
-ChopSubTypes
-add_domain_to_browser
-mDNS_StartBrowse
-ConstructServiceName
-IsLocalDomain
-GetNextActiveInterfaceID
-ReconfirmAntecedents
-mDNS_DeregisterInterface
-DeadvertiseInterface
-mDNS_Deregister_internal
-NumCacheRecordsForInterfaceID
-mDNS_UpdateLLQs
-SuspendLLQs
-RestartQueries
-mDNS_AddSearchDomain
-mDNS_NewMessageID
-GetServerForName
-ActivateUnicastQuery
-AddrRequiresPPPConnection
-mDNS_AddDNSServer
-SetExternalAddress
-UpdateSRVRecords
-ReleaseCacheRecord
-ReleaseCacheGroup
-uDNS_CheckCurrentQuestion
-NoTestQuery
-uDNS_ReceiveMsg
-GetLLQOptData
-LocateLLQOptData
-LocateAdditionals
-AnswerCurrentQuestionWithResourceRecord
-FoundInstance
-GenerateNTDResponse
-DeconstructServiceName
-mDNSPlatformInterfaceIndexfromInterfaceID
-get_uint16
-constructQueryMsg
-skipResourceRecord
-FoundDomain
-FreeARElemCallback
-SameNameRecordAnswersQuestion
-queryrecord_result_callback
-put_uint16
-queryrecord_termination_callback
-FoundStaticHostname
-AutomaticBrowseDomainChange
-FindIdenticalRecordInCache
-MakeDomainLabelFromLiteralString
-register_service_instance
-AllocateSubTypes
-mDNS_RegisterService
-ServiceCallback
-regservice_callback
-KeychainChanged
-mDNS_SetSecretForDomain
-DNSDigest_ConstructHMACKeyfromBase64
-StartGetZoneData
-GetZoneData_StartQuery
-AppendDNameListElem
-SetPrefsBrowseDomains
-udsserver_default_reg_domain_changed
-machserver_automatic_registration_domain_changed
-GetServiceTarget
-SetupLocalAutoTunnelInterface_internal
-mDNSAutoTunnelInterfaceUpDown
-proxy_mDNSAutoTunnelInterfaceUpDown
-mDNS_AddDynDNSHostName
-AdvertiseHostname
-mDNS_StartNATOperation_internal
-mDNSConfigureServer
-proxy_mDNSConfigureServer
-mDNSPlatformUDPSocket
-uDNS_SendNATMsg
-LNT_SendDiscoveryMsg
-uDNS_ReceiveNATPMPPacket
-natTraversalHandleAddressReply
-hostnameGetPublicAddressCallback
-natTraversalHandlePortMapReply
-AutoTunnelNATCallback
-GetZoneData_QuestionCallback
-startLLQHandshakeCallback
-startLLQHandshake
-StartLLQNatMap
-mDNSPlatformMemFree
-RecordRegistrationCallback
-sendRecordRegistration
-putZone
-putDeleteRRSet
-putUpdateLease
-MakeTCPConn
-mDNSPlatformTCPSocket
-mDNSPlatformTCPConnect
-tcpKQSocketCallback
-tlsSetupSock
-tlsWriteSock
-tlsReadSock
-LLQNatMapComplete
-mDNS_GrowCache
-tcpCallback
-DNSDigest_SignMessage
-MD5_Update
-md5_block_host_order
-mDNSPlatformUTC
-MD5_Final
-mDNSPlatformWriteTCP
-putLLQ
-serviceRegistrationCallback
-SendServiceRegistration
-putPrereqNameNotInUse
-putEmptyResourceRecord
-mDNSPlatformReadTCP
-DisposeTCPConn
-mDNSPlatformTCPCloseConnection
-GetPktLease
-LocateLeaseOptData
-checkUpdateResult
-GetRRDisplayString_rdb
-startPrivateQueryCallback
-HostnameCallback
-UpdateSRV
-SendServiceDeregistration
-putDeleteAllRRSets
-putDeletionRecord
-StartSRVNatMap
-SameDomainLabel
-CompleteSRVNatMap
-PowerChanged
-mDNSCoreMachineSleep
-uDNS_Sleep
-sendLLQRefresh
-mDNS_StopNATOperation_internal
-mDNS_Reconfirm_internal
-mDNSRandomFromFixedSeed
-DeregisterLocalOnlyDomainEnumPTR
-mDNS_Deregister
-RmvAutoBrowseDomain
-uDNS_Wake
-uDNS_DeregisterRecord
-MakeNegativeCacheRecord
-CompleteDeregistration
-mDNSPlatformUDPClose
-CloseSocketSet
-CancelGetZoneData
-SendRecordDeregistration
-mDNSPlatformStrLen
-TruncateUTF8ToLength
-get_rdata
-mDNS_AddRecordToService
-update_record
-mDNS_Update
-CompleteRDataUpdate
-update_callback
-ShouldSuppressKnownAnswer
-handle_resolve_request
-resolve_result_callback
-put_rdata
-resolve_termination_callback
-regservice_termination_callback
-mDNS_DeregisterService
-browse_termination_callback
-free_service_instance
-FreeExtraRR
-SetNextQueryTime
-AddNewClientTunnel
-AutoTunnelCallback
-FindSourceAddrForIP
-AutoTunnelSetKeys
-mDNSAutoTunnelSetKeys
-proxy_mDNSAutoTunnelSetKeys
-ReissueBlockedQuestions
-read_rr_from_ipc_msg
-CountPeerRegistrations
-RecordUpdatedNiceLabel
-regrecord_callback
-handle_port_mapping_request
-mDNS_StartNATOperation
-port_mapping_create_request_callback
-DNSTypeName
-mDNS_StopQueryWithRemoves
-uDNS_StopLongLivedQuery
-uDNS_ReceiveSSDPPacket
-LNT_ConfigureRouterInfo
-MakeTCPConnection
-tcpConnectionCallback
-LNT_GetExternalAddress
-SendSOAPMsgControlAction
-LNT_MapPort
-LNT_UnmapPort
-PutResourceRecordCappedTTL
-connection_termination
-uDNS_DeregisterService
-SendServiceRemovalNotification
-mDNS_RemoveDynDNSHostName
-mDNS_StopNATOperation
-unlinkSRS
-DDNSSettingEnabled
-sendChallengeResponse
-mDNSPlatformDynDNSHostNameStatusChanged
-UnlinkAuthRecord
-DynDNSHostNameCallback
-port_mapping_termination_callback
-SendDelayedUnicastResponse
-RecordProbeFailure
-mDNS_RenameAndReregisterService
-IncrementLabelSuffix
-LabelContainsSuffix
-AppendLabelSuffix
+__start
+_dyld_stub_binding_helper
+__dyld_func_lookup
+_main
+_LogMsgWithLevel
+_mDNS_vsnprintf
+_mDNSPlatformWriteLogMsg
+_safe_vproc_transaction_begin
+_KQueueSet
+_mDNSMacOSXSystemBuildNumber
+_mDNSDaemonInitialize
+_mDNS_Init
+_mDNSPlatformTimeInit
+_mDNSRandom
+_mDNSPlatformRandomNumber
+_mDNSPlatformRawTime
+_mDNSPlatformInit
+_mDNS_snprintf
+_GetUserSpecifiedLocalHostName
+_SetupSocket
+_SystemWakeForNetworkAccess
+_UpdateInterfaceList
+_myGetIfAddrs
+_AddInterfaceToList
+_SetupAddr
+_NetWakeInterface
+_mDNS_SetFQDN
+_AppendDomainLabel
+_AppendLiteralLabelString
+_mDNS_Lock_
+_mDNSPlatformLock
+_SameDomainNameCS
+_DomainNameLengthLimit
+_mDNSPlatformMemCopy
+_mDNS_Unlock_
+_mDNSPlatformUnlock
+_SetupActiveInterfaces
+_SearchForInterfaceByName
+_mDNS_RegisterInterface
+_AdvertiseInterface
+_mDNS_SetupResourceRecord
+_MakeDomainNameFromDNSNameString
+_AppendDNSNameString
+_mDNS_Register_internal
+_InitializeLastAPTime
+_SetNextAnnounceProbeTime
+_GetRDLength
+_ValidateRData
+_DomainNameHashValue
+_RDataHashValue
+_SetTargetToHostName
+_SameDomainName
+_SetNewRData
+_CompressedDomainNameLength
+_AcknowledgeRecord
+_mDNS_StartBrowse_internal
+_ConstructServiceName
+_AppendDomainName
+_mDNS_StartQuery_internal
+_IsLocalDomain
+_CheckForSoonToExpireRecords
+_GetAuthInfoForQuestion
+_GetAuthInfoForName_internal
+_FindDuplicateQuestion
+_SetNextQueryTime
+_SetDomainSecrets
+_mDNSKeychainGetSecrets
+_getHelperPort
+_proxy_mDNSKeychainGetSecrets
+_mDNS_SetSecretForDomain
+_DNSDigest_ConstructHMACKeyfromBase64
+_mDNSPlatformMemZero
+_UpdateAutoTunnelDomainStatus
+_ConvertDomainLabelToCString_withescape
+_mDNSASLLog
+_mDNSDynamicStoreSetConfig
+_proxy_mDNSDynamicStoreSetConfig
+_ConvertDomainNameToCString_withescape
+_UpdateConfigureServer
+_TunnelServers
+_mDNSCoreInitComplete
+_mDNS_StatusCallback
+_mDNSPlatformMemSame
+_uDNS_SetupDNSConfig
+_mDNSPlatformSetDNSConfig
+_dns_configuration_copy
+___dns_initialize
+__dns_configuration_server_port
+_shared_dns_infoGet
+_CountLabels
+_SkipLeadingLabels
+_dns_configuration_free
+_mDNSPlatformGetPrimaryInterface
+_mDNS_SetPrimaryInterfaceInfo
+_udsserver_init
+_udsSupportAddFDToEventLoop
+_mDNS_GetDomains
+_mDNS_StartQuery
+_RegisterLocalOnlyDomainEnumPTR
+_mDNSPlatformMemAllocate
+_mDNS_Register
+_AddAutoBrowseDomain
+_udsserver_automatic_browse_domain_changed
+_machserver_automatic_browse_domain_changed
+_udsserver_handle_configchange
+_UpdateDeviceInfoRecord
+_AppendDNameListElem
+_SetPrefsBrowseDomains
+_udsserver_default_reg_domain_changed
+_machserver_automatic_registration_domain_changed
+_mDNSMacOSXNetworkChanged
+_mDNSSameAddress
+_ClearInactiveInterfaces
+_mDNSCoreBeSleepProxyServer
+_mDNS_ConfigChanged
+_mDNSPreferencesSetName
+_proxy_mDNSPreferencesSetName
+_SameRDataBody
+_DeregisterLocalOnlyDomainEnumPTR
+_mDNS_Deregister
+_mDNS_Deregister_internal
+_mDNSPlatformMemFree
+_RmvAutoBrowseDomain
+_KQueueLoop
+_mDNS_TimeNow
+_mDNS_Execute
+_SendQueries
+_GetFirstActiveInterface
+_InitializeDNSMessage
+_uDNS_Execute
+_mDNSv4AddrIsRFC1918
+_udsserver_idle
+_connect_callback
+_NewRequest
+_request_callback
+_ConvertHeaderBytes
+_handle_regservice_request
+_get_uint32
+_mDNSPlatformInterfaceIDfromInterfaceIndex
+_get_string
+_mDNSPlatformStrCopy
+_get_uint16
+_ChopSubTypes
+_AuthorizedDomain
+_register_service_instance
+_AllocateSubTypes
+_mDNS_RegisterService
+_ServiceCallback
+_GetServiceTarget
+_SetupLocalAutoTunnelInterface_internal
+_mDNSAutoTunnelInterfaceUpDown
+_proxy_mDNSAutoTunnelInterfaceUpDown
+_NetworkChanged
+_KQueueLock
+_AbortDeregistration
+_mDNS_StartNATOperation_internal
+_put_uint32
+_send_all
+_uDNS_SendNATMsg
+_KQueueUnlock
+_KQWokenFlushBytes
+_handle_queryrecord_request
+_mDNS_NewMessageID
+_GetServerForName
+_ActivateUnicastQuery
+_LastLabel
+_SameDomainLabel
+_uDNS_CheckCurrentQuestion
+_CacheGroupForName
+_MakeNegativeCacheRecord
+_CreateNewCacheEntry
+_GetCacheEntity
+_ResourceRecordAnswersQuestion
+_SetNextCacheCheckTime
+_SameNameRecordAnswersQuestion
+_CheckCacheExpiration
+_CacheRecordDeferredAdd
+_AnswerCurrentQuestionWithResourceRecord
+_queryrecord_result_callback
+_create_reply
+_mDNSPlatformInterfaceIndexfromInterfaceID
+_put_string
+_put_uint16
+_abort_request
+_queryrecord_termination_callback
+_mDNS_StopQuery
+_mDNS_StopQuery_internal
+_putQuestion
+_putDomainNameAsLabels
+_FindCompressionPointer
+_GetNextActiveInterfaceID
+_PutResourceRecordTTLWithLimit
+_putRData
+_mDNSSendDNSMessage
+_putHINFO
+_mDNSPlatformSendUDP
+_mDNSAddrIsDNSMulticast
+_myKQSocketCallBack
+_mDNSCoreReceive
+_mDNSCoreReceiveQuery
+_AddressIsLocalSubnet
+_LocateOptRR
+_LocateAdditionals
+_LocateAuthorities
+_LocateAnswers
+_skipResourceRecord
+_getQuestion
+_getDomainName
+_GetLargeResourceRecord
+_PacketRRConflict
+_AddAdditionalsToResponseList
+_mDNS_HostNameCallback
+_regservice_callback
+_GenerateNTDResponse
+_DeconstructServiceName
+_CountPeerRegistrations
+_RecordUpdatedNiceLabel
+_ClearProxyRecords
+_SendResponses
+_uDNS_recvLLQResponse
+_AnswerAllLocalQuestionsWithLocalAuthRecord
+_handle_regrecord_request
+_read_rr_from_ipc_msg
+_get_rdata
+_regrecord_callback
+_StartGetZoneData
+_GetZoneData_StartQuery
+_SetRecordRetry
+_GetZoneData_QuestionCallback
+_RecordRegistrationGotZoneData
+_SameResourceRecordSignature
+_FindIdenticalRecordInCache
+_mDNS_GrowCache
+_ShouldSuppressKnownAnswer
+_AutoTunnelNATCallback
+_RegisterAutoTunnelRecords
+_SysEventCallBack
+_UpdateSRVRecords
+_UpdateSRV
+_mDNS_DeregisterInterface
+_mDNS_PurgeCacheResourceRecord
+_DeadvertiseInterface
+_NumCacheRecordsForInterfaceID
+_AddrRequiresPPPConnection
+_mDNS_AddDNSServer
+_PurgeOrReconfirmCacheRecord
+_LNT_ClearState
+_UpdateAutoTunnelDomainStatuses
+_ReleaseCacheGroup
+_mDNS_AddDynDNSHostName
+_AdvertiseHostname
+_mDNSConfigureServer
+_mDNSPlatformStrLen
+_proxy_mDNSConfigureServer
+_CancelGetZoneData
+_mDNSPlatformUDPSocket
+_uDNS_ReceiveMsg
+_GetLLQOptData
+_ExpectingUnicastResponseForQuestion
+_UpdateSPSStatus
+_SPSStatusPutNumber
+_mDNSPlatformUDPClose
+_CloseSocketSet
+_SendRecordRegistration
+_putZone
+_putUpdateLease
+_MakeTCPConn
+_mDNSPlatformTCPSocket
+_mDNSPlatformTCPConnect
+_putDeleteRRSet
+_ServiceRegistrationGotZoneData
+_SendServiceRegistration
+_tcpKQSocketCallback
+_tlsSetupSock
+_doSSLHandshake
+_tlsWriteSock
+_tlsReadSock
+_tcpCallback
+_GetAuthInfoForName
+_DNSDigest_SignMessage
+_MD5_Update
+_md5_block_data_order
+_md5_block_host_order
+_mDNSPlatformUTC
+_MD5_Final
+_mDNSPlatformWriteTCP
+_mDNSPlatformReadTCP
+_DisposeTCPConn
+_mDNSPlatformTCPCloseConnection
+_GetPktLease
+_checkUpdateResult
+_HostnameCallback
+_AutoTunnelRecordCallback
+_handle_getproperty_request
+_AbortUnlinkAndFree
+_udsSupportRemoveFDFromEventLoop
+_handle_browse_request
+_add_domain_to_browser
+_mDNS_StartBrowse
+_ReconfirmAntecedents
+_FoundInstance
+_connection_termination
+_startLLQHandshake
+_LLQNATCallback
+_uDNS_RegisterSearchDomains
+_mDNS_AddSearchDomain
+_AnswerLocalQuestionWithLocalAuthRecord
+_enum_result_callback
+_LLQGotZoneData
+_GetLLQEventPort
+_mDNSPlatformSourceAddrForDest
+_putLLQ
+_SetLLQTimer
+_sendLLQRefresh
+_SendDelayedUnicastResponse
+_mDNS_Reconfirm_internal
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
; $Log: mDNSResponder.sb,v $
-; Revision 1.25.2.1 2008/07/29 20:48:34 mcguire
-; <rdar://problem/6090007> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
-; merge r1.27 from <rdar://problem/3988320>
+; Revision 1.38 2009/04/16 16:03:08 mcguire
+; <rdar://problem/6792024> abort() causes high CPU usage instead of crash & restart
+;
+; Revision 1.37 2009/04/02 22:21:17 mcguire
+; <rdar://problem/6577409> Adopt IOPM APIs
+;
+; Revision 1.36 2009/03/02 01:32:20 mcguire
+; <rdar://problem/6623264> Seatbelt: Add rule to allow raw sockets
+;
+; Revision 1.35 2009/02/07 02:51:10 cheshire
+; <rdar://problem/6084043> Sleep Proxy: Need to adopt IOPMConnection
+; Allow mDNSResponder to access IOPMConnection API
+;
+; Revision 1.34 2008/11/11 00:55:08 mcguire
+; <rdar://problem/6357957> sandbox: need to allow Mach port com.apple.system.DirectoryService.membership_v1
+;
+; Revision 1.33 2008/10/24 02:03:30 cheshire
+; So we can watch for Internet Sharing changes, allow read access to
+; /Library/Preferences/SystemConfiguration/com.apple.nat.plist
+;
+; Revision 1.32 2008/10/07 23:06:58 mcguire
+; <rdar://problem/6276444> Seatbelt: Policy denied Mach service lookup: com.apple.system.logger
+;
+; Revision 1.31 2008/09/24 23:57:27 mcguire
+; <rdar://problem/6227808> need read access to /private/var/db/crls/crlcache.db
+;
+; Revision 1.30 2008/09/11 22:01:51 mcguire
+; re-add accidentally removed log comment
+;
+; Revision 1.29 2008/09/11 20:46:08 mcguire
+; <rdar://problem/6208848> can't write to -Caches-
+;
+; Revision 1.28 2008/09/11 20:04:14 mcguire
+; <rdar://problem/6211355> Instances of \. in regex exprs don't do what is intended
+;
+; Revision 1.27 2008/07/24 21:18:14 cheshire
+; <rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+; Need to allow access to /dev/urandom
+;
+; Revision 1.26 2008/06/03 01:21:12 mcguire
+; <rdar://problem/5902470> add /var/db/mds to sb profile
;
; Revision 1.25 2008/03/17 18:04:41 mcguire
; <rdar://problem/5800476> SC now reads preference file
"com.apple.bsd.dirhelper"
"com.apple.distributed_notifications.2"
"com.apple.ocspd"
+ "com.apple.PowerManagement.control"
"com.apple.mDNSResponderHelper"
"com.apple.SecurityServer"
"com.apple.SystemConfiguration.configd"
"com.apple.system.DirectoryService.libinfo_v1"
- "com.apple.system.notification_center"))
+ "com.apple.system.DirectoryService.membership_v1"
+ "com.apple.system.notification_center"
+ "com.apple.system.logger"))
; Rules to allow the operations mDNSResponder needs start here
+(allow signal (target self))
(allow network*) ; Allow networking, including Unix Domain Sockets
+(if (defined? 'system-socket)
+ (allow system-socket)) ; To create raw sockets
(allow sysctl-read) ; To get hardware model information
(allow file-read-metadata) ; Needed for dyld to work
(allow ipc-posix-shm) ; Needed for POSIX shared memory
-(allow file-read-data (regex "^/dev/random\$"))
-(allow file-read-data file-write-data (regex "^/dev/console\$")) ; Needed for syslog early in the boot process
-(allow file-read-data (regex "^/dev/autofs_nowait\$")) ; Used by CF to circumvent automount triggers
+(allow file-read-data (regex #"^/dev/random$"))
+(allow file-read-data file-write-data (regex #"^/dev/console$")) ; Needed for syslog early in the boot process
+(allow file-read-data (regex #"^/dev/autofs_nowait$")) ; Used by CF to circumvent automount triggers
; Allow us to read and write our socket
-(allow file-read* file-write* (regex "^/private/var/run/mDNSResponder\$"))
+(allow file-read* file-write* (regex #"^/private/var/run/mDNSResponder$"))
; Allow us to read system version, settings, and other miscellaneous necessary file system accesses
-(allow file-read-data (regex "^/dev/urandom$"))
-(allow file-read-data (regex "^/usr/sbin(/mDNSResponder)?\$")) ; Needed for CFCopyVersionDictionary()
-(allow file-read-data (regex "^/usr/share/icu/.*\$"))
-(allow file-read-data (regex "^/usr/share/zoneinfo/.*\$"))
-(allow file-read-data (regex "^/Library/Preferences/SystemConfiguration/preferences\.plist\$"))
-(allow file-read-data (regex "^/Library/Preferences/(ByHost/)?\.GlobalPreferences.*\.plist\$"))
-(allow file-read-data (regex "^/Library/Preferences/com\.apple\.security.*\.plist\$"))
-(allow file-read-data (regex "^/Library/Preferences/com\.apple\.crypto\.plist\$"))
-(allow file-read-data (regex "^/Library/Security/Trust Settings/Admin\.plist\$"))
-(allow file-read-data (regex "^/System/Library/CoreServices/SystemVersion.*\$"))
-(allow file-read-data (regex "^/System/Library/Preferences/com\.apple\.security.*\.plist\$"))
-(allow file-read-data (regex "^/System/Library/Preferences/com\.apple\.crypto\.plist\$"))
+(allow file-read-data (regex #"^/dev/urandom$"))
+(allow file-read-data (regex #"^/usr/sbin(/mDNSResponder)?$")) ; Needed for CFCopyVersionDictionary()
+(allow file-read-data (regex #"^/usr/share/icu/.*$"))
+(allow file-read-data (regex #"^/usr/share/zoneinfo/.*$"))
+(allow file-read-data (regex #"^/Library/Preferences/SystemConfiguration/preferences\.plist$"))
+(allow file-read-data (regex #"^/Library/Preferences/SystemConfiguration/com\.apple\.nat\.plist$"))
+(allow file-read-data (regex #"^/Library/Preferences/(ByHost/)?\.GlobalPreferences.*\.plist$"))
+(allow file-read-data (regex #"^/Library/Preferences/com\.apple\.security.*\.plist$"))
+(allow file-read-data (regex #"^/Library/Preferences/com\.apple\.crypto\.plist$"))
+(allow file-read-data (regex #"^/Library/Security/Trust Settings/Admin\.plist$"))
+(allow file-read-data (regex #"^/System/Library/CoreServices/SystemVersion.*$"))
+(allow file-read-data (regex #"^/System/Library/Preferences/com\.apple\.security.*\.plist$"))
+(allow file-read-data (regex #"^/System/Library/Preferences/com\.apple\.crypto\.plist$"))
+(allow file-read-data (regex #"^/System/Library/SystemConfiguration/PowerManagement\.bundle(/|$)"))
+(allow file-read-data (regex #"^/Library/Preferences/SystemConfiguration/com\.apple\.PowerManagement\.plist$"))
; Allow access to System Keychain
-(allow file-read-data (regex "^/System/Library/Security\$"))
-(allow file-read-data (regex "^/System/Library/Keychains/.*\$"))
-(allow file-read-data (regex "^/Library/Keychains/System\.keychain\$"))
+(allow file-read-data (regex #"^/System/Library/Security$"))
+(allow file-read-data (regex #"^/System/Library/Keychains/.*$"))
+(allow file-read-data (regex #"^/Library/Keychains/System\.keychain$"))
; Our Module Directory Services cache
-(allow file-read-data (regex "^/private/var/tmp/mds/"))
-(allow file-read* file-write* (regex "^/private/var/tmp/mds/[0-9]+(/|\$)"))
-
+(allow file-read-data (regex #"^/private/var/tmp/mds/"))
+(allow file-read* file-write* (regex #"^/private/var/tmp/mds/[0-9]+(/|$)"))
+(allow file-read-data (regex #"^/private/var/db/mds/"))
+(allow file-read* file-write* (regex #"^/private/var/db/mds/[0-9]+(/|$)"))
+(allow file-read* file-write* (regex #"^/private/var/folders/[^/]+/[^/]+/-Caches-/mds(/|$)"))
+; CRL Cache for SSL/TLS connections
+(allow file-read-data (regex #"^/private/var/db/crls/crlcache\.db$"))
D284BF300ADD81630027CCDF /* PBXTargetDependency */,
D284BF260ADD814F0027CCDF /* PBXTargetDependency */,
D284BF2A0ADD81530027CCDF /* PBXTargetDependency */,
- FFD41DDB0664169900F0C438 /* PBXTargetDependency */,
);
name = "Build More";
productName = "Build All";
2EDC5E730C39EA640092701B /* helper-server.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EDC5E720C39EA640092701B /* helper-server.h */; };
2EDC5E740C39EA640092701B /* helper-server.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EDC5E720C39EA640092701B /* helper-server.h */; };
2EDC5E750C39EA640092701B /* helper-server.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EDC5E720C39EA640092701B /* helper-server.h */; };
- 4A8202650C56C4C900DDFD48 /* pfkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A8202530C56C36600DDFD48 /* pfkey.c */; };
4AAE0C9A0C68EA81003882A5 /* mDNSResponderHelper.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4AAE0C7A0C68E97F003882A5 /* mDNSResponderHelper.8 */; };
+ 4AE9B04B0F39448B0080B59D /* safe_vproc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4AE9B0480F39448B0080B59D /* safe_vproc.c */; };
+ 4AE9B04C0F39448B0080B59D /* safe_vproc.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AE9B0490F39448B0080B59D /* safe_vproc.h */; };
+ 4AE9B0920F3A52A10080B59D /* safe_vproc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4AE9B0480F39448B0080B59D /* safe_vproc.c */; };
+ 4AE9B0930F3A52A20080B59D /* safe_vproc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4AE9B0480F39448B0080B59D /* safe_vproc.c */; };
+ 4AE9B0940F3A52AE0080B59D /* safe_vproc.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AE9B0490F39448B0080B59D /* safe_vproc.h */; };
+ 4AE9B0950F3A52AE0080B59D /* safe_vproc.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AE9B0490F39448B0080B59D /* safe_vproc.h */; };
D284BE530ADD80740027CCDF /* DNSServiceDiscoveryDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6575FBFF022EAFBA00000109 /* DNSServiceDiscoveryDefines.h */; };
D284BE540ADD80740027CCDF /* dnssd_ipc.h in Headers */ = {isa = PBXBuildFile; fileRef = F5E11B5B04A28126019798ED /* dnssd_ipc.h */; };
D284BE560ADD80740027CCDF /* DNSServiceDiscoveryReply.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC00022EAFBA00000109 /* DNSServiceDiscoveryReply.defs */; settings = {ATTRIBUTES = (Client, ); }; };
D284BF040ADD80B00027CCDF /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF2609FA07B4433800CE10E5 /* Cocoa.framework */; };
D284BF050ADD80B00027CCDF /* PreferencePanes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF260A1F07B4436900CE10E5 /* PreferencePanes.framework */; };
D284BF060ADD80B00027CCDF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09AB6884FE841BABC02AAC07 /* CoreFoundation.framework */; };
- D284C04E0ADD95D30027CCDF /* Info-PreferencePane.plist in Resources */ = {isa = PBXBuildFile; fileRef = D284C04D0ADD95D30027CCDF /* Info-PreferencePane.plist */; };
- DB2CC4560662DE4500335AB3 /* BaseListener.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4430662DD1100335AB3 /* BaseListener.java */; };
- DB2CC4570662DE4600335AB3 /* BrowseListener.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4440662DD1100335AB3 /* BrowseListener.java */; };
- DB2CC4580662DE4700335AB3 /* DNSRecord.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4450662DD1100335AB3 /* DNSRecord.java */; };
- DB2CC4590662DE4700335AB3 /* DNSSD.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4460662DD1100335AB3 /* DNSSD.java */; };
- DB2CC45A0662DE4800335AB3 /* DNSSDException.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4470662DD1100335AB3 /* DNSSDException.java */; };
- DB2CC45B0662DE4900335AB3 /* DNSSDRegistration.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4480662DD1100335AB3 /* DNSSDRegistration.java */; };
- DB2CC45C0662DE4900335AB3 /* DNSSDService.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC4490662DD1100335AB3 /* DNSSDService.java */; };
- DB2CC45D0662DE4A00335AB3 /* DomainListener.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC44A0662DD1100335AB3 /* DomainListener.java */; };
- DB2CC45E0662DE4B00335AB3 /* QueryListener.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC44C0662DD1100335AB3 /* QueryListener.java */; };
- DB2CC45F0662DE4C00335AB3 /* RegisterListener.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC44D0662DD1100335AB3 /* RegisterListener.java */; };
- DB2CC4600662DE4C00335AB3 /* ResolveListener.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC44E0662DD1100335AB3 /* ResolveListener.java */; };
- DB2CC4610662DE4D00335AB3 /* TXTRecord.java in Sources */ = {isa = PBXBuildFile; fileRef = DB2CC44F0662DD1100335AB3 /* TXTRecord.java */; };
- FF2C5FB10A48B8680066DA11 /* DNSSDRecordRegistrar.java in Sources */ = {isa = PBXBuildFile; fileRef = FF2C5FB00A48B8680066DA11 /* DNSSDRecordRegistrar.java */; };
- FF2C5FB30A48B86E0066DA11 /* RegisterRecordListener.java in Sources */ = {isa = PBXBuildFile; fileRef = FF2C5FB20A48B86E0066DA11 /* RegisterRecordListener.java */; };
FFA572330AF18F1C0055A0F1 /* dnssd_ipc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5E11B5A04A28126019798ED /* dnssd_ipc.c */; };
FFA572340AF18F1C0055A0F1 /* dnssd_clientlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FFFA38620AEEDB090065B80A /* dnssd_clientlib.c */; };
FFA572350AF18F1C0055A0F1 /* dnssd_clientstub.c in Sources */ = {isa = PBXBuildFile; fileRef = FFFA38640AEEDB130065B80A /* dnssd_clientstub.c */; };
FFA5724B0AF18FCC0055A0F1 /* DNSServiceDiscovery.c in Sources */ = {isa = PBXBuildFile; fileRef = FFA572480AF18FCC0055A0F1 /* DNSServiceDiscovery.c */; };
FFA572610AF190940055A0F1 /* DNSServiceDiscovery.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FFA572600AF1908D0055A0F1 /* DNSServiceDiscovery.h */; };
FFA572640AF190C80055A0F1 /* dns_sd.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = FFA572630AF190C20055A0F1 /* dns_sd.h */; };
+ FFB437150EB165BD00E17C68 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CA213D02786FC30CCA2C71 /* IOKit.framework */; };
FFC22AA20B00F42A00BAB070 /* DNSServiceDiscoveryRequest.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC01022EAFBA00000109 /* DNSServiceDiscoveryRequest.defs */; };
FFC22AA30B00F42B00BAB070 /* DNSServiceDiscoveryRequest.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC01022EAFBA00000109 /* DNSServiceDiscoveryRequest.defs */; };
FFC22AA40B00F42C00BAB070 /* DNSServiceDiscoveryRequest.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC01022EAFBA00000109 /* DNSServiceDiscoveryRequest.defs */; };
FFC22AA50B00F43000BAB070 /* DNSServiceDiscoveryReply.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC00022EAFBA00000109 /* DNSServiceDiscoveryReply.defs */; settings = {ATTRIBUTES = (Server, ); }; };
FFC22AA60B00F43100BAB070 /* DNSServiceDiscoveryReply.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC00022EAFBA00000109 /* DNSServiceDiscoveryReply.defs */; settings = {ATTRIBUTES = (Server, ); }; };
FFC22AA70B00F43100BAB070 /* DNSServiceDiscoveryReply.defs in Sources */ = {isa = PBXBuildFile; fileRef = 6575FC00022EAFBA00000109 /* DNSServiceDiscoveryReply.defs */; settings = {ATTRIBUTES = (Server, ); }; };
+ FFF589B70E37F66800EF515C /* ClientCommon.c in Sources */ = {isa = PBXBuildFile; fileRef = FF5852100DD27BD300862BDF /* ClientCommon.c */; };
+ FFF589C10E37F67E00EF515C /* ClientCommon.c in Sources */ = {isa = PBXBuildFile; fileRef = FF5852100DD27BD300862BDF /* ClientCommon.c */; };
FFFA38630AEEDB090065B80A /* dnssd_clientlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FFFA38620AEEDB090065B80A /* dnssd_clientlib.c */; };
FFFA38650AEEDB130065B80A /* dnssd_clientstub.c in Sources */ = {isa = PBXBuildFile; fileRef = FFFA38640AEEDB130065B80A /* dnssd_clientstub.c */; };
FFFA38660AEEDB2B0065B80A /* dnssd_ipc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5E11B5A04A28126019798ED /* dnssd_ipc.c */; };
remoteGlobalIDString = 03067D640C83A3700022BE1F;
remoteInfo = "Build Some";
};
- D284BDEA0ADD77F60027CCDF /* PBXContainerItemProxy */ = {
+ 4AE471690EAFF83800A6C5AD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = DB2CC4530662DD6800335AB3;
- remoteInfo = dns_sd.jar;
- };
- D284BEB40ADD809A0027CCDF /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = DB2CC4530662DD6800335AB3;
+ remoteGlobalIDString = 4AE471670EAFF81900A6C5AD;
remoteInfo = dns_sd.jar;
};
D284BF250ADD814F0027CCDF /* PBXContainerItemProxy */ = {
4A8202520C56C36500DDFD48 /* libpfkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libpfkey.h; sourceTree = "<group>"; };
4A8202530C56C36600DDFD48 /* pfkey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pfkey.c; sourceTree = "<group>"; };
4AAE0C7A0C68E97F003882A5 /* mDNSResponderHelper.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mDNSResponderHelper.8; sourceTree = SOURCE_ROOT; };
+ 4AE9B0480F39448B0080B59D /* safe_vproc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = safe_vproc.c; sourceTree = "<group>"; };
+ 4AE9B0490F39448B0080B59D /* safe_vproc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = safe_vproc.h; sourceTree = "<group>"; };
654BE64F02B63B93000001D1 /* mDNSEmbeddedAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mDNSEmbeddedAPI.h; path = ../mDNSCore/mDNSEmbeddedAPI.h; sourceTree = "<group>"; };
654BE65002B63B93000001D1 /* mDNSDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mDNSDebug.h; path = ../mDNSCore/mDNSDebug.h; sourceTree = "<group>"; };
65713D46025A293200000109 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = "<absolute>"; };
FF2C5FB20A48B86E0066DA11 /* RegisterRecordListener.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = RegisterRecordListener.java; path = ../mDNSShared/Java/RegisterRecordListener.java; sourceTree = SOURCE_ROOT; };
FF354EB108516C63007C00E1 /* installtool */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = installtool; path = PreferencePane/installtool; sourceTree = SOURCE_ROOT; };
FF485D5105632E0000130380 /* mDNSResponder.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = mDNSResponder.8; path = ../mDNSShared/mDNSResponder.8; sourceTree = SOURCE_ROOT; };
+ FF5852100DD27BD300862BDF /* ClientCommon.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ClientCommon.c; path = ../Clients/ClientCommon.c; sourceTree = SOURCE_ROOT; };
FF85880B0BD599F40080D89F /* mDNSResponder.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mDNSResponder.sb; sourceTree = SOURCE_ROOT; };
FFA572390AF18F1C0055A0F1 /* libdns_sd_debug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdns_sd_debug.a; sourceTree = BUILT_PRODUCTS_DIR; };
FFA572450AF18F450055A0F1 /* libdns_sd_profile.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdns_sd_profile.a; sourceTree = BUILT_PRODUCTS_DIR; };
FFA572630AF190C20055A0F1 /* dns_sd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dns_sd.h; path = ../mDNSShared/dns_sd.h; sourceTree = SOURCE_ROOT; };
FFB765840AEED9C700583A2C /* libdns_sd.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdns_sd.a; sourceTree = BUILT_PRODUCTS_DIR; };
FFCB6D73075D539900B8AF62 /* PlatformCommon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PlatformCommon.c; path = ../mDNSShared/PlatformCommon.c; sourceTree = SOURCE_ROOT; };
- FFD41DDA0664157900F0C438 /* dns_sd.jar */ = {isa = PBXFileReference; explicitFileType = archive.jar; includeInIndex = 0; path = dns_sd.jar; sourceTree = BUILT_PRODUCTS_DIR; };
FFE6935007C2CA7F00283007 /* ConfigurationAuthority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConfigurationAuthority.h; path = PreferencePane/ConfigurationAuthority.h; sourceTree = SOURCE_ROOT; };
FFE6935207C2CAA400283007 /* DNSServiceDiscoveryPref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DNSServiceDiscoveryPref.h; path = PreferencePane/DNSServiceDiscoveryPref.h; sourceTree = SOURCE_ROOT; };
FFE6935407C2CABD00283007 /* PrivilegedOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrivilegedOperations.h; path = PreferencePane/PrivilegedOperations.h; sourceTree = SOURCE_ROOT; };
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ FFB437150EB165BD00E17C68 /* IOKit.framework in Frameworks */,
2E0406150C3197CB00F13B59 /* libbsm.dylib in Frameworks */,
2E04070A0C31EEEC00F13B59 /* CoreFoundation.framework in Frameworks */,
2E04070B0C31EEEC00F13B59 /* SystemConfiguration.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- DB2CC4520662DD6800335AB3 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
FFA572360AF18F1C0055A0F1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
08FB7795FE84155DC02AAC07 /* mDNS Server Sources */ = {
isa = PBXGroup;
children = (
+ 4AE9B0480F39448B0080B59D /* safe_vproc.c */,
+ 4AE9B0490F39448B0080B59D /* safe_vproc.h */,
4AAE0C7A0C68E97F003882A5 /* mDNSResponderHelper.8 */,
2ECC11A50C4FEC3800CB1885 /* helpermsg-types.h */,
2E35528F0C3A95C100CA1CB7 /* helper-error.h */,
isa = PBXGroup;
children = (
D284C04D0ADD95D30027CCDF /* Info-PreferencePane.plist */,
- FFD41DDA0664157900F0C438 /* dns_sd.jar */,
D284BE730ADD80740027CCDF /* mDNSResponder */,
D284BE950ADD80800027CCDF /* mDNSResponder.debug */,
D284BEA30ADD808B0027CCDF /* mDNS */,
children = (
6575FC20022EB7AA00000109 /* SamplemDNSClient.c */,
FF1C919F07021E3F001048AB /* dns-sd.c */,
+ FF5852100DD27BD300862BDF /* ClientCommon.c */,
);
name = "Command-Line Clients";
sourceTree = "<group>";
2ECC11A80C4FEC3800CB1885 /* helpermsg-types.h in Headers */,
2E8165E80C5980E300485EB2 /* libpfkey.h in Headers */,
2E8165EA0C5980F700485EB2 /* ipsec_strerror.h in Headers */,
+ 4AE9B04C0F39448B0080B59D /* safe_vproc.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2EDC5E750C39EA640092701B /* helper-server.h in Headers */,
2E3552900C3A95C100CA1CB7 /* helper-error.h in Headers */,
2ECC11A60C4FEC3800CB1885 /* helpermsg-types.h in Headers */,
+ 4AE9B0950F3A52AE0080B59D /* safe_vproc.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2EDC5E740C39EA640092701B /* helper-server.h in Headers */,
2E3552910C3A95C100CA1CB7 /* helper-error.h in Headers */,
2ECC11A70C4FEC3800CB1885 /* helpermsg-types.h in Headers */,
+ 4AE9B0940F3A52AE0080B59D /* safe_vproc.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
};
/* End PBXHeadersBuildPhase section */
-/* Begin PBXJavaArchiveBuildPhase section */
- DB2CC4510662DD6800335AB3 /* JavaArchive */ = {
- isa = PBXJavaArchiveBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXJavaArchiveBuildPhase section */
-
-/* Begin PBXLibraryTarget section */
- DB2CC4530662DD6800335AB3 /* dns_sd.jar */ = {
- isa = PBXLibraryTarget;
- buildConfigurationList = D284BE1C0ADD78180027CCDF /* Build configuration list for PBXLibraryTarget "dns_sd.jar" */;
+/* Begin PBXLegacyTarget section */
+ 4AE471670EAFF81900A6C5AD /* dns_sd.jar */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "-f ${SRCROOT}/../mDNSPosix/Makefile OBJDIR=${CONFIGURATION_TEMP_DIR}/dns_sd.jar.build BUILDDIR=${BUILT_PRODUCTS_DIR} SHAREDDIR=${SRCROOT}/../mDNSShared os=x JavaForXcode_$(ACTION)";
+ buildConfigurationList = 4AE471770EAFF84000A6C5AD /* Build configuration list for PBXLegacyTarget "dns_sd.jar" */;
buildPhases = (
- DB2CC4500662DD6800335AB3 /* Sources */,
- DB2CC4510662DD6800335AB3 /* JavaArchive */,
- DB2CC4520662DD6800335AB3 /* Frameworks */,
- DB2CC4550662DE1700335AB3 /* ShellScript */,
- FFD41DDD06641B4200F0C438 /* ShellScript */,
);
+ buildToolPath = /usr/bin/make;
+ buildWorkingDirectory = "";
comments = "Multiplatform .jar file that implements Java interface to DNS-SD";
dependencies = (
);
name = dns_sd.jar;
- productInstallPath = /System/Library/Java/Extensions;
+ passBuildSettingsInEnvironment = 1;
productName = dns_sd.jar;
- productReference = FFD41DDA0664157900F0C438 /* dns_sd.jar */;
};
-/* End PBXLibraryTarget section */
+/* End PBXLegacyTarget section */
/* Begin PBXNativeTarget section */
2E0405EF0C31955500F13B59 /* mDNSResponderHelper */ = {
);
comments = "Platform-specific JNI library that bridges dns_sd.jar to <dns_sd.h>.";
dependencies = (
- D284BEB30ADD809A0027CCDF /* PBXTargetDependency */,
+ 4AE4716A0EAFF83800A6C5AD /* PBXTargetDependency */,
);
name = libjdns_sd.jnilib;
productInstallPath = /usr/lib/java;
isa = PBXNativeTarget;
buildConfigurationList = D284BED60ADD80A20027CCDF /* Build configuration list for PBXNativeTarget "dnsextd" */;
buildPhases = (
- 030BBF010CE13A2800472F0C /* ShellScript */,
D284BEC20ADD80A20027CCDF /* Headers */,
D284BEC40ADD80A20027CCDF /* Sources */,
D284BECE0ADD80A20027CCDF /* Frameworks */,
2E0405EF0C31955500F13B59 /* mDNSResponderHelper */,
D284BE970ADD808B0027CCDF /* mDNS tool */,
D284BEA50ADD80920027CCDF /* dns-sd tool */,
- DB2CC4530662DD6800335AB3 /* dns_sd.jar */,
+ 4AE471670EAFF81900A6C5AD /* dns_sd.jar */,
D284BEB20ADD809A0027CCDF /* libjdns_sd.jnilib */,
D284BEBF0ADD80A20027CCDF /* dnsextd */,
D284BEDB0ADD80A70027CCDF /* ddnswriteconfig */,
D284BEF90ADD80B00027CCDF /* InfoPlist.strings in Resources */,
D284BEFB0ADD80B00027CCDF /* inprogress.tiff in Resources */,
D284BEFC0ADD80B00027CCDF /* installtool in Resources */,
- D284C04E0ADD95D30027CCDF /* Info-PreferencePane.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
shellPath = /bin/sh;
shellScript = "if [ -e \"${SDKROOT}/usr/lib/libipsec.dylib\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/ipsec_options.h\"\ntouch \"${CONFIGURATION_TEMP_DIR}/ipsec_options.h\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/libipsec.a\"\nelse\necho \"#define MDNS_NO_IPSEC 1\" > ${CONFIGURATION_TEMP_DIR}/ipsec_options.h\ntouch \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfor i in ${ARCHS}\ndo\nccflags=\"-arch $i $ccflags\"\ndone\ncc ${ccflags} \"${CONFIGURATION_TEMP_DIR}/empty.c\" -c -o \"${CONFIGURATION_TEMP_DIR}/libipsec.a\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfi\n";
};
- 030BBF010CE13A2800472F0C /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "rm -f \"${CONFIGURATION_TEMP_DIR}/ipsec_options.h\"\ntouch \"${CONFIGURATION_TEMP_DIR}/ipsec_options.h\"\n";
- showEnvVarsInLog = 0;
- };
D284BE510ADD80740027CCDF /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -e \"${SDKROOT}/usr/local/include/dnsinfo.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/dnsinfo.h\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nelse\necho \"#define MDNS_NO_DNSINFO 1\" > ${CONFIGURATION_TEMP_DIR}/dnsinfo.h\ntouch \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfor i in ${ARCHS}\ndo\nccflags=\"-arch $i $ccflags\"\ndone\ncc ${ccflags} \"${CONFIGURATION_TEMP_DIR}/empty.c\" -c -o \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfi\n\nif [ -e \"${SDKROOT}/usr/include/sandbox.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nelse\necho \"#define MDNS_NO_SANDBOX 1\" > \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nfi\n";
+ shellScript = "if [ -e \"${SDKROOT}/usr/local/include/dnsinfo.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/dnsinfo.h\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nelse\necho \"#define MDNS_NO_DNSINFO 1\" > ${CONFIGURATION_TEMP_DIR}/dnsinfo.h\ntouch \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfor i in ${ARCHS}\ndo\nccflags=\"-arch $i $ccflags\"\ndone\ncc ${ccflags} \"${CONFIGURATION_TEMP_DIR}/empty.c\" -c -o \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfi\n\nif [ -e \"${SDKROOT}/usr/include/sandbox.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nelse\necho \"#define MDNS_NO_SANDBOX 1\" > \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nfi\n\nif [ -e \"${SDKROOT}/usr/include/vproc.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/vproc.h\"\nelse\ntouch \"${CONFIGURATION_TEMP_DIR}/vproc.h\"\nfi\n\nif [ -e \"${SDKROOT}/System/Library/Frameworks/IOKit.framework/PrivateHeaders/pwr_mgt/IOPMLibPrivate.h\" ]\nthen\nrm -rf \"${CONFIGURATION_TEMP_DIR}/IOKit\"\nelse\nmkdir -p \"${CONFIGURATION_TEMP_DIR}/IOKit/pwr_mgt\"\ntouch \"${CONFIGURATION_TEMP_DIR}/IOKit/pwr_mgt/IOPMLibPrivate.h\"\nfi\n";
};
D284BE6C0ADD80740027CCDF /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
shellPath = /bin/sh;
shellScript = "if [ -e \"${SDKROOT}/usr/local/include/dnsinfo.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/dnsinfo.h\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nelse\necho \"#define MDNS_NO_DNSINFO 1\" > ${CONFIGURATION_TEMP_DIR}/dnsinfo.h\ntouch \"${CONFIGURATION_TEMP_DIR}/empty.c\"\ncc -arch i386 -arch ppc \"${CONFIGURATION_TEMP_DIR}/empty.c\" -c -o \"${CONFIGURATION_TEMP_DIR}/libdnsinfo.a\"\nrm -f \"${CONFIGURATION_TEMP_DIR}/empty.c\"\nfi\n\nif [ -e \"${SDKROOT}/usr/include/sandbox.h\" ]\nthen\nrm -f \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nelse\necho \"#define MDNS_NO_SANDBOX 1\" > \"${CONFIGURATION_TEMP_DIR}/sandbox.h\"\nfi\n";
};
- DB2CC4550662DE1700335AB3 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 12;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "javah -force -J-Xbootclasspath/p:${CONFIGURATION_TEMP_DIR}/dns_sd.jar.build/JavaClasses -o ${CONFIGURATION_TEMP_DIR}/dns_sd.jar.build/DNSSD.java.h com.apple.dnssd.AppleDNSSD com.apple.dnssd.AppleBrowser com.apple.dnssd.AppleResolver com.apple.dnssd.AppleRegistration com.apple.dnssd.AppleQuery com.apple.dnssd.AppleDomainEnum com.apple.dnssd.AppleService com.apple.dnssd.AppleDNSRecord com.apple.dnssd.AppleRecordRegistrar";
- };
FF045B6A0C7E4AA600448140 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
shellPath = /bin/tcsh;
shellScript = "# Install plist to tell launchd how to start dnsextd\nmkdir -p ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons\ncp ${SRCROOT}/LaunchDaemonInfo.dnsextd.plist ${DSTROOT}${SYSTEM_LIBRARY_DIR}/LaunchDaemons/com.apple.dnsextd.plist\n";
};
- FFD41DDD06641B4200F0C438 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "rm -f ${CONFIGURATION_BUILD_DIR}/dns_sd";
- };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2E0405F60C31961100F13B59 /* helpermsg.defs in Sources */,
2E96A51D0C39BDAC0087C4D2 /* helper-main.c in Sources */,
2E8165E90C5980EE00485EB2 /* pfkey.c in Sources */,
+ 4AE9B04B0F39448B0080B59D /* safe_vproc.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D284BE630ADD80740027CCDF /* daemon.c in Sources */,
2E04061F0C3198B700F13B59 /* helpermsg.defs in Sources */,
2E96A5320C39C1A50087C4D2 /* helper-stubs.c in Sources */,
+ 4AE9B0930F3A52A20080B59D /* safe_vproc.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D284BE8B0ADD80800027CCDF /* daemon.c in Sources */,
2E0406200C3198B700F13B59 /* helpermsg.defs in Sources */,
2E96A5300C39C1A50087C4D2 /* helper-stubs.c in Sources */,
+ 4AE9B0920F3A52A10080B59D /* safe_vproc.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
D284BEA80ADD80920027CCDF /* dns-sd.c in Sources */,
+ FFF589B70E37F66800EF515C /* ClientCommon.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D284BECD0ADD80A20027CCDF /* PlatformCommon.c in Sources */,
2EAE955A0C31F4D30021F738 /* helpermsg.defs in Sources */,
2E35529E0C3A9E7600CA1CB7 /* helper-stubs.c in Sources */,
- 4A8202650C56C4C900DDFD48 /* pfkey.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D284BEFE0ADD80B00027CCDF /* DNSServiceDiscoveryPref.m in Sources */,
D284BEFF0ADD80B00027CCDF /* PrivilegedOperations.c in Sources */,
D284BF000ADD80B00027CCDF /* ConfigurationAuthority.c in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- DB2CC4500662DD6800335AB3 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DB2CC4560662DE4500335AB3 /* BaseListener.java in Sources */,
- DB2CC4570662DE4600335AB3 /* BrowseListener.java in Sources */,
- DB2CC4580662DE4700335AB3 /* DNSRecord.java in Sources */,
- DB2CC4590662DE4700335AB3 /* DNSSD.java in Sources */,
- DB2CC45A0662DE4800335AB3 /* DNSSDException.java in Sources */,
- DB2CC45B0662DE4900335AB3 /* DNSSDRegistration.java in Sources */,
- DB2CC45C0662DE4900335AB3 /* DNSSDService.java in Sources */,
- DB2CC45D0662DE4A00335AB3 /* DomainListener.java in Sources */,
- DB2CC45E0662DE4B00335AB3 /* QueryListener.java in Sources */,
- DB2CC45F0662DE4C00335AB3 /* RegisterListener.java in Sources */,
- DB2CC4600662DE4C00335AB3 /* ResolveListener.java in Sources */,
- DB2CC4610662DE4D00335AB3 /* TXTRecord.java in Sources */,
- FF2C5FB10A48B8680066DA11 /* DNSSDRecordRegistrar.java in Sources */,
- FF2C5FB30A48B86E0066DA11 /* RegisterRecordListener.java in Sources */,
+ FFF589C10E37F67E00EF515C /* ClientCommon.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
target = 03067D640C83A3700022BE1F /* Build Some */;
targetProxy = 03067D850C849CC30022BE1F /* PBXContainerItemProxy */;
};
- D284BEB30ADD809A0027CCDF /* PBXTargetDependency */ = {
+ 4AE4716A0EAFF83800A6C5AD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = DB2CC4530662DD6800335AB3 /* dns_sd.jar */;
- targetProxy = D284BEB40ADD809A0027CCDF /* PBXContainerItemProxy */;
+ target = 4AE471670EAFF81900A6C5AD /* dns_sd.jar */;
+ targetProxy = 4AE471690EAFF83800A6C5AD /* PBXContainerItemProxy */;
};
D284BF260ADD814F0027CCDF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 00AD62BB032D7A0C0CCA2C71 /* Build More */;
targetProxy = FFB7657C0AEED97F00583A2C /* PBXContainerItemProxy */;
};
- FFD41DDB0664169900F0C438 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = DB2CC4530662DD6800335AB3 /* dns_sd.jar */;
- targetProxy = D284BDEA0ADD77F60027CCDF /* PBXContainerItemProxy */;
- };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
HEADER_SEARCH_PATHS = "${CONFIGURATION_TEMP_DIR}";
INSTALL_PATH = /usr/sbin;
};
name = Development;
};
- D284BE1D0ADD78180027CCDF /* Development */ = {
+ 4AE471680EAFF81900A6C5AD /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CONFIGURATION_BUILD_DIR = "${BUILD_DIR}";
- CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
+ COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- INSTALL_PATH = "${SYSTEM_LIBRARY_DIR}/Java/Extensions";
- JAVA_ARCHIVE_CLASSES = YES;
- JAVA_ARCHIVE_COMPRESSION = YES;
- JAVA_ARCHIVE_TYPE = JAR;
- JAVA_COMPILER_DEBUGGING_SYMBOLS = NO;
- JAVA_COMPILER_SOURCE_VERSION = 1.4;
- JAVA_COMPILER_TARGET_VM_VERSION = 1.4;
- JAVA_SOURCE_SUBDIR = .;
- LIBRARY_STYLE = STATIC;
- OTHER_CFLAGS = "";
- OTHER_LDFLAGS = "";
- OTHER_LIBTOOL_FLAGS = "";
- OTHER_REZFLAGS = "";
- PRODUCT_NAME = dns_sd;
- PURE_JAVA = YES;
- REZ_EXECUTABLE = YES;
- SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = dns_sd.jar;
};
name = Development;
};
CONFIGURATION_BUILD_DIR = "${BUILD_DIR}";
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
D284BE2C0ADD78180027CCDF /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+ DEAD_CODE_STRIPPING = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"APPLE_OSX_mDNSResponder=1",
"__MigTypeCheck=1",
);
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
MVERS = "\"(Engineering Build)\"";
- OTHER_CFLAGS = "-DUSE_SYSTEMCONFIGURATION_PRIVATE_HEADERS";
+ OTHER_CFLAGS = (
+ "-DUSE_SYSTEMCONFIGURATION_PRIVATE_HEADERS",
+ "-fwrapv",
+ );
PREBINDING = NO;
+ STRIP_STYLE = debugging;
WARNING_CFLAGS = (
"-W",
"-Wall",
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
FRAMEWORK_SEARCH_PATHS = "";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
HEADER_SEARCH_PATHS = (
../mDNSShared,
INSTALL_PATH = /usr/sbin;
LIBRARY_SEARCH_PATHS = "\"${CONFIGURATION_TEMP_DIR}\"";
MACOSX_DEPLOYMENT_TARGET = 10.4;
+ ORDER_FILE = "${SRCROOT}/mDNSResponder.order";
OTHER_CFLAGS = (
"$(inherited)",
"-no-cpp-precomp",
OTHER_REZFLAGS = "";
PRODUCT_NAME = mDNSResponder;
REZ_EXECUTABLE = YES;
- SECTORDER_FLAGS = (
- "-sectorder",
- __TEXT,
- __text,
- mDNSResponder.order,
- );
- STRIPFLAGS = "-S";
};
name = Development;
};
__text,
mDNSResponder.order,
);
- STRIPFLAGS = "-S";
};
name = Development;
};
CONFIGURATION_BUILD_DIR = "${BUILD_DIR}";
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
INSTALL_PATH = /usr/bin;
MACOSX_DEPLOYMENT_TARGET = 10.4;
PRODUCT_NAME = mDNS;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
};
name = Development;
};
CONFIGURATION_BUILD_DIR = "${BUILD_DIR}";
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
HEADER_SEARCH_PATHS = ../mDNSShared;
INSTALL_PATH = /usr/bin;
PRODUCT_NAME = "dns-sd";
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
};
name = Development;
};
DYLIB_CURRENT_VERSION = 1;
EXECUTABLE_EXTENSION = jnilib;
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
HEADER_SEARCH_PATHS = (
../mDNSShared,
"${SYSTEM_LIBRARY_DIR}/Frameworks/JavaVM.framework/Versions/A/Headers",
"${SYSTEM_LIBRARY_DIR}/Frameworks/JavaVM.framework/Versions/1.3.1/Headers",
- "${CONFIGURATION_TEMP_DIR}/dns_sd.jar.build",
+ "${PROJECT_DERIVED_FILE_DIR}",
);
INSTALL_PATH = /usr/lib/java;
LIBRARY_STYLE = DYNAMIC;
PRODUCT_NAME = libjdns_sd;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
};
name = Development;
};
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
FRAMEWORK_SEARCH_PATHS = "";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
HEADER_SEARCH_PATHS = (
"${APPLE_INTERNAL_DEVELOPER_DIR}/Headers",
PRODUCT_NAME = dnsextd;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
YACC = "/usr/bin/bison -y";
};
name = Development;
CONFIGURATION_BUILD_DIR = "${BUILD_DIR}";
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
INSTALL_PATH = "/Library/Application Support/Bonjour";
- MACOSX_DEPLOYMENT_TARGET = 10.4;
+ MACOSX_DEPLOYMENT_TARGET = "";
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = ddnswriteconfig;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
};
name = Development;
};
CONFIGURATION_TEMP_DIR = "${BUILD_DIR}/mDNSResponder.build";
EXPORTED_SYMBOLS_FILE = "";
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
INFOPLIST_FILE = "PreferencePane/Info-PreferencePane.plist";
INSTALL_PATH = /AppleInternal/Library/PreferencePanes;
- MACOSX_DEPLOYMENT_TARGET = 10.4;
+ MACOSX_DEPLOYMENT_TARGET = "";
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "-twolevel_namespace";
OTHER_REZFLAGS = "";
PRODUCT_NAME = Bonjour;
SECTORDER_FLAGS = "";
- STRIPFLAGS = "-S";
WRAPPER_EXTENSION = prefPane;
};
name = Development;
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Development;
};
- D284BE1C0ADD78180027CCDF /* Build configuration list for PBXLibraryTarget "dns_sd.jar" */ = {
+ 4AE471770EAFF84000A6C5AD /* Build configuration list for PBXLegacyTarget "dns_sd.jar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- D284BE1D0ADD78180027CCDF /* Development */,
+ 4AE471680EAFF81900A6C5AD /* Development */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Development;
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple 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: safe_vproc.c,v $
+Revision 1.3 2009/02/14 00:09:53 cheshire
+Only log "Compiled without vproc_transaction support" when running on a system
+where we expect that to be available -- if running on a system that doesn't even
+have vproc_transaction, then it doesn't matter that the code was compiled without it.
+
+Revision 1.2 2009/02/09 21:16:17 mcguire
+<rdar://problem/5858533> Adopt vproc_transaction API in mDNSResponder
+additional cleanup: don't alloc memory since we currently only expect to have one transaction
+
+Revision 1.1 2009/02/06 03:06:49 mcguire
+<rdar://problem/5858533> Adopt vproc_transaction API in mDNSResponder
+
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <vproc.h>
+#include "safe_vproc.h"
+#include "mDNSDebug.h"
+
+#ifdef VPROC_HAS_TRANSACTIONS
+
+static vproc_transaction_t transaction = NULL;
+
+void safe_vproc_transaction_begin(void)
+ {
+ if (vproc_transaction_begin)
+ {
+ if (transaction) { LogMsg("safe_vproc_transaction_begin: Already have a transaction"); }
+ else transaction = vproc_transaction_begin(NULL);
+ }
+ }
+
+void safe_vproc_transaction_end(void)
+ {
+ if (vproc_transaction_end)
+ {
+ if (transaction) { vproc_transaction_end(NULL, transaction); transaction = NULL; }
+ else LogMsg("safe_vproc_transaction_end: No current transaction");
+ }
+ }
+
+#else
+
+#include <stdio.h>
+#include <CoreFoundation/CFString.h>
+
+CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
+CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
+#define OSXVers_10_6_SnowLeopard 10
+
+void safe_vproc_transaction_begin(void)
+ {
+ static int majorversion = 0;
+ if (!majorversion)
+ {
+ CFDictionaryRef vers = _CFCopySystemVersionDictionary();
+ if (vers)
+ {
+ char buildver[256];
+ CFStringRef cfbuildver = CFDictionaryGetValue(vers, _kCFSystemVersionBuildVersionKey);
+ if (cfbuildver && CFStringGetCString(cfbuildver, buildver, sizeof(buildver), kCFStringEncodingUTF8))
+ sscanf(buildver, "%d", &majorversion);
+ CFRelease(vers);
+ }
+ if (!majorversion || majorversion >= OSXVers_10_6_SnowLeopard)
+ LogMsg("Compiled without vproc_transaction support");
+ }
+ }
+
+void safe_vproc_transaction_end(void) { }
+
+#endif
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple 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: safe_vproc.h,v $
+Revision 1.1 2009/02/06 03:06:49 mcguire
+<rdar://problem/5858533> Adopt vproc_transaction API in mDNSResponder
+
+ */
+
+#ifndef __SAFE_VPROC_H
+#define __SAFE_VPROC_H
+
+extern void safe_vproc_transaction_begin(void);
+extern void safe_vproc_transaction_end(void);
+
+#endif /* __SAFE_VPROC_H */
Change History (most recent first):
$Log: Client.c,v $
+Revision 1.21 2008/11/04 19:46:01 cheshire
+Updated comment about MAX_ESCAPED_DOMAIN_NAME size (should be 1009, not 1005)
+
Revision 1.20 2007/07/27 19:30:41 cheshire
Changed mDNSQuestionCallback parameter from mDNSBool to QC_result,
to properly reflect tri-state nature of the possible responses
Revision 1.10 2003/11/14 21:27:09 cheshire
<rdar://problem/3484766>: Security: Crashing bug in mDNSResponder
-Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1005) instead of 256-byte buffers.
+Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1009) instead of 256-byte buffers.
Revision 1.9 2003/08/14 02:19:55 cheshire
<rdar://problem/3375491> Split generic ResourceRecord type into two separate types: AuthRecord and CacheRecord
Change History (most recent first):
$Log: Identify.c,v $
+Revision 1.44 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.43 2008/09/05 22:51:21 cheshire
+Minor cleanup to bring code in sync with TOT, and make "_services" metaquery work again
+
Revision 1.42 2007/07/27 19:30:41 cheshire
Changed mDNSQuestionCallback parameter from mDNSBool to QC_result,
to properly reflect tri-state nature of the possible responses
__MDNS__mDNSCoreReceive(m, msg, end, srcaddr, srcport, &AllDNSLinkGroup_v4, dstport, InterfaceID);
}
-static void NameCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
+mDNSlocal void NameCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
(void)m; // Unused
(void)question; // Unused
}
}
-static void InfoCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
+mDNSlocal void InfoCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
(void)m; // Unused
(void)question; // Unused
}
// If we've got everything we're looking for, don't need to wait any more
- if (NumHINFO && (NumAddr || NumAAAA)) StopNow = 1;
+ if (/*NumHINFO && */ (NumAddr || NumAAAA)) StopNow = 1;
}
-static void ServicesCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
+mDNSlocal void ServicesCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
(void)m; // Unused
(void)question; // Unused
if (answer->rrtype == kDNSType_PTR && mDNSSameAddress(&lastsrc, &target))
{
NumAnswers++;
- NumAddr++;
mprintf("%##s %s %##s\n", answer->name->c, DNSTypeName(answer->rrtype), answer->rdata->u.name.c);
- StopNow = 1;
}
}
-mDNSexport void WaitForAnswer(mDNS *const m, int seconds)
+mDNSlocal void WaitForAnswer(mDNS *const m, int seconds)
{
struct timeval end;
gettimeofday(&end, NULL);
FD_ZERO(&readfds);
gettimeofday(&now, NULL);
if (remain.tv_usec < now.tv_usec) { remain.tv_usec += 1000000; remain.tv_sec--; }
- if (remain.tv_sec < now.tv_sec) return;
+ if (remain.tv_sec < now.tv_sec)
+ {
+ if (!NumAnswers) printf("No response after %d seconds\n", seconds);
+ return;
+ }
remain.tv_usec -= now.tv_usec;
remain.tv_sec -= now.tv_sec;
mDNSPosixGetFDSet(m, &nfds, &readfds, &remain);
mDNSlocal mStatus StartQuery(DNSQuestion *q, char *qname, mDNSu16 qtype, const mDNSAddr *target, mDNSQuestionCallback callback)
{
+ lastsrc = zeroAddr;
if (qname) MakeDomainNameFromDNSNameString(&q->qname, qname);
+ q->InterfaceID = mDNSInterface_Any;
q->Target = target ? *target : zeroAddr;
q->TargetPort = MulticastDNSPort;
q->TargetQID = zeroID;
- q->InterfaceID = mDNSInterface_Any;
q->qtype = qtype;
q->qclass = kDNSClass_IN;
q->LongLived = mDNSfalse;
- q->ExpectUnique = mDNStrue;
+ q->ExpectUnique = mDNSfalse; // Don't want to stop after the first response packet
q->ForceMCast = mDNStrue; // Query via multicast, even for apparently uDNS names like 1.1.1.17.in-addr.arpa.
q->ReturnIntermed = mDNStrue;
q->QuestionCallback = callback;
mDNSlocal int DoQuery(DNSQuestion *q, char *qname, mDNSu16 qtype, const mDNSAddr *target, mDNSQuestionCallback callback)
{
DoOneQuery(q, qname, qtype, target, callback);
- if (StopNow == 0 && target && target->type)
+ if (StopNow == 0 && NumAnswers == 0 && target && target->type)
{
mprintf("%##s %s Trying multicast\n", q->qname.c, DNSTypeName(q->qtype));
DoOneQuery(q, qname, qtype, NULL, callback);
}
mDNS_snprintf(&buffer[64], sizeof(buffer)-64, "ip6.arpa.");
target.type = mDNSAddrType_IPv6;
- bcopy(&s6, &target.ip.v6, sizeof(target.ip.v6));
+ mDNSPlatformMemCopy(&target.ip.v6, &s6, sizeof(target.ip.v6));
DoQuery(&q, buffer, kDNSType_PTR, &target, NameCallback);
if (StopNow == 2) break;
}
if (hardware[0] || software[0])
{
- DNSQuestion q1;
printf("HINFO Hardware: %s\n", hardware);
printf("HINFO Software: %s\n", software);
- // We need to make sure the services query is targeted
- if (target.type == 0) target = hostaddr;
- StartQuery(&q1, "_services._dns-sd._udp.local.", kDNSQType_ANY, &target, ServicesCallback);
- WaitForAnswer(&mDNSStorage, 4);
- mDNS_StopQuery(&mDNSStorage, &q1);
- if (StopNow == 2) break;
}
- else if (NumAnswers)
+ else if (NumAnswers) printf("%s has no HINFO record\n", hostname);
+ else printf("Incorrect dot-local hostname, address, or no mDNSResponder running on that machine\n");
+
+ if (NumAnswers)
{
- printf("Host has no HINFO record; Best guess is ");
- if (id.b[1]) printf("mDNSResponder-%d\n", id.b[1]);
- else if (NumAAAA) printf("very early Panther build (mDNSResponder-33 or earlier)\n");
- else printf("Jaguar version of mDNSResponder with no IPv6 support\n");
+ // Because of the way we use lastsrc in ServicesCallback, we need to clear the cache to make sure we're getting fresh answers
+ mDNS *const m = &mDNSStorage;
+ mDNSu32 slot;
+ CacheGroup *cg;
+ CacheRecord *rr;
+ FORALL_CACHERECORDS(slot, cg, rr) mDNS_PurgeCacheResourceRecord(m, rr);
+ if (target.type == 0) target = hostaddr; // Make sure the services query is targeted
+ DoQuery(&q, "_services._dns-sd._udp.local.", kDNSType_PTR, &target, ServicesCallback);
+ if (StopNow == 2) break;
}
- else
- printf("Incorrect dot-local hostname, address, or no mDNSResponder running on that machine\n");
}
mDNS_Close(&mDNSStorage);
# then try typing "gmake os=xxx" instead.
#
# $Log: Makefile,v $
+# Revision 1.83 2009/02/02 19:44:06 cheshire
+# Use "-fwrapv" option to tell compiler that the code is written assuming that
+# signed arithmetic is implemented using the twos-complement representation
+# (this is pretty much universally true on today's processors).
+# <http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Code-Gen-Options.html>
+# Without this option, gcc may decide that because the C language
+# does not require processors to use twos-complement representation, that means
+# gcc is free to do some "creative" optimizations that don't preserve the overflow
+# behaviour of twos-complement arithmetic. See also "-fstrict-overflow":
+# <http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Optimize-Options.html>
+#
+# Revision 1.82 2009/01/12 22:48:00 cheshire
+# Don't need to include "." in the "#include" search path
+#
+# Revision 1.81 2009/01/11 03:20:06 mkrochma
+# <rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+#
+# Revision 1.80 2008/11/03 23:27:51 cheshire
+# Defined __MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 to stop build failures on Leopard
+#
+# Revision 1.79 2008/10/24 01:59:59 mcguire
+# <rdar://problem/6257159> Build Failure: Need to stop using Jam
+#
# Revision 1.78 2007/10/22 20:16:49 cheshire
# Got rid of jaguar and panther from list of target platforms;
# changed "os=tiger" to "os=x" (which works with both Tiger and Leopard)
LIBVERS = 1
COREDIR = ../mDNSCore
-SHAREDDIR = ../mDNSShared
+SHAREDDIR ?= ../mDNSShared
JDK = /usr/jdk
CC = @cc
CP = cp
RM = rm
LN = ln -s -f
-CFLAGS_COMMON = -I. -I$(COREDIR) -I$(SHAREDDIR) -I$(OBJDIR) -W -Wall -DPID_FILE=\"/var/run/mdnsd.pid\" -DMDNS_UDS_SERVERPATH=\"/var/run/mdnsd\"
+CFLAGS_COMMON = -I$(COREDIR) -I$(SHAREDDIR) -I$(OBJDIR) -fwrapv -W -Wall -DPID_FILE=\"/var/run/mdnsd.pid\" -DMDNS_UDS_SERVERPATH=\"/var/run/mdnsd\"
CFLAGS_PTHREAD =
LINKOPTS =
LINKOPTS_PTHREAD = -lpthread
# 1. We want to make small binaries, suitable for putting into hardware devices
# 2. Some of the code analysis warnings only work when some form of optimization is enabled
CFLAGS_DEBUG = -Os -DMDNS_DEBUGMSGS=0
-OBJDIR = objects/prod
-BUILDDIR = build/prod
+OBJDIR ?= objects/prod
+BUILDDIR ?= build/prod
STRIP = strip -S
endif
# Configure per-OS peculiarities
ifeq ($(os),solaris)
+CFLAGS_DEBUG = -O0 -DMDNS_DEBUGMSGS=0
CFLAGS_OS = -DNOT_HAVE_DAEMON -DNOT_HAVE_SA_LEN -DNOT_HAVE_SOCKLEN_T -DNOT_HAVE_IF_NAMETOINDEX \
- -DLOG_PERROR=0 -D_XPG4_2 -D__EXTENSIONS__ -DHAVE_BROKEN_RECVIF_NAME
+ -DLOG_PERROR=0 -D_XPG4_2 -D__EXTENSIONS__ -DHAVE_BROKEN_RECVIF_NAME -DTARGET_OS_SOLARIS
CC = gcc
LD = gcc -shared
LINKOPTS = -lsocket -lnsl -lresolv
else
ifeq ($(os),x)
-CFLAGS_OS = -DHAVE_IPV6 -no-cpp-precomp -Werror -Wdeclaration-after-statement #-Wunreachable-code
+# We have to define __MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 or on Leopard
+# we get build failures: ‘daemon’ is deprecated (declared at /usr/include/stdlib.h:283)
+CFLAGS_OS = -DHAVE_IPV6 -no-cpp-precomp -Werror -Wdeclaration-after-statement \
+ -D__MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 #-Wunreachable-code
CC = @gcc-4.0
LD = $(CC) -dynamiclib
LINKOPTS = -lSystem
# 'setup' sets up the build directory structure the way we want
setup:
- @if test ! -d objects ; then mkdir objects ; fi
- @if test ! -d build ; then mkdir build ; fi
- @if test ! -d $(OBJDIR) ; then mkdir $(OBJDIR) ; fi
- @if test ! -d $(BUILDDIR) ; then mkdir $(BUILDDIR) ; fi
+ @if test ! -d $(OBJDIR) ; then mkdir -p $(OBJDIR) ; fi
+ @if test ! -d $(BUILDDIR) ; then mkdir -p $(BUILDDIR) ; fi
# clean removes targets and objects
clean:
#############################################################################
# The following targets build Java wrappers for the dns-sd.h API.
+# Note that the JavaForXcode targets are used when building the project for OS X using Xcode
JAVAC = $(JDK)/bin/javac
JAVAH = $(JDK)/bin/javah
JAR = $(JDK)/bin/jar
JAVACFLAGS = $(CFLAGS) $(JAVACFLAGS_OS) -I$(JDK)/include
+JavaForXcode_: setup $(BUILDDIR)/dns_sd.jar $(PROJECT_DERIVED_FILE_DIR)/DNSSD.java.h
+ @echo $@ done
+
+$(PROJECT_DERIVED_FILE_DIR)/DNSSD.java.h: $(OBJDIR)/DNSSD.java.h
+ @if test ! -d $(PROJECT_DERIVED_FILE_DIR) ; then mkdir -p $(PROJECT_DERIVED_FILE_DIR) ; fi
+ $(CP) $< $@
+
+JavaForXcode_clean:
+ @if test -d $(OBJDIR) ; then rm -r $(OBJDIR) ; fi
+ @if test -f $(PROJECT_DERIVED_FILE_DIR)/DNSSD.java.h ; then $(RM) $(PROJECT_DERIVED_FILE_DIR)/DNSSD.java.h ; fi
+ @if test -f $(BUILDDIR)/dns_sd.jar ; then $(RM) $(BUILDDIR)/dns_sd.jar ; fi
+ @echo $@ done
+
+JavaForXcode_installhdrs:
+ @echo $@ NOOP
+
+JavaForXcode_install: JavaForXcode_ $(DSTROOT)/$(SYSTEM_LIBRARY_DIR)/Java/Extensions/dns_sd.jar
+ @echo $@ done
+
+$(DSTROOT)/$(SYSTEM_LIBRARY_DIR)/Java/Extensions/dns_sd.jar: $(BUILDDIR)/dns_sd.jar
+ @if test ! -d $(DSTROOT)/$(SYSTEM_LIBRARY_DIR)/Java/Extensions ; then mkdir -p $(DSTROOT)/$(SYSTEM_LIBRARY_DIR)/Java/Extensions ; fi
+ $(CP) $< $@
+
Java: setup $(BUILDDIR)/dns_sd.jar $(BUILDDIR)/libjdns_sd.$(LDSUFFIX)
@echo "Java wrappers done"
com.apple.dnssd.AppleRegistration \
com.apple.dnssd.AppleQuery \
com.apple.dnssd.AppleDomainEnum \
- com.apple.dnssd.AppleService
+ com.apple.dnssd.AppleService \
+ com.apple.dnssd.AppleDNSRecord \
+ com.apple.dnssd.AppleRecordRegistrar
#############################################################################
Change History (most recent first):
$Log: NetMonitor.c,v $
+Revision 1.94 2009/04/24 00:31:56 cheshire
+<rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
+Added code to display NSEC records
+
+Revision 1.93 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.92 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
+Revision 1.91 2008/11/13 22:08:07 cheshire
+Show additional records in Query packets
+
+Revision 1.90 2008/09/05 22:20:26 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+Add "UDPSocket *src" parameter in mDNSPlatformSendUDP call
+
Revision 1.89 2007/05/17 19:12:42 cheshire
Tidy up code layout
#include <stdio.h> // For printf()
#include <stdlib.h> // For malloc()
-#include <string.h> // For bcopy()
+#include <string.h> // For strrchr(), strcmp()
#include <time.h> // For "struct tm" etc.
#include <signal.h> // For SIGINT, SIGTERM
#include <netdb.h> // For gethostbyname()
InterfaceID = mDNSInterface_Any; // Send query from our unicast reply socket
}
- mDNSSendDNSMessage(&mDNSStorage, &query, qptr, InterfaceID, target, MulticastDNSPort, mDNSNULL, mDNSNULL);
+ mDNSSendDNSMessage(&mDNSStorage, &query, qptr, InterfaceID, mDNSNULL, target, MulticastDNSPort, mDNSNULL, mDNSNULL);
}
mDNSlocal void AnalyseHost(mDNS *const m, HostEntry *entry, const mDNSInterfaceID InterfaceID)
} break;
case kDNSType_AAAA: n += mprintf("%.16a", &rd->ipv6); break;
case kDNSType_SRV: n += mprintf("%##s:%d", rd->srv.target.c, mDNSVal16(rd->srv.port)); break;
+ case kDNSType_NSEC: {
+ int i;
+ for (i=0; i<255; i++)
+ if (rd->nsec.bitmap[i>>3] & (128 >> (i&7)))
+ n += mprintf("%s ", DNSTypeName(i));
+ } break;
default: {
mDNSu8 *s = rd->data;
while (s < rdend && p < buffer+MaxWidth)
if (!ptr) { DisplayError(srcaddr, ep, end, "AUTHORITY"); return; }
}
+ for (i=0; i<msg->h.numAdditionals; i++)
+ {
+ const mDNSu8 *ep = ptr;
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt);
+ if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; }
+ DisplayResourceRecord(srcaddr, " ", &pkt.r.resrec);
+ }
+
if (entry) AnalyseHost(m, entry, InterfaceID);
}
else if (inet_pton(AF_INET6, argv[i], &s6) == 1)
{
a.type = mDNSAddrType_IPv6;
- bcopy(&s6, &a.ip.v6, sizeof(a.ip.v6));
+ mDNSPlatformMemCopy(&a.ip.v6, &s6, sizeof(a.ip.v6));
}
else
{
Change History (most recent first):
$Log: PosixDaemon.c,v $
+Revision 1.49 2009/04/30 20:07:51 mcguire
+<rdar://problem/6822674> Support multiple UDSs from launchd
+
+Revision 1.48 2009/04/11 01:43:28 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.47 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
+Revision 1.46 2008/11/03 23:09:15 cheshire
+Don't need to include mDNSDebug.h as well as mDNSEmbeddedAPI.h
+
+Revision 1.45 2008/10/03 18:25:17 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
+Revision 1.44 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
Revision 1.43 2007/10/22 20:05:34 cheshire
Use mDNSPlatformSourceAddrForDest instead of FindSourceAddrForIP
#include <sys/types.h>
#include "mDNSEmbeddedAPI.h"
-#include "mDNSDebug.h"
#include "mDNSPosix.h"
+#include "mDNSUNP.h" // For daemon()
#include "uds_daemon.h"
#include "PlatformCommon.h"
mDNSPlatformSourceAddrForDest(&DynDNSIP, &dummy);
if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL);
if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL);
- m->MainCallback(m, mStatus_ConfigChanged);
+ mDNS_ConfigChanged(m);
}
// Do appropriate things at startup with command line arguments. Calls exit() if unhappy.
mDNSlocal void DumpStateLog(mDNS *const m)
// Dump a little log of what we've been up to.
{
- LogMsgIdent(mDNSResponderVersionString, "---- BEGIN STATE LOG ----");
+ LogMsg("---- BEGIN STATE LOG ----");
udsserver_info(m);
- LogMsgIdent(mDNSResponderVersionString, "---- END STATE LOG ----");
+ LogMsg("---- END STATE LOG ----");
}
mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit.
ParseCmdLinArgs(argc, argv);
- LogMsgIdent(mDNSResponderVersionString, "starting");
+ LogMsg("%s starting", mDNSResponderVersionString);
err = mDNS_Init(&mDNSStorage, &PlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses,
mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext);
if (mStatus_NoError == err)
- err = udsserver_init(dnssd_InvalidSocket);
+ err = udsserver_init(mDNSNULL, 0);
Reconfigure(&mDNSStorage);
if (mStatus_NoError == err)
err = MainLoop(&mDNSStorage);
- LogMsgIdent(mDNSResponderVersionString, "stopping");
+ LogMsg("%s stopping", mDNSResponderVersionString);
mDNS_Close(&mDNSStorage);
- if (udsserver_exit(dnssd_InvalidSocket) < 0)
+ if (udsserver_exit() < 0)
LogMsg("ExitCallback: udsserver_exit failed");
#if MDNS_DEBUGMSGS > 0
// No-op, for now
}
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
// For convenience when using the "strings" command, this is the last thing in the file
#if mDNSResponderVersion > 1
Change History (most recent first):
$Log: ProxyResponder.c,v $
+Revision 1.45 2008/11/04 19:46:01 cheshire
+Updated comment about MAX_ESCAPED_DOMAIN_NAME size (should be 1009, not 1005)
+
Revision 1.44 2007/04/22 20:16:25 cheshire
Fix compiler errors (const parameter declarations)
Revision 1.24 2003/11/14 21:27:09 cheshire
<rdar://problem/3484766>: Security: Crashing bug in mDNSResponder
-Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1005) instead of 256-byte buffers.
+Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1009) instead of 256-byte buffers.
Revision 1.23 2003/10/30 19:39:28 cheshire
Fix warnings on certain compilers
Change History (most recent first):
$Log: Responder.c,v $
+Revision 1.36 2009/01/15 03:39:08 mkrochma
+Fix warning about ignoring return value of daemon
+
+Revision 1.35 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.34 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
Revision 1.33 2007/04/16 20:49:39 cheshire
Fix compile errors for mDNSPosix build
#include "mDNSEmbeddedAPI.h"// Defines the interface to the client layer above
#include "mDNSPosix.h" // Defines the specific types needed to run mDNS on this platform
+#include "mDNSUNP.h" // For daemon()
#include <assert.h>
#include <stdio.h> // For printf()
while (optind < argc)
{
gServiceText[gServiceTextLen] = strlen(argv[optind]);
- memcpy(gServiceText+gServiceTextLen+1, argv[optind], gServiceText[gServiceTextLen]);
+ mDNSPlatformMemCopy(gServiceText+gServiceTextLen+1, argv[optind], gServiceText[gServiceTextLen]);
gServiceTextLen += 1 + gServiceText[gServiceTextLen];
optind++;
}
unsigned int newlen = textLen + 1 + len;
if (len == 0 || newlen >= sizeof(text)) break;
text[textLen] = len;
- memcpy(text + textLen + 1, rawText, len);
+ mDNSPlatformMemCopy(text + textLen + 1, rawText, len);
textLen = newlen;
}
else
// because printf has no format specified for pid_t.
if (gDaemon) {
+ int result;
if (gMDNSPlatformPosixVerboseLevel > 0) {
fprintf(stderr, "%s: Starting in daemon mode\n", gProgramName);
}
- daemon(0,0);
- {
+ result = daemon(0,0);
+ if (result == 0) {
FILE *fp;
int junk;
junk = fclose(fp);
assert(junk == 0);
}
+ } else {
+ fprintf(stderr, "%s: Could not run as daemon - exiting\n", gProgramName);
+ exit(result);
}
} else {
if (gMDNSPlatformPosixVerboseLevel > 0) {
Change History (most recent first):
$Log: mDNSPosix.c,v $
+Revision 1.108 2009/01/25 03:16:46 mkrochma
+Added skeleton definition of mDNSPlatformSetLocalARP
+
+Revision 1.107 2009/01/07 08:25:03 mkrochma
+Added skeleton definition of mDNSPlatformUpdateProxyList
+
+Revision 1.106 2008/10/22 17:19:57 cheshire
+Don't need to define BPF_fd any more (it's now per-interface, not global)
+
+Revision 1.105 2008/10/03 23:34:08 cheshire
+Added skeleton definition of mDNSPlatformSendRawPacket
+
+Revision 1.104 2008/09/05 22:16:48 cheshire
+<rdar://problem/3988320> Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+Add "UDPSocket *src" parameter in mDNSPlatformSendUDP
+
Revision 1.103 2007/10/02 19:31:17 cheshire
In ParseDNSServers, should use strncasecmp for case-insensitive compare
// mDNS core calls this routine when it needs to send a packet.
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
- mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstPort)
+ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, mDNSIPPort dstPort)
{
int err = 0;
struct sockaddr_storage to;
PosixNetworkInterface * thisIntf = (PosixNetworkInterface *)(InterfaceID);
int sendingsocket = -1;
+ (void)src; // Will need to use this parameter once we implement mDNSPlatformUDPSocket/mDNSPlatformUDPClose
+
assert(m != NULL);
assert(msg != NULL);
assert(end != NULL);
{
(void)sock; // Unused
}
+
+mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
+ {
+ (void)m; // Unused
+ (void)InterfaceID; // Unused
+ }
+
+mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
+ {
+ (void)msg; // Unused
+ (void)end; // Unused
+ (void)InterfaceID; // Unused
+ }
+
+mDNSexport void mDNSPlatformSetLocalARP(const mDNSv4Addr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
+ {
+ (void)tpa; // Unused
+ (void)tha; // Unused
+ (void)InterfaceID; // Unused
+ }
mDNSexport mStatus mDNSPlatformTLSSetupCerts(void)
{
Change History (most recent first):
$Log: mDNSUNP.c,v $
+Revision 1.40 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.39 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
+Revision 1.38 2009/01/10 22:54:42 mkrochma
+<rdar://problem/5797544> Fixes from Igor Seleznev to get mdnsd working on Linux
+
+Revision 1.37 2008/10/23 22:33:24 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
Revision 1.36 2008/04/21 18:21:22 mkrochma
<rdar://problem/5877307> Need to free ifi_netmask
Submitted by Igor Seleznev
#include <stdlib.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
+#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#if defined(AF_INET6) && HAVE_IPV6 && !HAVE_LINUX
#include <net/if_var.h>
#include <netinet/in_var.h>
-// NOTE: netinet/in_var.h implicitly includes netinet6/in6_var.h for us
+// Note: netinet/in_var.h implicitly includes netinet6/in6_var.h for us
#endif
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
struct in6_ifreq ifr6;
if (sockf6 == -1)
sockf6 = socket(AF_INET6, SOCK_DGRAM, 0);
- bzero(&ifr6, sizeof(ifr6));
+ memset(&ifr6, 0, sizeof(ifr6));
memcpy(&ifr6.ifr_name, &ifr->ifr_name, sizeof(ifr6.ifr_name ));
memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) goto gotError;
strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
#endif
pktp->ipi_ifindex = sdl->sdl_index;
+#ifdef HAVE_BROKEN_RECVIF_NAME
+ if (sdl->sdl_index == 0) {
+ pktp->ipi_ifindex = *(uint_t*)sdl;
+ }
+#endif
assert(pktp->ipi_ifname[IFI_NAME - 1] == 0);
// null terminated because of memset above
continue;
#define DNS_LABEL_MAXLEN 63
// Maximum length of a single DNS label
-#define DNS_NAME_MAXLEN 255
+#define DNS_NAME_MAXLEN 256
// Maximum length of a DNS name
//----------
// This enables verbose syslog messages
// If zero, only "imporant" messages will appear in syslog
-#define k_hostname_maxlen 255
+#define k_hostname_maxlen 256
// As per RFC1034 and RFC1035
#define k_aliases_max 15
#define k_addrs_max 15
temp_config = (config_t *) malloc (sizeof (config_t));
if (temp_config)
{
- // NOTE: This code will leak memory if initialisation fails
+ // Note: This code will leak memory if initialisation fails
// repeatedly. This should only happen in the case of a memory
// error, so I'm not sure if it's a meaningful problem. - AW
*temp_config = k_empty_config;
-Microsoft Visual Studio Solution File, Format Version 8.00\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLL", "mDNSWindows\DLL\dnssd.vcproj", "{AB581101-18F0-46F6-B56A-83A6B1EA657E}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mDNSResponder", "mDNSWindows\SystemService\Service.vcproj", "{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NSPTool", "mDNSWindows\NSPTool\NSPTool.vcproj", "{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdnsNSP", "mDNSWindows\mdnsNSP\mdnsNSP.vcproj", "{F4F15529-F0EB-402F-8662-73C5797EE557}"\r
ProjectSection(ProjectDependencies) = postProject\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPlugin", "Clients\ExplorerPlugin\ExplorerPlugin.vcproj", "{BB8AC1B5-6587-4163-BDC6-788B157705CA}"\r
ProjectSection(ProjectDependencies) = postProject\r
- {AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5} = {3A2B6325-3053-4236-84BD-AA9BE2E323E5}\r
EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrinterSetupWizard", "Clients\PrinterSetupWizard\PrinterSetupWizard.vcproj", "{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}"\r
ProjectSection(ProjectDependencies) = postProject\r
- {AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLL.NET", "mDNSWindows\DLL.NET\dnssd_NET.vcproj", "{9C6701E2-82B7-44B7-9B5E-3897D9153F79}"\r
- ProjectSection(ProjectDependencies) = postProject\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5} = {3A2B6325-3053-4236-84BD-AA9BE2E323E5}\r
EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ControlPanel", "mDNSWindows\ControlPanel\ControlPanel.vcproj", "{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}"\r
{AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
EndProjectSection\r
EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrinterSetupWizardLocRes", "Clients\PrinterSetupWizard\PrinterSetupWizardLocRes.vcproj", "{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrinterSetupWizardLocRes", "Clients\PrinterSetupWizard\PrinterSetupWizardLocRes.vcproj", "{967F5375-0176-43D3-ADA3-22EE25551C37}"\r
ProjectSection(ProjectDependencies) = postProject\r
{AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
EndProjectSection\r
EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrinterSetupWizardRes", "Clients\PrinterSetupWizard\PrinterSetupWizardRes.vcproj", "{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PrinterSetupWizardRes", "Clients\PrinterSetupWizard\PrinterSetupWizardRes.vcproj", "{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}"\r
ProjectSection(ProjectDependencies) = postProject\r
{AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
EndProjectSection\r
EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPluginLocRes", "Clients\ExplorerPlugin\ExplorerPluginLocRes.vcproj", "{BB8AC1B5-6587-4163-BDC6-788B157705CA}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPluginLocRes", "Clients\ExplorerPlugin\ExplorerPluginLocRes.vcproj", "{1643427B-F226-4AD6-B413-97DA64D5C6B4}"\r
ProjectSection(ProjectDependencies) = postProject\r
{AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
EndProjectSection\r
EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPluginRes", "Clients\ExplorerPlugin\ExplorerPluginRes.vcproj", "{BB8AC1B5-6587-4163-BDC6-788B157705CA}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerPluginRes", "Clients\ExplorerPlugin\ExplorerPluginRes.vcproj", "{871B1492-B4A4-4B57-9237-FA798484D7D7}"\r
ProjectSection(ProjectDependencies) = postProject\r
{AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dns-sd", "Clients\DNS-SD.VisualStudio\dns-sd.vcproj", "{AA230639-E115-4A44-AA5A-44A61235BA50}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Java", "mDNSWindows\Java\Java.vcproj", "{9CE2568A-3170-41C6-9F20-A0188A9EC114}"\r
ProjectSection(ProjectDependencies) = postProject\r
EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ControlPanel (Vista)", "mDNSWindows\ControlPanel\ControlPanelExe.vcproj", "{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLStub", "mDNSWindows\DLLStub\DLLStub.vcproj", "{3A2B6325-3053-4236-84BD-AA9BE2E323E5}"\r
ProjectSection(ProjectDependencies) = postProject\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
EndProjectSection\r
EndProject\r
Global\r
- GlobalSection(SolutionConfiguration) = preSolution\r
- Debug = Debug\r
- Release = Release\r
- EndGlobalSection\r
- GlobalSection(ProjectDependencies) = postSolution\r
- EndGlobalSection\r
- GlobalSection(ProjectConfiguration) = postSolution\r
- {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug.ActiveCfg = Debug|Win32\r
- {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug.Build.0 = Debug|Win32\r
- {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release.ActiveCfg = Release|Win32\r
- {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release.Build.0 = Release|Win32\r
- {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug.ActiveCfg = Debug|Win32\r
- {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug.Build.0 = Debug|Win32\r
- {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release.ActiveCfg = Release|Win32\r
- {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release.Build.0 = Release|Win32\r
- {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug.ActiveCfg = Debug|Win32\r
- {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug.Build.0 = Debug|Win32\r
- {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release.ActiveCfg = Release|Win32\r
- {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release.Build.0 = Release|Win32\r
- {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug.ActiveCfg = Debug|Win32\r
- {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug.Build.0 = Debug|Win32\r
- {F4F15529-F0EB-402F-8662-73C5797EE557}.Release.ActiveCfg = Release|Win32\r
- {F4F15529-F0EB-402F-8662-73C5797EE557}.Release.Build.0 = Release|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug.ActiveCfg = Debug|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug.Build.0 = Debug|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release.ActiveCfg = Release|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release.Build.0 = Release|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug.ActiveCfg = Debug|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug.Build.0 = Debug|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release.ActiveCfg = Release|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release.Build.0 = Release|Win32\r
- {9C6701E2-82B7-44B7-9B5E-3897D9153F79}.Debug.ActiveCfg = Debug|Win32\r
- {9C6701E2-82B7-44B7-9B5E-3897D9153F79}.Debug.Build.0 = Debug|Win32\r
- {9C6701E2-82B7-44B7-9B5E-3897D9153F79}.Release.ActiveCfg = Release|Win32\r
- {9C6701E2-82B7-44B7-9B5E-3897D9153F79}.Release.Build.0 = Release|Win32\r
- {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug.ActiveCfg = Debug|Win32\r
- {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug.Build.0 = Debug|Win32\r
- {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release.ActiveCfg = Release|Win32\r
- {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release.Build.0 = Release|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug.ActiveCfg = Debug|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug.Build.0 = Debug|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release.ActiveCfg = Release|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release.Build.0 = Release|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug.ActiveCfg = Debug|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug.Build.0 = Debug|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release.ActiveCfg = Release|Win32\r
- {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release.Build.0 = Release|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug.ActiveCfg = Debug|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug.Build.0 = Debug|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release.ActiveCfg = Release|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release.Build.0 = Release|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug.ActiveCfg = Debug|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug.Build.0 = Debug|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release.ActiveCfg = Release|Win32\r
- {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release.Build.0 = Release|Win32\r
- {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug.ActiveCfg = Debug|Win32\r
- {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug.Build.0 = Debug|Win32\r
- {AA230639-E115-4A44-AA5A-44A61235BA50}.Release.ActiveCfg = Release|Win32\r
- {AA230639-E115-4A44-AA5A-44A61235BA50}.Release.Build.0 = Release|Win32\r
- {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug.ActiveCfg = Debug|Win32\r
- {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug.Build.0 = Debug|Win32\r
- {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release.ActiveCfg = Release|Win32\r
- {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release.Build.0 = Release|Win32\r
- {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug.ActiveCfg = Debug|Win32\r
- {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug.Build.0 = Debug|Win32\r
- {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release.ActiveCfg = Release|Win32\r
- {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release.Build.0 = Release|Win32\r
- {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug.ActiveCfg = Debug|Win32\r
- {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug.Build.0 = Debug|Win32\r
- {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release.ActiveCfg = Release|Win32\r
- {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release.Build.0 = Release|Win32\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Debug|x64 = Debug|x64\r
+ Release|Win32 = Release|Win32\r
+ Release|x64 = Release|x64\r
EndGlobalSection\r
- GlobalSection(ExtensibilityGlobals) = postSolution\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Win32.Build.0 = Debug|Win32\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|x64.ActiveCfg = Debug|x64\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|x64.Build.0 = Debug|x64\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Win32.ActiveCfg = Release|Win32\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Win32.Build.0 = Release|Win32\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|x64.ActiveCfg = Release|x64\r
+ {AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|x64.Build.0 = Release|x64\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Win32.Build.0 = Debug|Win32\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|x64.ActiveCfg = Debug|x64\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|x64.Build.0 = Debug|x64\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Win32.ActiveCfg = Release|Win32\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Win32.Build.0 = Release|Win32\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|x64.ActiveCfg = Release|x64\r
+ {C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|x64.Build.0 = Release|x64\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Win32.Build.0 = Debug|Win32\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|x64.ActiveCfg = Debug|x64\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|x64.Build.0 = Debug|x64\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Win32.ActiveCfg = Release|Win32\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Win32.Build.0 = Release|Win32\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|x64.ActiveCfg = Release|x64\r
+ {208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|x64.Build.0 = Release|x64\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Win32.Build.0 = Debug|Win32\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|x64.ActiveCfg = Debug|x64\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|x64.Build.0 = Debug|x64\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Win32.ActiveCfg = Release|Win32\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Win32.Build.0 = Release|Win32\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|x64.ActiveCfg = Release|x64\r
+ {F4F15529-F0EB-402F-8662-73C5797EE557}.Release|x64.Build.0 = Release|x64\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Win32.Build.0 = Debug|Win32\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|x64.ActiveCfg = Debug|x64\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|x64.Build.0 = Debug|x64\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Win32.ActiveCfg = Release|Win32\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Win32.Build.0 = Release|Win32\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|x64.ActiveCfg = Release|x64\r
+ {BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|x64.Build.0 = Release|x64\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Win32.Build.0 = Debug|Win32\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|x64.ActiveCfg = Debug|x64\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|x64.Build.0 = Debug|x64\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Win32.ActiveCfg = Release|Win32\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Win32.Build.0 = Release|Win32\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|x64.ActiveCfg = Release|x64\r
+ {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|x64.Build.0 = Release|x64\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Win32.Build.0 = Debug|Win32\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|x64.ActiveCfg = Debug|x64\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|x64.Build.0 = Debug|x64\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Win32.ActiveCfg = Release|Win32\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Win32.Build.0 = Release|Win32\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|x64.ActiveCfg = Release|x64\r
+ {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|x64.Build.0 = Release|x64\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Win32.Build.0 = Debug|Win32\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|x64.ActiveCfg = Debug|x64\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|x64.Build.0 = Debug|x64\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Win32.ActiveCfg = Release|Win32\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Win32.Build.0 = Release|Win32\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|x64.ActiveCfg = Release|x64\r
+ {967F5375-0176-43D3-ADA3-22EE25551C37}.Release|x64.Build.0 = Release|x64\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Win32.Build.0 = Debug|Win32\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|x64.ActiveCfg = Debug|x64\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|x64.Build.0 = Debug|x64\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Win32.ActiveCfg = Release|Win32\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Win32.Build.0 = Release|Win32\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|x64.ActiveCfg = Release|x64\r
+ {CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|x64.Build.0 = Release|x64\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Win32.Build.0 = Debug|Win32\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|x64.ActiveCfg = Debug|x64\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|x64.Build.0 = Debug|x64\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Win32.ActiveCfg = Release|Win32\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Win32.Build.0 = Release|Win32\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|x64.ActiveCfg = Release|x64\r
+ {1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|x64.Build.0 = Release|x64\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Win32.Build.0 = Debug|Win32\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|x64.ActiveCfg = Debug|x64\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|x64.Build.0 = Debug|x64\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Win32.ActiveCfg = Release|Win32\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Win32.Build.0 = Release|Win32\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|x64.ActiveCfg = Release|x64\r
+ {871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|x64.Build.0 = Release|x64\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Win32.Build.0 = Debug|Win32\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|x64.ActiveCfg = Debug|x64\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|x64.Build.0 = Debug|x64\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Win32.ActiveCfg = Release|Win32\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Win32.Build.0 = Release|Win32\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|x64.ActiveCfg = Release|x64\r
+ {AA230639-E115-4A44-AA5A-44A61235BA50}.Release|x64.Build.0 = Release|x64\r
+ {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Win32.Build.0 = Debug|Win32\r
+ {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|x64.ActiveCfg = Debug|x64\r
+ {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Win32.ActiveCfg = Release|Win32\r
+ {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Win32.Build.0 = Release|Win32\r
+ {9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|x64.ActiveCfg = Release|x64\r
+ {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Win32.Build.0 = Debug|Win32\r
+ {A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|x64.ActiveCfg = Debug|x64\r
+ {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Win32.ActiveCfg = Release|Win32\r
+ {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Win32.Build.0 = Release|Win32\r
+ {A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|x64.ActiveCfg = Release|x64\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Win32.Build.0 = Debug|Win32\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|x64.ActiveCfg = Debug|x64\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|x64.Build.0 = Debug|x64\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Win32.ActiveCfg = Release|Win32\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Win32.Build.0 = Release|Win32\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|x64.ActiveCfg = Release|x64\r
+ {0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|x64.Build.0 = Release|x64\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Win32.Build.0 = Debug|Win32\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|x64.ActiveCfg = Debug|x64\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|x64.Build.0 = Debug|x64\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Win32.ActiveCfg = Release|Win32\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Win32.Build.0 = Release|Win32\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|x64.ActiveCfg = Release|x64\r
+ {3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|x64.Build.0 = Release|x64\r
EndGlobalSection\r
- GlobalSection(ExtensibilityAddIns) = postSolution\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
EndGlobalSection\r
EndGlobal\r
Change History (most recent first):
$Log: CommonServices.h,v $
+Revision 1.11 2009/03/30 19:51:29 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
+Revision 1.10 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
+Revision 1.9 2009/01/10 22:03:43 mkrochma
+<rdar://problem/5797507> dnsextd fails to build on Linux
+
Revision 1.8 2007/01/17 19:16:59 cheshire
Only define ssize_t if it's not already defined
#endif
#endif
+// Solaris
+
+#if( !defined( TARGET_OS_SOLARIS ) )
+ #if( defined(solaris) || (defined(__SVR4) && defined(sun)) )
+ #define TARGET_OS_SOLARIS 1
+ #else
+ #define TARGET_OS_SOLARIS 0
+ #endif
+#endif
+
// Palm
#if( !defined( TARGET_OS_PALM ) )
// No predefined macro for VxWorks so just assume VxWorks if nothing else is set.
- #if( !macintosh && !__MACH__ && !defined( __linux__ ) && !defined( __PALMOS_TRAPS__ ) && !defined( __PALMOS_ARMLET__ ) && !defined( _WIN32 ) )
+ #if( !macintosh && !__MACH__ && !defined( __linux__ ) && !defined ( __SVR4 ) && !defined ( __sun ) && !defined( __PALMOS_TRAPS__ ) && !defined( __PALMOS_ARMLET__ ) && !defined( _WIN32 ) )
#define TARGET_OS_VXWORKS 1
#else
#define TARGET_OS_VXWORKS 0
//===========================================================================================================================
#if( !KERNEL )
+ #if defined(WIN32) && !defined(_WSPIAPI_COUNTOF)
+ #define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+ #endif
#include <stddef.h>
#endif
#elif( TARGET_OS_LINUX )
- // Linux (no special includes yet).
+ // Linux
+
+ #include <stdint.h>
+ #include <arpa/inet.h>
+
+#elif( TARGET_OS_SOLARIS )
+
+ // Solaris
+
+ #include <stdint.h>
+
+ #include <arpa/inet.h>
+ #include <arpa/nameser.h>
+
+ #if ( defined( BYTE_ORDER ) && defined( LITTLE_ENDIAN ) && ( BYTE_ORDER == LITTLE_ENDIAN ) )
+ #define TARGET_RT_LITTLE_ENDIAN 1
+ #endif
+ #if ( defined( BYTE_ORDER ) && defined( BIG_ENDIAN ) && ( BYTE_ORDER == BIG_ENDIAN ) )
+ #define TARGET_RT_BIG_ENDIAN 1
+ #endif
#elif( TARGET_OS_PALM )
Change History (most recent first):
$Log: DNSSD.java,v $
+Revision 1.16 2008/11/04 20:06:20 cheshire
+<rdar://problem/6186231> Change MAX_DOMAIN_NAME to 256
+
Revision 1.15 2007/03/13 00:28:03 vazquez
<rdar://problem/4625928> Java: Rename exported symbols in libjdns_sd.jnilib
public static final int REGISTRATION_DOMAINS = ( 1 << 7 );
/** Maximum length, in bytes, of a domain name represented as an escaped C-String. */
- public static final int MAX_DOMAIN_NAME = 1005;
+ public static final int MAX_DOMAIN_NAME = 1009;
/** Pass for ifIndex to specify all available interfaces. */
public static final int ALL_INTERFACES = 0;
Change History (most recent first):
$Log: PlatformCommon.c,v $
+Revision 1.21 2009/04/11 00:20:24 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.20 2008/10/09 22:26:05 cheshire
+Save space by not showing high-resolution timestamp in LogMsgNoIdent() lines
+
+Revision 1.19 2008/07/14 17:43:36 mkrochma
+Fix previous check in so connect still gets called
+
+Revision 1.18 2008/07/12 17:19:41 mkrochma
+<rdar://problem/6068351> mDNSResponder PlatformCommon.c uses sin_len even on non-compliant platforms
+
Revision 1.17 2008/03/05 00:19:09 cheshire
Conditionalize LogTimeStamps so it's specific to APPLE_OSX, for now
{
union { struct sockaddr s; struct sockaddr_in a4; struct sockaddr_in6 a6; } addr;
socklen_t len = sizeof(addr);
+ socklen_t inner_len = 0;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
src->type = mDNSAddrType_None;
if (sock == -1) return;
if (dst->type == mDNSAddrType_IPv4)
{
- addr.a4.sin_len = sizeof(addr.a4);
+ inner_len = sizeof(addr.a4);
+ #ifndef NOT_HAVE_SA_LEN
+ addr.a4.sin_len = inner_len;
+ #endif
addr.a4.sin_family = AF_INET;
addr.a4.sin_port = 1; // Not important, any port will do
addr.a4.sin_addr.s_addr = dst->ip.v4.NotAnInteger;
}
else if (dst->type == mDNSAddrType_IPv6)
{
- addr.a6.sin6_len = sizeof(addr.a6);
+ inner_len = sizeof(addr.a6);
+ #ifndef NOT_HAVE_SA_LEN
+ addr.a6.sin6_len = inner_len;
+ #endif
addr.a6.sin6_family = AF_INET6;
addr.a6.sin6_flowinfo = 0;
addr.a6.sin6_port = 1; // Not important, any port will do
addr.a6.sin6_scope_id = 0;
}
else return;
-
- if ((connect(sock, &addr.s, addr.s.sa_len)) < 0)
+
+ if ((connect(sock, &addr.s, inner_len)) < 0)
{ LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno, strerror(errno)); goto exit; }
if ((getsockname(sock, &addr.s, &len)) < 0)
}
#endif
-mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, int logoptflags)
+mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, mDNSLogLevel_t loglevel)
{
#if APPLE_OSX_mDNSResponder && LogTimeStamps
extern mDNS mDNSStorage;
if (mDNS_DebugMode) // In debug mode we write to stderr
{
#if APPLE_OSX_mDNSResponder && LogTimeStamps
- if (mDNSPlatformClockDivisor)
+ if (ident && ident[0] && mDNSPlatformClockDivisor)
fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer);
else
#endif
}
else // else, in production mode, we write to syslog
{
- openlog(ident, LOG_CONS | logoptflags, LOG_DAEMON);
+ static int log_inited = 0;
+
+ int syslog_level = LOG_ERR;
+ switch (loglevel)
+ {
+ case MDNS_LOG_MSG: syslog_level = LOG_ERR; break;
+ case MDNS_LOG_OPERATION: syslog_level = LOG_WARNING; break;
+ case MDNS_LOG_SPS: syslog_level = LOG_NOTICE; break;
+ case MDNS_LOG_INFO: syslog_level = LOG_INFO; break;
+ case MDNS_LOG_DEBUG: syslog_level = LOG_DEBUG; break;
+ default:
+ fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
+ fflush(stderr);
+ }
+
+ if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; }
+
#if APPLE_OSX_mDNSResponder && LogTimeStamps
- if (mDNSPlatformClockDivisor)
- syslog(LOG_ERR, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
+ if (ident && ident[0] && mDNSPlatformClockDivisor)
+ syslog(syslog_level, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
else
#endif
- syslog(LOG_ERR, "%s", buffer);
- closelog();
+ syslog(syslog_level, "%s", buffer);
}
}
* checking, so that C code building with earlier versions of the header file
* can avoid compile errors trying to use functions that aren't even defined
* in those earlier versions. Similar checks may also be performed at run-time:
- * => weak linking -- to avoid link failures if run with an earler
+ * => weak linking -- to avoid link failures if run with an earlier
* version of the library that's missing some desired symbol, or
* => DNSServiceGetProperty(DaemonVersion) -- to verify whether the running daemon
* ("system service" on Windows) meets some required minimum functionality level.
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 1760300
+#define _DNS_SD_H 2120100
#ifdef __cplusplus
extern "C" {
#elif defined(_WIN32)
#include <windows.h>
#define _UNUSED
-#define bzero(a, b) memset(a, 0, b)
#ifndef _MSL_STDINT_H
typedef UINT8 uint8_t;
typedef INT8 int8_t;
* the CNAME referral, the intermediate CNAME result is also returned to the client.
* When this flag is not set, NXDomain errors are not returned, and CNAME records
* are followed silently without informing the client of the intermediate steps.
+ * (In earlier builds this flag was briefly calledkDNSServiceFlagsReturnCNAME)
*/
- /* Previous name for kDNSServiceFlagsReturnIntermediates flag (not used externally) */
- #define kDNSServiceFlagsReturnCNAME kDNSServiceFlagsReturnIntermediates
-
kDNSServiceFlagsNonBrowsable = 0x2000,
/* A service registered with the NonBrowsable flag set can be resolved using
* DNSServiceResolve(), but will not be discoverable using DNSServiceBrowse().
* an associated PTR record.
*/
- kDNSServiceFlagsShareConnection = 0x4000
+ kDNSServiceFlagsShareConnection = 0x4000,
/* For efficiency, clients that perform many concurrent operations may want to use a
* single Unix Domain Socket connection with the background daemon, instead of having a
* separate connection for each independent operation. To use this mode, clients first
* 1. Collective kDNSServiceFlagsMoreComing flag
* When callbacks are invoked using a shared DNSServiceRef, the
* kDNSServiceFlagsMoreComing flag applies collectively to *all* active
- * operations sharing the same DNSServiceRef. If the MoreComing flag is
- * set it means that there are more results queued on this DNSServiceRef,
+ * operations sharing the same parent DNSServiceRef. If the MoreComing flag is
+ * set it means that there are more results queued on this parent DNSServiceRef,
* but not necessarily more results for this particular callback function.
* The implication of this for client programmers is that when a callback
* is invoked with the MoreComing flag set, the code should update its
* internal data structures with the new result, and set a variable indicating
* that its UI needs to be updated. Then, later when a callback is eventually
* invoked with the MoreComing flag not set, the code should update *all*
- * stale UI elements related to that shared DNSServiceRef that need updating,
- * not just the UI elements related to the particular callback that happened
- * to be the last one to be invoked.
+ * stale UI elements related to that shared parent DNSServiceRef that need
+ * updating, not just the UI elements related to the particular callback
+ * that happened to be the last one to be invoked.
+ *
+ * 2. Canceling operations and kDNSServiceFlagsMoreComing
+ * Whenever you cancel any operation for which you had deferred UI updates
+ * waiting because of a kDNSServiceFlagsMoreComing flag, you should perform
+ * those deferred UI updates. This is because, after cancelling the operation,
+ * you can no longer wait for a callback *without* MoreComing set, to tell
+ * you do perform your deferred UI updates (the operation has been canceled,
+ * so there will be no more callbacks). An implication of the collective
+ * kDNSServiceFlagsMoreComing flag for shared connections is that this
+ * guideline applies more broadly -- any time you cancel an operation on
+ * a shared connection, you should perform all deferred UI updates for all
+ * operations sharing that connection. This is because the MoreComing flag
+ * might have been referring to events coming for the operation you canceled,
+ * which will now not be coming because the operation has been canceled.
*
- * 2. Only share DNSServiceRef's created with DNSServiceCreateConnection
+ * 3. Only share DNSServiceRef's created with DNSServiceCreateConnection
* Calling DNSServiceCreateConnection(&ref) creates a special shareable DNSServiceRef.
* DNSServiceRef's created by other calls like DNSServiceBrowse() or DNSServiceResolve()
* cannot be shared by copying them and using kDNSServiceFlagsShareConnection.
*
- * 3. Don't Double-Deallocate
+ * 4. Don't Double-Deallocate
* Calling DNSServiceRefDeallocate(ref) for a particular operation's DNSServiceRef terminates
* just that operation. Calling DNSServiceRefDeallocate(ref) for the main shared DNSServiceRef
* (the parent DNSServiceRef, originally created by DNSServiceCreateConnection(&ref))
* to do a DNSServiceRefDeallocate (or any other operation) on them will result in accesses
* to freed memory, leading to crashes or other equally undesirable results.
*
- * 4. Thread Safety
+ * 5. Thread Safety
* The dns_sd.h API does not presuppose any particular threading model, and consequently
* does no locking of its own (which would require linking some specific threading library).
* If client code calls API routines on the same DNSServiceRef concurrently
* lock or take similar appropriate precautions to serialize those calls.
*/
+ kDNSServiceFlagsSuppressUnusable = 0x8000
+ /* Placeholder definition, for future use
+ */
};
/* Possible protocols for DNSServiceNATPortMappingCreate(). */
kDNSServiceType_SSHFP = 44, /* SSH Key Fingerprint */
kDNSServiceType_IPSECKEY = 45, /* IPSECKEY */
kDNSServiceType_RRSIG = 46, /* RRSIG */
- kDNSServiceType_NSEC = 47, /* NSEC */
+ kDNSServiceType_NSEC = 47, /* Denial of Existence */
kDNSServiceType_DNSKEY = 48, /* DNSKEY */
- kDNSServiceType_DHCID = 49, /* DHCID */
+ kDNSServiceType_DHCID = 49, /* DHCP Client Identifier */
+ kDNSServiceType_NSEC3 = 50, /* Hashed Authenticated Denial of Existence */
+ kDNSServiceType_NSEC3PARAM= 51, /* Hashed Authenticated Denial of Existence */
+
+ kDNSServiceType_HIP = 55, /* Host Identity Protocol */
+
+ kDNSServiceType_SPF = 99, /* Sender Policy Framework for E-Mail */
+ kDNSServiceType_UINFO = 100, /* IANA-Reserved */
+ kDNSServiceType_UID = 101, /* IANA-Reserved */
+ kDNSServiceType_GID = 102, /* IANA-Reserved */
+ kDNSServiceType_UNSPEC = 103, /* IANA-Reserved */
kDNSServiceType_TKEY = 249, /* Transaction key */
kDNSServiceType_TSIG = 250, /* Transaction signature. */
/* Maximum length, in bytes, of a domain name represented as an *escaped* C-String */
/* including the final trailing dot, and the C-String terminating NULL at the end. */
-#define kDNSServiceMaxDomainName 1005
+#define kDNSServiceMaxDomainName 1009
/*
* Notes on DNS Name Escaping
* -- or --
- * "Why is kDNSServiceMaxDomainName 1005, when the maximum legal domain name is 255 bytes?"
+ * "Why is kDNSServiceMaxDomainName 1009, when the maximum legal domain name is 256 bytes?"
*
- * All strings used in DNS-SD are UTF-8 strings.
- * With few exceptions, most are also escaped using standard DNS escaping rules:
+ * All strings used in the DNS-SD APIs are UTF-8 strings. Apart from the exceptions noted below,
+ * the APIs expect the strings to be properly escaped, using the conventional DNS escaping rules:
*
* '\\' represents a single literal '\' in the name
* '\.' represents a single literal '.' in the name
* _service._udp, where the "service" part is 1-14 characters, which may be
* letters, digits, or hyphens. The domain part of the three-part name may be
* any legal domain, providing that the resulting servicename+regtype+domain
- * name does not exceed 255 bytes.
+ * name does not exceed 256 bytes.
*
* For most software, these issues are transparent. When browsing, the discovered
* servicenames should simply be displayed as-is. When resolving, the discovered
*
* rdata: The raw rdata to be contained in the added resource record.
*
- * ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value.
+ * ttl: The time to live of the resource record, in seconds.
+ * Most clients should pass 0 to indicate that the system should
+ * select a sensible default value.
*
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
* error code indicating the error that occurred (the RecordRef is not initialized).
* rdata: The new rdata to be contained in the updated resource record.
*
* ttl: The time to live of the updated resource record, in seconds.
+ * Most clients should pass 0 to indicate that the system should
+ * select a sensible default value.
*
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
* error code indicating the error that occurred.
* call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
* (To deregister ALL records registered on a single connected DNSServiceRef
* and deallocate each of their corresponding DNSServiceRecordRefs, call
- * DNSServiceRefDealloocate()).
+ * DNSServiceRefDeallocate()).
*
* flags: Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique
* (see flag type definitions for details).
*
* rdata: A pointer to the raw rdata, as it is to appear in the DNS record.
*
- * ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value.
+ * ttl: The time to live of the resource record, in seconds.
+ * Most clients should pass 0 to indicate that the system should
+ * select a sensible default value.
*
* callBack: The function to be called when a result is found, or if the call
* asynchronously fails (e.g. because of a name conflict.)
/* DNSServiceNATPortMappingCreate
*
- * Request a port mapping in the NAT gateway which maps a port on the local machine
- * to a public port on the NAT.
+ * Request a port mapping in the NAT gateway, which maps a port on the local machine
+ * to an external port on the NAT.
+ *
* The port mapping will be renewed indefinitely until the client process exits, or
* explicitly terminates the port mapping request by calling DNSServiceRefDeallocate().
* The client callback will be invoked, informing the client of the NAT gateway's
- * public IP address and the public port that has been allocated for this client.
- * The client should then record this public IP address and port using whatever
+ * external IP address and the external port that has been allocated for this client.
+ * The client should then record this external IP address and port using whatever
* directory service mechanism it is using to enable peers to connect to it.
* (Clients advertising services using Wide-Area DNS-SD DO NOT need to use this API
* -- when a client calls DNSServiceRegister() NAT mappings are automatically created
- * and the public IP address and port for the service are recorded in the global DNS.
+ * and the external IP address and port for the service are recorded in the global DNS.
* Only clients using some directory mechanism other than Wide-Area DNS-SD need to use
* this API to explicitly map their own ports.)
+ *
* It's possible that the client callback could be called multiple times, for example
* if the NAT gateway's IP address changes, or if a configuration change results in a
- * different public port being mapped for this client. Over the lifetime of any long-lived
+ * different external port being mapped for this client. Over the lifetime of any long-lived
* port mapping, the client should be prepared to handle these notifications of changes
* in the environment, and should update its recorded address and/or port as appropriate.
*
+ * NOTE: There are two unusual aspects of how the DNSServiceNATPortMappingCreate API works,
+ * which were intentionally designed to help simplify client code:
+ *
+ * 1. It's not an error to request a NAT mapping when the machine is not behind a NAT gateway.
+ * In other NAT mapping APIs, if you request a NAT mapping and the machine is not behind a NAT
+ * gateway, then the API returns an error code -- it can't get you a NAT mapping if there's no
+ * NAT gateway. The DNSServiceNATPortMappingCreate API takes a different view. Working out
+ * whether or not you need a NAT mapping can be tricky and non-obvious, particularly on
+ * a machine with multiple active network interfaces. Rather than make every client recreate
+ * this logic for deciding whether a NAT mapping is required, the PortMapping API does that
+ * work for you. If the client calls the PortMapping API when the machine already has a
+ * routable public IP address, then instead of complaining about it and giving an error,
+ * the PortMapping API just invokes your callback, giving the machine's public address
+ * and your own port number. This means you don't need to write code to work out whether
+ * your client needs to call the PortMapping API -- just call it anyway, and if it wasn't
+ * necessary, no harm is done:
+ *
+ * - If the machine already has a routable public IP address, then your callback
+ * will just be invoked giving your own address and port.
+ * - If a NAT mapping is required and obtained, then your callback will be invoked
+ * giving you the external address and port.
+ * - If a NAT mapping is required but not obtained from the local NAT gateway,
+ * or the machine has no network connectivity, then your callback will be
+ * invoked giving zero address and port.
+ *
+ * 2. In other NAT mapping APIs, if a laptop computer is put to sleep and woken up on a new
+ * network, it's the client's job to notice this, and work out whether a NAT mapping
+ * is required on the new network, and make a new NAT mapping request if necessary.
+ * The DNSServiceNATPortMappingCreate API does this for you, automatically.
+ * The client just needs to make one call to the PortMapping API, and its callback will
+ * be invoked any time the mapping state changes. This property complements point (1) above.
+ * If the client didn't make a NAT mapping request just because it determined that one was
+ * not required at that particular moment in time, the client would then have to monitor
+ * for network state changes to determine if a NAT port mapping later became necessary.
+ * By unconditionally making a NAT mapping request, even when a NAT mapping not to be
+ * necessary, the PortMapping API will then begin monitoring network state changes on behalf of
+ * the client, and if a NAT mapping later becomes necessary, it will automatically create a NAT
+ * mapping and inform the client with a new callback giving the new address and port information.
+ *
* DNSServiceNATPortMappingReply() parameters:
*
* sdRef: The DNSServiceRef initialized by DNSServiceNATPortMappingCreate().
* For other failures, will indicate the failure that occurred, and the other
* parameters are undefined.
*
- * publicAddress: Four byte IPv4 address in network byte order.
+ * externalAddress: Four byte IPv4 address in network byte order.
*
* protocol: Will be kDNSServiceProtocol_UDP or kDNSServiceProtocol_TCP or both.
*
- * privatePort: The port on the local machine that was mapped.
+ * internalPort: The port on the local machine that was mapped.
*
- * publicPort: The actual public port in the NAT gateway that was mapped.
- * This is very likely to be different than the requested public port.
+ * externalPort: The actual external port in the NAT gateway that was mapped.
+ * This is likely to be different than the requested external port.
*
* ttl: The lifetime of the NAT port mapping created on the gateway.
* This controls how quickly stale mappings will be garbage-collected
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
- uint32_t publicAddress, /* four byte IPv4 address in network byte order */
+ uint32_t externalAddress, /* four byte IPv4 address in network byte order */
DNSServiceProtocol protocol,
- uint16_t privatePort,
- uint16_t publicPort, /* may be different than the requested port */
- uint32_t ttl, /* may be different than the requested ttl */
+ uint16_t internalPort,
+ uint16_t externalPort, /* may be different than the requested port */
+ uint32_t ttl, /* may be different than the requested ttl */
void *context
);
*
* protocol: To request a port mapping, pass in kDNSServiceProtocol_UDP, or kDNSServiceProtocol_TCP,
* or (kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP) to map both.
- * The local listening port number must also be specified in the privatePort parameter.
- * To just discover the NAT gateway's public IP address, pass zero for protocol,
- * privatePort, publicPort and ttl.
+ * The local listening port number must also be specified in the internalPort parameter.
+ * To just discover the NAT gateway's external IP address, pass zero for protocol,
+ * internalPort, externalPort and ttl.
*
- * privatePort: The port number in network byte order on the local machine which is listening for packets.
+ * internalPort: The port number in network byte order on the local machine which is listening for packets.
*
- * publicPort: The requested public port in network byte order in the NAT gateway that you would
- * like to map to the private port. Pass 0 if you don't care which public port is chosen for you.
+ * externalPort: The requested external port in network byte order in the NAT gateway that you would
+ * like to map to the internal port. Pass 0 if you don't care which external port is chosen for you.
*
* ttl: The requested renewal period of the NAT port mapping, in seconds.
* If the client machine crashes, suffers a power failure, is disconnected from
* the error that occurred.
*
* If you don't actually want a port mapped, and are just calling the API
- * because you want to find out the NAT's public IP address (e.g. for UI
- * display) then pass zero for protocol, privatePort, publicPort and ttl.
+ * because you want to find out the NAT's external IP address (e.g. for UI
+ * display) then pass zero for protocol, internalPort, externalPort and ttl.
*/
DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
DNSServiceRef *sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
- DNSServiceProtocol protocol, /* TCP and/or UDP */
- uint16_t privatePort, /* network byte order */
- uint16_t publicPort, /* network byte order */
- uint32_t ttl, /* time to live in seconds */
+ DNSServiceProtocol protocol, /* TCP and/or UDP */
+ uint16_t internalPort, /* network byte order */
+ uint16_t externalPort, /* network byte order */
+ uint32_t ttl, /* time to live in seconds */
DNSServiceNATPortMappingReply callBack,
- void *context /* may be NULL */
+ void *context /* may be NULL */
);
* Parameters:
*
* fullName: A pointer to a buffer that where the resulting full domain name is to be written.
- * The buffer must be kDNSServiceMaxDomainName (1005) bytes in length to
+ * The buffer must be kDNSServiceMaxDomainName (1009) bytes in length to
* accommodate the longest legal domain name without buffer overrun.
*
* service: The service name - any dots or backslashes must NOT be escaped.
* domain: The domain name, e.g. "apple.com.". Literal dots or backslashes,
* if any, must be escaped, e.g. "1st\. Floor.apple.com."
*
- * return value: Returns 0 on success, -1 on error.
+ * return value: Returns kDNSServiceErr_NoError (0) on success, kDNSServiceErr_BadParam on error.
*
*/
-int DNSSD_API DNSServiceConstructFullName
+DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
(
char *fullName,
const char *service, /* may be NULL */
*
* key: A null-terminated string which only contains printable ASCII
* values (0x20-0x7E), excluding '=' (0x3D). Keys should be
- * 8 characters or less (not counting the terminating null).
+ * 9 characters or fewer (not counting the terminating null).
*
* valueSize: The size of the value.
*
* val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
* val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
* ...
- * bcopy(val1ptr, myval1, len1);
- * bcopy(val2ptr, myval2, len2);
+ * memcpy(myval1, val1ptr, len1);
+ * memcpy(myval2, val2ptr, len2);
* ...
* return;
*
* If you wish to retain the values after return from the DNSServiceResolve()
- * callback, then you need to copy the data to your own storage using bcopy()
+ * callback, then you need to copy the data to your own storage using memcpy()
* or similar, as shown in the example above.
*
* If for some reason you need to parse a TXT record you built yourself
* key: A string buffer used to store the key name.
* On return, the buffer contains a null-terminated C string
* giving the key name. DNS-SD TXT keys are usually
- * 8 characters or less. To hold the maximum possible
+ * 9 characters or fewer. To hold the maximum possible
* key name, the buffer should be 256 bytes long.
*
* valueLen: On output, will be set to the size of the "value" data.
Change History (most recent first):
$Log: dnsextd.c,v $
+Revision 1.97 2009/01/13 05:31:34 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.96 2009/01/13 00:45:41 cheshire
+Uncommented "#ifdef NOT_HAVE_DAEMON" check
+
+Revision 1.95 2009/01/12 22:47:13 cheshire
+Only include "mDNSUNP.h" when building on a system that requires the "daemon()" definition (currently only Solaris)
+
+Revision 1.94 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
+Revision 1.93 2008/12/17 05:06:53 cheshire
+Increased maximum DNS Update lifetime from 20 minutes to 2 hours -- now that we have Sleep Proxy,
+having clients wake every fifteen minutes to renew their record registrations is no longer reasonable.
+
+Revision 1.92 2008/11/13 19:09:36 cheshire
+Updated rdataOPT code
+
+Revision 1.91 2008/11/04 23:06:51 cheshire
+Split RDataBody union definition into RDataBody and RDataBody2, and removed
+SOA from the normal RDataBody union definition, saving 270 bytes per AuthRecord
+
+Revision 1.90 2008/10/03 18:18:57 cheshire
+Define dummy "mDNS_ConfigChanged(mDNS *const m)" routine to avoid link errors
+
+Revision 1.89 2008/09/15 23:52:30 cheshire
+<rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op
+Made __crashreporter_info__ symbol conditional, so we only use it for OS X build
+
Revision 1.88 2008/03/06 21:26:11 cheshire
Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
#include <time.h>
#include <errno.h>
+// Solaris doesn't have daemon(), so we define it here
+#ifdef NOT_HAVE_DAEMON
+#include "../mDNSPosix/mDNSUNP.h" // For daemon()
+#endif // NOT_HAVE_DAEMON
+
// Compatibility workaround
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
pkt = malloc(allocsize);
require_action_quiet( pkt, exit, err = mStatus_NoMemoryErr; LogErr( "RecvPacket", "malloc" ) );
- bzero( pkt, sizeof( *pkt ) );
+ mDNSPlatformMemZero( pkt, sizeof( *pkt ) );
}
pkt->len = msglen;
if ( getpeername( fd, ( struct sockaddr* ) &pkt->src, &srclen ) || ( srclen != sizeof( pkt->src ) ) )
{
LogErr("RecvPacket", "getpeername");
- bzero(&pkt->src, sizeof(pkt->src));
+ mDNSPlatformMemZero(&pkt->src, sizeof(pkt->src));
}
nread = my_recv(sock, &pkt->msg, msglen, closed );
if (!ptr) { Log("Unable to read additional record"); goto end; }
}
- if ( lcr.r.resrec.rrtype == kDNSType_OPT && lcr.r.resrec.rdlength >= LLQ_OPT_RDLEN && lcr.r.resrec.rdata->u.opt.opt == kDNSOpt_LLQ )
+ if ( lcr.r.resrec.rrtype == kDNSType_OPT && lcr.r.resrec.rdlength >= DNSOpt_LLQData_Space && lcr.r.resrec.rdata->u.opt[0].opt == kDNSOpt_LLQ )
{
result = mDNStrue;
}
cr = malloc(size);
if (!cr) { LogErr("CopyCacheRecord", "malloc"); return NULL; }
memcpy(cr, orig, size);
- cr->resrec.rdata = (RData*)&cr->rdatastorage;
+ cr->resrec.rdata = (RData*)&cr->smallrdatastorage;
cr->resrec.name = name;
return cr;
VLog("Rehashing lease table (new size %d buckets)", newnbuckets);
new = malloc(sizeof(RRTableElem *) * newnbuckets);
if (!new) { LogErr("RehashTable", "malloc"); return; }
- bzero(new, newnbuckets * sizeof(RRTableElem *));
+ mDNSPlatformMemZero(new, newnbuckets * sizeof(RRTableElem *));
for (i = 0; i < d->nbuckets; i++)
{
ptr[1] = (mDNSu8)(rr->rrtype & 0xFF);
ptr[2] = (mDNSu8)((mDNSu16)kDNSQClass_ANY >> 8);
ptr[3] = (mDNSu8)((mDNSu16)kDNSQClass_ANY & 0xFF);
- bzero(ptr+4, sizeof(rr->rroriginalttl) + sizeof(rr->rdlength)); // zero ttl/rdata
+ mDNSPlatformMemZero(ptr+4, sizeof(rr->rroriginalttl) + sizeof(rr->rdlength)); // zero ttl/rdata
msg->h.mDNS_numUpdates++;
return ptr + 10;
}
// setup our sockaddr
- bzero( &d->addr, sizeof( d->addr ) );
+ mDNSPlatformMemZero( &d->addr, sizeof( d->addr ) );
d->addr.sin_addr.s_addr = zerov4Addr.NotAnInteger;
d->addr.sin_port = UnicastDNSPort.NotAnInteger;
d->addr.sin_family = AF_INET;
// setup nameserver's sockaddr
- bzero(&d->ns_addr, sizeof(d->ns_addr));
+ mDNSPlatformMemZero(&d->ns_addr, sizeof(d->ns_addr));
d->ns_addr.sin_family = AF_INET;
inet_pton( AF_INET, LOOPBACK, &d->ns_addr.sin_addr );
d->ns_addr.sin_port = NSIPCPort.NotAnInteger;
d->nelems = 0;
d->table = malloc(sizeof(RRTableElem *) * LEASETABLE_INIT_NBUCKETS);
if (!d->table) { LogErr("InitLeaseTable", "malloc"); return -1; }
- bzero(d->table, sizeof(RRTableElem *) * LEASETABLE_INIT_NBUCKETS);
+ mDNSPlatformMemZero(d->table, sizeof(RRTableElem *) * LEASETABLE_INIT_NBUCKETS);
return 0;
}
// set up sockets on which we receive llq requests
- bzero(&self->llq_addr, sizeof(self->llq_addr));
+ mDNSPlatformMemZero(&self->llq_addr, sizeof(self->llq_addr));
self->llq_addr.sin_family = AF_INET;
self->llq_addr.sin_addr.s_addr = zerov4Addr.NotAnInteger;
self->llq_addr.sin_port = ( self->llq_port.NotAnInteger ) ? self->llq_port.NotAnInteger : DNSEXTPort.NotAnInteger;
self->llq_tcpsd = socket( AF_INET, SOCK_STREAM, 0 );
require_action( dnssd_SocketValid(self->tlssd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );
- bzero(&daddr, sizeof(daddr));
+ mDNSPlatformMemZero(&daddr, sizeof(daddr));
daddr.sin_family = AF_INET;
daddr.sin_addr.s_addr = zerov4Addr.NotAnInteger;
daddr.sin_port = ( self->private_port.NotAnInteger ) ? self->private_port.NotAnInteger : PrivateDNSPort.NotAnInteger;
tmp = malloc(allocsize);
if (!tmp) { LogErr("UpdateLeaseTable", "malloc"); goto cleanup; }
memcpy(&tmp->rr, &lcr.r, sizeof(CacheRecord) + rr->rdlength - InlineCacheRDSize);
- tmp->rr.resrec.rdata = (RData *)&tmp->rr.rdatastorage;
+ tmp->rr.resrec.rdata = (RData *)&tmp->rr.smallrdatastorage;
AssignDomainName(&tmp->name, rr->name);
tmp->rr.resrec.name = &tmp->name;
tmp->expire = tv.tv_sec + (unsigned)lease;
static const mDNSOpaque16 UpdateRefused = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_Update, kDNSFlag1_RC_Refused } };
Log("Rejecting Update Request with %d additions but no lease", adds);
reply = malloc(sizeof(*reply));
- bzero(&reply->src, sizeof(reply->src));
+ mDNSPlatformMemZero(&reply->src, sizeof(reply->src));
reply->len = sizeof(DNSMessageHeader);
reply->zone = NULL;
reply->isZonePublic = 0;
InitializeDNSMessage(&reply->msg.h, request->msg.h.id, UpdateRefused);
return(reply);
}
- if (lease > 1200) // Don't allow lease greater than 20 minutes
- lease = 1200;
+ if (lease > 7200) // Don't allow lease greater than two hours; typically 90-minute renewal period
+ lease = 7200;
}
// Send msg to server, read reply
// Set fields of an LLQ OPT Resource Record
mDNSlocal void FormatLLQOpt(AuthRecord *opt, int opcode, const mDNSOpaque64 *const id, mDNSs32 lease)
{
- bzero(opt, sizeof(*opt));
+ mDNSPlatformMemZero(opt, sizeof(*opt));
mDNS_SetupResourceRecord(opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
opt->resrec.rrclass = NormalMaxDNSMessageData;
- opt->resrec.rdlength = LLQ_OPT_RDLEN;
- opt->resrec.rdestimate = LLQ_OPT_RDLEN;
- opt->resrec.rdata->u.opt.opt = kDNSOpt_LLQ;
- opt->resrec.rdata->u.opt.optlen = sizeof(LLQOptData);
- opt->resrec.rdata->u.opt.OptData.llq.vers = kLLQ_Vers;
- opt->resrec.rdata->u.opt.OptData.llq.llqOp = opcode;
- opt->resrec.rdata->u.opt.OptData.llq.err = LLQErr_NoError;
- opt->resrec.rdata->u.opt.OptData.llq.id = *id;
- opt->resrec.rdata->u.opt.OptData.llq.llqlease = lease;
+ opt->resrec.rdlength = sizeof(rdataOPT); // One option in this OPT record
+ opt->resrec.rdestimate = sizeof(rdataOPT);
+ opt->resrec.rdata->u.opt[0].opt = kDNSOpt_LLQ;
+ opt->resrec.rdata->u.opt[0].u.llq.vers = kLLQ_Vers;
+ opt->resrec.rdata->u.opt[0].u.llq.llqOp = opcode;
+ opt->resrec.rdata->u.opt[0].u.llq.err = LLQErr_NoError;
+ opt->resrec.rdata->u.opt[0].u.llq.id = *id;
+ opt->resrec.rdata->u.opt[0].u.llq.llqlease = lease;
}
// Calculate effective remaining lease of an LLQ
// validate OPT
if (opt.r.resrec.rrtype != kDNSType_OPT) { Log("Malformatted LLQ from %s: last Additional not an OPT RR", addr); goto end; }
- if (opt.r.resrec.rdlength < pkt->msg.h.numQuestions * LLQ_OPT_RDLEN) { Log("Malformatted LLQ from %s: OPT RR to small (%d bytes for %d questions)", addr, opt.r.resrec.rdlength, pkt->msg.h.numQuestions); }
+ if (opt.r.resrec.rdlength < pkt->msg.h.numQuestions * DNSOpt_LLQData_Space) { Log("Malformatted LLQ from %s: OPT RR to small (%d bytes for %d questions)", addr, opt.r.resrec.rdlength, pkt->msg.h.numQuestions); }
// dispatch each question
for (i = 0; i < pkt->msg.h.numQuestions; i++)
{
qptr = getQuestion(&pkt->msg, qptr, end, 0, &q);
if (!qptr) { Log("Malformatted LLQ from %s: cannot read question %d", addr, i); goto end; }
- llq = (LLQOptData *)&opt.r.resrec.rdata->u.opt.OptData.llq + i; // point into OptData at index i
+ llq = (LLQOptData *)&opt.r.resrec.rdata->u.opt[0].u.llq + i; // point into OptData at index i
if (llq->vers != kLLQ_Vers) { Log("LLQ from %s contains bad version %d (expected %d)", addr, llq->vers, kLLQ_Vers); goto end; }
e = LookupLLQ(d, pkt->src, &q.qname, q.qtype, &llq->id);
context = malloc( sizeof( UDPContext ) );
require_action( context, exit, err = mStatus_NoMemoryErr ; LogErr( "RecvUDPMessage", "malloc" ) );
- bzero( context, sizeof( *context ) );
+ mDNSPlatformMemZero( context, sizeof( *context ) );
context->d = self;
context->sd = sd;
context = ( TCPContext* ) malloc( sizeof( TCPContext ) );
require_action( context, exit, err = mStatus_NoMemoryErr; LogErr( "AcceptTCPConnection", "malloc" ) );
- bzero( context, sizeof( sizeof( TCPContext ) ) );
+ mDNSPlatformMemZero( context, sizeof( sizeof( TCPContext ) ) );
context->d = self;
newSock = accept( sd, ( struct sockaddr* ) &context->cliaddr, &clilen );
require_action( newSock != -1, exit, err = mStatus_UnknownErr; LogErr( "AcceptTCPConnection", "accept" ) );
d = malloc(sizeof(*d));
if (!d) { LogErr("main", "malloc"); exit(1); }
- bzero(d, sizeof(DaemonInfo));
+ mDNSPlatformMemZero(d, sizeof(DaemonInfo));
// Setup the public SRV record names
// It's an error for these routines to actually be called, so perhaps we should log any call
// to them.
void mDNSCoreInitComplete( mDNS * const m, mStatus result) { ( void ) m; ( void ) result; }
+void mDNS_ConfigChanged(mDNS *const m) { ( void ) m; }
void mDNSCoreMachineSleep(mDNS * const m, mDNSBool wake) { ( void ) m; ( void ) wake; }
void mDNSCoreReceive(mDNS *const m, void *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
// The "@(#) " pattern is a special prefix the "what" command looks for
const char mDNSResponderVersionString_SCCS[] = "@(#) dnsextd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
+#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
+#endif
Change History (most recent first):
$Log: dnsextd_lexer.l,v $
+Revision 1.6 2008/07/18 17:40:46 cheshire
+Removed redundant definition of "YY_NO_UNPUT" (not needed now that we use "%option nounput" instead)
+
+Revision 1.5 2008/06/24 18:32:26 mcguire
+<rdar://problem/6024542> flex producing .c files that result in warnings
+
Revision 1.4 2007/05/25 20:01:43 cheshire
<rdar://problem/5226767> /usr/bin/flex failures prevent mDNSResponder from building
Only define "int yylineno" on flex 2.5.4 and earlier
int yylineno = 1;
#endif
-#define YY_NO_UNPUT
-
int yylex(void);
static char*
%}
+%option nounput
%%
options return OPTIONS;
Change History (most recent first):
$Log: dnsextd_parser.y,v $
+Revision 1.9 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
Revision 1.8 2007/03/21 19:47:50 cheshire
<rdar://problem/4789463> Leak: On error path in ParseConfig
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <mDNSEmbeddedAPI.h>
-#include <DebugServices.h>
+#include "mDNSEmbeddedAPI.h"
+#include "DebugServices.h"
#include "dnsextd.h"
void yyerror( const char* error );
Change History (most recent first):
$Log: dnssd_clientlib.c,v $
+Revision 1.21 2009/04/01 21:10:11 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows. Use _stricmp and _strnicmp.
+
+Revision 1.20 2008/11/26 20:57:37 cheshire
+For consistency with other similar macros, renamed mdnsIsDigit/mdnsIsLetter/mdnsValidHostChar
+to mDNSIsDigit/mDNSIsLetter/mDNSValidHostChar
+
+Revision 1.19 2008/11/04 21:15:18 cheshire
+<rdar://problem/5969564> Potential buffer overflows in DNSServiceConstructFullName
+
Revision 1.18 2007/11/30 23:06:10 cheshire
Fixed compile warning: declaration of 'index' shadows a global declaration
#if defined(_WIN32)
// disable warning "conversion from <data> to uint16_t"
#pragma warning(disable:4244)
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
#endif
/*********************************************************************************************
*
*********************************************************************************************/
-#define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
+#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
+
+// DomainEndsInDot returns 1 if name ends with a dot, 0 otherwise
+// (DNSServiceConstructFullName depends this returning 1 for true, rather than any non-zero value meaning true)
static int DomainEndsInDot(const char *dom)
{
{
if (dom[0] == '\\') // advance past escaped byte sequence
{
- if (mdnsIsDigit(dom[1]) && mdnsIsDigit(dom[2]) && mdnsIsDigit(dom[3]))
+ if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
dom += 4; // If "\ddd" then skip four
else dom += 2; // else if "\x" then skip two
}
*
*********************************************************************************************/
-int DNSSD_API DNSServiceConstructFullName
+// Note: Need to make sure we don't write more than kDNSServiceMaxDomainName (1009) bytes to fullName
+// In earlier builds this constant was defined to be 1005, so to avoid buffer overruns on clients
+// compiled with that constant we'll actually limit the output to 1005 bytes.
+
+DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
(
- char *fullName,
- const char *service, /* may be NULL */
- const char *regtype,
- const char *domain
+ char *const fullName,
+ const char *const service, // May be NULL
+ const char *const regtype,
+ const char *const domain
)
{
- unsigned long len;
- unsigned char c;
- char *fn = fullName;
- const char *s = service;
- const char *r = regtype;
- const char *d = domain;
+ const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
+ char *fn = fullName;
+ char *const lim = fullName + 1005;
+ const char *s = service;
+ const char *r = regtype;
+ const char *d = domain;
+
+ // regtype must be at least "x._udp" or "x._tcp"
+ if (len < 6 || !domain || !domain[0]) return kDNSServiceErr_BadParam;
+ if (strncasecmp((regtype + len - 4), "_tcp", 4) && strncasecmp((regtype + len - 4), "_udp", 4)) return kDNSServiceErr_BadParam;
if (service && *service)
{
while (*s)
{
- c = (unsigned char)*s++;
- if (c == '.' || (c == '\\')) *fn++ = '\\'; // escape dot and backslash literals
- else if (c <= ' ') // escape non-printable characters
+ unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
+ if (c <= ' ') // Escape non-printable characters
{
+ if (fn+4 >= lim) goto fail;
*fn++ = '\\';
- *fn++ = (char) ('0' + (c / 100));
- *fn++ = (char) ('0' + (c / 10) % 10);
- c = (unsigned char)('0' + (c % 10));
+ *fn++ = '0' + (c / 100);
+ *fn++ = '0' + (c / 10) % 10;
+ c = '0' + (c ) % 10;
}
+ else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
+ {
+ if (fn+2 >= lim) goto fail;
+ *fn++ = '\\';
+ }
+ else
+ if (fn+1 >= lim) goto fail;
*fn++ = (char)c;
}
*fn++ = '.';
}
- if (!regtype) return -1;
- len = (unsigned long) strlen(regtype);
- if (DomainEndsInDot(regtype)) len--;
- if (len < 6) return -1; // regtype must be at least "x._udp" or "x._tcp"
- if (strncasecmp((regtype + len - 4), "_tcp", 4) && strncasecmp((regtype + len - 4), "_udp", 4)) return -1;
- while (*r) *fn++ = *r++;
- if (!DomainEndsInDot(regtype)) *fn++ = '.';
-
- if (!domain || !domain[0]) return -1;
- while (*d) *fn++ = *d++;
- if (!DomainEndsInDot(domain)) *fn++ = '.';
+ while (*r) if (fn+1 >= lim) goto fail; else *fn++ = *r++;
+ if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; }
+
+ while (*d) if (fn+1 >= lim) goto fail; else *fn++ = *d++;
+ if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail; else *fn++ = '.'; }
+
+ *fn = '\0';
+ return kDNSServiceErr_NoError;
+
+fail:
*fn = '\0';
- return 0;
+ return kDNSServiceErr_BadParam;
}
/*********************************************************************************************
Change History (most recent first):
$Log: dnssd_clientstub.c,v $
+Revision 1.134 2009/06/19 23:13:24 cheshire
+<rdar://problem/6990066> Library: crash at handle_resolve_response + 183
+Added check for NULL after calling get_string
+
+Revision 1.133 2009/05/27 22:19:12 cheshire
+Remove questionable uses of errno
+
+Revision 1.132 2009/05/26 21:31:07 herscher
+Fix compile errors on Windows
+
+Revision 1.131 2009/05/26 04:48:19 herscher
+<rdar://problem/6844819> ExplorerPlugin does not work in B4W 2.0
+
+Revision 1.130 2009/05/02 01:29:48 mcguire
+<rdar://problem/6847601> spin calling DNSServiceProcessResult if errno was set to EWOULDBLOCK by an unrelated call
+
+Revision 1.129 2009/05/01 19:18:50 cheshire
+<rdar://problem/6843645> Using duplicate DNSServiceRefs when sharing a connection should return an error
+
+Revision 1.128 2009/04/01 21:09:35 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows.
+
+Revision 1.127 2009/03/03 21:38:19 cheshire
+Improved "deliver_request ERROR" message
+
+Revision 1.126 2009/02/12 21:02:22 cheshire
+Commented out BPF "Sending fd" debugging message
+
+Revision 1.125 2009/02/12 20:28:32 cheshire
+Added some missing "const" declarations
+
+Revision 1.124 2009/02/10 01:44:39 cheshire
+<rdar://problem/6553729> DNSServiceUpdateRecord fails with kDNSServiceErr_BadReference for otherwise valid reference
+
+Revision 1.123 2009/01/19 00:49:21 mkrochma
+Type cast size_t values to unsigned long
+
+Revision 1.122 2009/01/18 03:51:37 mkrochma
+Fix warning in deliver_request on Linux
+
+Revision 1.121 2009/01/16 23:34:37 cheshire
+<rdar://problem/6504143> Uninitialized error code variable in error handling path in deliver_request
+
+Revision 1.120 2009/01/13 05:31:35 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.119 2009/01/11 03:45:08 mkrochma
+Stop type casting num_written and num_read to int
+
+Revision 1.118 2009/01/11 03:20:06 mkrochma
+<rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
+
+Revision 1.117 2009/01/10 22:03:43 mkrochma
+<rdar://problem/5797507> dnsextd fails to build on Linux
+
+Revision 1.116 2009/01/05 16:55:24 cheshire
+<rdar://problem/6452199> Stuck in "Examining available disks"
+ConnectionResponse handler was accidentally matching the parent DNSServiceRef before
+finding the appropriate subordinate DNSServiceRef for the operation in question.
+
+Revision 1.115 2008/12/18 00:19:11 mcguire
+<rdar://problem/6452199> Stuck in "Examining available disks"
+
+Revision 1.114 2008/12/10 02:11:43 cheshire
+ARMv5 compiler doesn't like uncommented stuff after #endif
+
+Revision 1.113 2008/12/04 03:23:05 cheshire
+Preincrement UID counter before we use it -- it helps with debugging if we know the all-zeroes ID should never appear
+
+Revision 1.112 2008/11/25 22:56:54 cheshire
+<rdar://problem/6377257> Make library code more defensive when client calls DNSServiceProcessResult with bad DNSServiceRef repeatedly
+
+Revision 1.111 2008/10/28 17:58:44 cheshire
+If client code keeps calling DNSServiceProcessResult repeatedly after an error, rate-limit the
+"DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function" log messages
+
+Revision 1.110 2008/10/23 23:38:58 cheshire
+For Windows compatibility, instead of "strerror(errno)" use "dnssd_strerror(dnssd_errno)"
+
+Revision 1.109 2008/10/23 23:06:17 cheshire
+Removed () from dnssd_errno macro definition -- it's not a function and doesn't need any arguments
+
+Revision 1.108 2008/10/23 22:33:24 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
+Revision 1.107 2008/10/20 21:50:11 cheshire
+Improved /dev/bpf error message
+
+Revision 1.106 2008/10/20 15:37:18 cheshire
+Log error message if opening /dev/bpf fails
+
+Revision 1.105 2008/09/27 01:26:34 cheshire
+Added handler to pass back BPF fd when requested
+
+Revision 1.104 2008/09/23 01:36:00 cheshire
+Updated code to use internalPort/externalPort terminology, instead of the old privatePort/publicPort
+terms (which could be misleading, because the word "private" suggests security).
+
+Revision 1.103 2008/07/24 18:51:13 cheshire
+Removed spurious spaces
+
Revision 1.102 2008/02/25 19:16:19 cheshire
<rdar://problem/5708953> Problems with DNSServiceGetAddrInfo API
Was returning a bogus result (NULL pointer) when following a CNAME referral
#if defined(_WIN32)
+ #define _SSIZE_T
+ #include <CommonServices.h>
+ #include <DebugServices.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
+ #include <stdarg.h>
#define sockaddr_mdns sockaddr_in
#define AF_MDNS AF_INET
#define sleep(X) Sleep((X) * 1000)
static int g_initWinsock = 0;
-
+ #define LOG_WARNING kDebugLevelWarning
+ static void syslog( int priority, const char * message, ...)
+ {
+ va_list args;
+ int len;
+ char * buffer;
+ DWORD err = WSAGetLastError();
+ va_start( args, message );
+ len = _vscprintf( message, args ) + 1;
+ buffer = malloc( len * sizeof(char) );
+ if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugString( buffer ); free( buffer ); }
+ WSASetLastError( err );
+ }
#else
+ #include <sys/fcntl.h> // For O_RDWR etc.
#include <sys/time.h>
#include <sys/socket.h>
#include <syslog.h>
typedef struct _DNSRecordRef_t DNSRecord;
// client stub callback to process message from server and deliver results to client application
-typedef void (*ProcessReplyFn)(DNSServiceOp *sdr, CallbackHeader *cbh, char *msg, char *end);
+typedef void (*ProcessReplyFn)(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *msg, const char *const end);
#define ValidatorBits 0x12345678
#define DNSServiceRefValid(X) (dnssd_SocketValid((X)->sockfd) && (((X)->sockfd ^ (X)->validator) == ValidatorBits))
static int write_all(dnssd_sock_t sd, char *buf, int len)
{
// Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
- //if (send(sd, buf, len, MSG_WAITALL) != len) return -1;
+ //if (send(sd, buf, len, MSG_WAITALL) != len) return -1;
while (len)
{
ssize_t num_written = send(sd, buf, len, 0);
{
// Should never happen. If it does, it indicates some OS bug,
// or that the mDNSResponder daemon crashed (which should never happen).
- syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %d/%d %d %s", sd, num_written, len,
- (num_written < 0) ? errno : 0,
- (num_written < 0) ? strerror(errno) : "");
+ syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%d %d %s", sd, num_written, len,
+ (num_written < 0) ? dnssd_errno : 0,
+ (num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
return -1;
}
buf += num_written;
return 0;
}
-// Read len bytes. Return 0 on success, -1 on error
+enum { read_all_success = 0, read_all_fail = -1, read_all_wouldblock = -2 };
+
+// Read len bytes. Return 0 on success, read_all_fail on error, or read_all_wouldblock for
static int read_all(dnssd_sock_t sd, char *buf, int len)
{
// Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
{
// Should never happen. If it does, it indicates some OS bug,
// or that the mDNSResponder daemon crashed (which should never happen).
- syslog(LOG_WARNING, "dnssd_clientstub read_all(%d) failed %d/%d %d %s", sd, num_read, len,
- (num_read < 0) ? errno : 0,
- (num_read < 0) ? strerror(errno) : "");
- return -1;
+ syslog(LOG_WARNING, "dnssd_clientstub read_all(%d) failed %ld/%d %d %s", sd, num_read, len,
+ (num_read < 0) ? dnssd_errno : 0,
+ (num_read < 0) ? dnssd_strerror(dnssd_errno) : "");
+ return (num_read < 0 && dnssd_errno == dnssd_EWOULDBLOCK) ? read_all_wouldblock : read_all_fail;
}
buf += num_read;
len -= num_read;
}
- return 0;
+ return read_all_success;
}
// Returns 1 if more bytes remain to be read on socket descriptor sd, 0 otherwise
#elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
struct timeval time;
if (gettimeofday(&time, NULL) < 0)
- { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", errno, strerror(errno)); return NULL; }
+ { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno)); return NULL; }
sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
(unsigned long)(time.tv_sec & 0xFFF), (unsigned long)(time.tv_usec));
*len += strlen(ctrl_path) + 1;
msg = malloc(*len);
if (!msg) { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: malloc failed"); return NULL; }
- bzero(msg, *len);
+ memset(msg, 0, *len);
hdr = (ipc_msg_hdr *)msg;
hdr->version = VERSION;
hdr->datalen = datalen;
syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with NULL DNSServiceRef");
return kDNSServiceErr_BadParam;
}
- if (!DNSServiceRefValid(*ref))
+ if (!DNSServiceRefValid(*ref) || (*ref)->op != connection_request || (*ref)->primary)
{
syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with invalid DNSServiceRef %p %08X %08X",
(*ref), (*ref)->sockfd, (*ref)->validator);
DNSServiceOp **p = &(*ref)->next; // Append ourselves to end of primary's list
while (*p) p = &(*p)->next;
*p = sdr;
+ // Preincrement counter before we use it -- it helps with debugging if we know the all-zeroes ID should never appear
+ if (++(*ref)->uid.u32[0] == 0) ++(*ref)->uid.u32[1]; // In parent DNSServiceOp increment UID counter
sdr->primary = *ref; // Set our primary pointer
sdr->sockfd = (*ref)->sockfd; // Inherit primary's socket
sdr->validator = (*ref)->validator;
sdr->uid = (*ref)->uid;
- if (++(*ref)->uid.u32[0] == 0) ++(*ref)->uid.u32[1]; // In parent DNSServiceOp increment UID counter
//printf("ConnectToServer sharing socket %d\n", sdr->sockfd);
}
else
sdr->validator = sdr->sockfd ^ ValidatorBits;
if (!dnssd_SocketValid(sdr->sockfd))
{
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: socket failed %d %s", errno, strerror(errno));
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: socket failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
FreeDNSServiceOp(sdr);
return kDNSServiceErr_NoMemory;
}
#ifdef SO_NOSIGPIPE
// Some environments (e.g. OS X) support turning off SIGPIPE for a socket
if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_NOSIGPIPE failed %d %s", errno, strerror(errno));
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_NOSIGPIPE failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
#endif
#if defined(USE_TCP_LOOPBACK)
saddr.sin_family = AF_INET;
return kDNSServiceErr_NoError;
}
+#define deliver_request_bailout(MSG) \
+ do { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup; } while(0)
+
static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
{
uint32_t datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
#endif
dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
- DNSServiceErrorType err;
+ DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
int MakeSeparateReturnSocket = 0;
// Note: need to check hdr->op, not sdr->op.
dnssd_sockaddr_t caddr;
dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) goto cleanup;
+ if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("TCP socket");
caddr.sin_family = AF_INET;
caddr.sin_port = 0;
caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
- if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) goto cleanup;
- if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) goto cleanup;
- listen(listenfd, 1);
+ if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) deliver_request_bailout("TCP bind");
+ if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) deliver_request_bailout("TCP getsockname");
+ if (listen(listenfd, 1) < 0) deliver_request_bailout("TCP listen");
port.s = caddr.sin_port;
data[0] = port.b[0]; // don't switch the byte order, as the
data[1] = port.b[1]; // daemon expects it in network byte order
int bindresult;
dnssd_sockaddr_t caddr;
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) goto cleanup;
+ if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
caddr.sun_family = AF_LOCAL;
// According to Stevens (section 3.2), there is no portable way to
mask = umask(0);
bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
umask(mask);
- if (bindresult < 0) goto cleanup;
- listen(listenfd, 1);
+ if (bindresult < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
+ if (listen(listenfd, 1) < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
}
#else
{
dnssd_sock_t sp[2];
- //if (pipe(sp) < 0)
- // syslog(LOG_WARNING, "dnssd_clientstub ERROR: pipe() failed errno %d (%s)", errno, strerror(errno));
- if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub ERROR: socketpair() failed errno %d (%s)", errno, strerror(errno));
+ if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) deliver_request_bailout("socketpair");
else
{
errsd = sp[0]; // We'll read our four-byte error code from sp[0]
// any associated data does not work reliably -- e.g. one particular issue we ran
// into is that if the receiving program is in a kqueue loop waiting to be notified
// of the received message, it doesn't get woken up when the control message arrives.
- if (MakeSeparateReturnSocket) datalen--;
+ if (MakeSeparateReturnSocket || sdr->op == send_bpf) datalen--; // Okay to use sdr->op when checking for op == send_bpf
#endif
// At this point, our listening socket is set up and waiting, if necessary, for the daemon to connect back to
ConvertHeaderBytes(hdr);
- //syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %ld bytes", datalen + sizeof(ipc_msg_hdr));
+ //syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %lu bytes", (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
//if (MakeSeparateReturnSocket) syslog(LOG_WARNING, "dnssd_clientstub deliver_request name is %s", data);
#if TEST_SENDING_ONE_BYTE_AT_A_TIME
unsigned int i;
for (i=0; i<datalen + sizeof(ipc_msg_hdr); i++)
{
- syslog(LOG_WARNING, "dnssd_clientstub writing %d", i);
- if (write_all(sdr->sockfd, ((char *)hdr)+i, 1) < 0) goto cleanup;
+ syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %d", i);
+ if (write_all(sdr->sockfd, ((char *)hdr)+i, 1) < 0)
+ { syslog(LOG_WARNING, "write_all (byte %u) failed", i); goto cleanup; }
usleep(10000);
}
#else
- if (write_all(sdr->sockfd, (char *)hdr, datalen + sizeof(ipc_msg_hdr)) < 0) goto cleanup;
+ if (write_all(sdr->sockfd, (char *)hdr, datalen + sizeof(ipc_msg_hdr)) < 0)
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub deliver_request ERROR: write_all(%d, %lu bytes) failed",
+ sdr->sockfd, (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
+ goto cleanup;
+ }
#endif
if (!MakeSeparateReturnSocket) errsd = sdr->sockfd;
- else
+ if (MakeSeparateReturnSocket || sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
{
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
// At this point we may block in accept for a few milliseconds waiting for the daemon to connect back to us,
dnssd_sockaddr_t daddr;
dnssd_socklen_t len = sizeof(daddr);
errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
- if (!dnssd_SocketValid(errsd)) goto cleanup;
+ if (!dnssd_SocketValid(errsd)) deliver_request_bailout("accept");
#else
#if APPLE_OSX_mDNSResponder
struct msghdr msg;
struct cmsghdr *cmsg;
char cbuf[CMSG_SPACE(sizeof(dnssd_sock_t))];
+
+ if (sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
+ {
+ int i;
+ char p[12]; // Room for "/dev/bpf999" with terminating null
+ for (i=0; i<100; i++)
+ {
+ snprintf(p, sizeof(p), "/dev/bpf%d", i);
+ listenfd = open(p, O_RDWR, 0);
+ //if (dnssd_SocketValid(listenfd)) syslog(LOG_WARNING, "Sending fd %d for %s", listenfd, p);
+ if (!dnssd_SocketValid(listenfd) && dnssd_errno != EBUSY)
+ syslog(LOG_WARNING, "Error opening %s %d (%s)", p, dnssd_errno, dnssd_strerror(dnssd_errno));
+ if (dnssd_SocketValid(listenfd) || dnssd_errno != EBUSY) break;
+ }
+ }
+
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &vec;
sizeof(struct cmsghdr) + sizeof(dnssd_sock_t),
CMSG_LEN(sizeof(dnssd_sock_t)), (long)CMSG_SPACE(sizeof(dnssd_sock_t)),
(long)((char*)CMSG_DATA(cmsg) + 4 - cbuf));
-#endif DEBUG_64BIT_SCM_RIGHTS
+#endif // DEBUG_64BIT_SCM_RIGHTS
if (sendmsg(sdr->sockfd, &msg, 0) < 0)
{
- syslog(LOG_WARNING, "dnssd_clientstub ERROR: sendmsg failed read sd=%d write sd=%d errno %d (%s)",
- errsd, listenfd, errno, strerror(errno));
+ syslog(LOG_WARNING, "dnssd_clientstub deliver_request ERROR: sendmsg failed read sd=%d write sd=%d errno %d (%s)",
+ errsd, listenfd, dnssd_errno, dnssd_strerror(dnssd_errno));
err = kDNSServiceErr_Incompatible;
goto cleanup;
}
#if DEBUG_64BIT_SCM_RIGHTS
syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d okay", errsd, listenfd);
-#endif DEBUG_64BIT_SCM_RIGHTS
+#endif // DEBUG_64BIT_SCM_RIGHTS
#endif
// Close our end of the socketpair *before* blocking in read_all to get the four-byte error code.
// At this point we may block in read_all for a few milliseconds waiting for the daemon to send us the error code,
// but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
- if (read_all(errsd, (char*)&err, (int)sizeof(err)) < 0)
+ if (sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
+ err = kDNSServiceErr_NoError;
+ else if (read_all(errsd, (char*)&err, (int)sizeof(err)) < 0)
err = kDNSServiceErr_ServiceNotRunning; // On failure read_all will have written a message to syslog for us
else
err = ntohl(err);
#if defined(USE_NAMED_ERROR_RETURN_SOCKET)
// syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removing UDS: %s", data);
if (unlink(data) != 0)
- syslog(LOG_WARNING, "dnssd_clientstub WARNING: unlink(\"%s\") failed errno %d (%s)", data, errno, strerror(errno));
+ syslog(LOG_WARNING, "dnssd_clientstub WARNING: unlink(\"%s\") failed errno %d (%s)", data, dnssd_errno, dnssd_strerror(dnssd_errno));
// else syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removed UDS: %s", data);
#endif
}
+
free(hdr);
return err;
}
if (!sdRef->ProcessReply)
{
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function");
+ static int num_logs = 0;
+ if (num_logs < 10) syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function");
+ if (num_logs < 1000) num_logs++; else sleep(1);
return kDNSServiceErr_BadReference;
}
// return NoError on EWOULDBLOCK. This will handle the case
// where a non-blocking socket is told there is data, but it was a false positive.
// On error, read_all will write a message to syslog for us, so don't need to duplicate that here
- if (read_all(sdRef->sockfd, (void *)&cbh.ipc_hdr, sizeof(cbh.ipc_hdr)) < 0)
+ // Note: If we want to properly support using non-blocking sockets in the future
+ int result = read_all(sdRef->sockfd, (void *)&cbh.ipc_hdr, sizeof(cbh.ipc_hdr));
+ if (result == read_all_fail)
{
- if (dnssd_errno() != dnssd_EWOULDBLOCK)
- {
- sdRef->ProcessReply = NULL;
- return kDNSServiceErr_ServiceNotRunning;
- }
- else
+ sdRef->ProcessReply = NULL;
+ return kDNSServiceErr_ServiceNotRunning;
+ }
+ else if (result == read_all_wouldblock)
+ {
+ if (morebytes && sdRef->logcounter < 100)
{
- if (morebytes && sdRef->logcounter < 100)
- {
- sdRef->logcounter++;
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult error: select indicated data was waiting but read_all returned EWOULDBLOCK");
- }
- return kDNSServiceErr_NoError;
+ sdRef->logcounter++;
+ syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult error: select indicated data was waiting but read_all returned EWOULDBLOCK");
}
+ return kDNSServiceErr_NoError;
}
ConvertHeaderBytes(&cbh.ipc_hdr);
}
else
{
- char *ptr = data;
+ const char *ptr = data;
cbh.cb_flags = get_flags (&ptr, data + cbh.ipc_hdr.datalen);
cbh.cb_interface = get_uint32 (&ptr, data + cbh.ipc_hdr.datalen);
cbh.cb_err = get_error_code(&ptr, data + cbh.ipc_hdr.datalen);
return kDNSServiceErr_NoError;
}
-static void handle_resolve_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_resolve_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *end)
{
char fullname[kDNSServiceMaxDomainName];
char target[kDNSServiceMaxDomainName];
get_string(&data, end, fullname, kDNSServiceMaxDomainName);
get_string(&data, end, target, kDNSServiceMaxDomainName);
- if (data + 2 > end) data = NULL;
+ if (!data || data + 2 > end) data = NULL;
else
{
port.b[0] = *data++;
return err;
}
-static void handle_query_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_query_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
uint32_t ttl;
char name[kDNSServiceMaxDomainName];
uint16_t rrtype, rrclass, rdlen;
- char *rdata;
+ const char *rdata;
get_string(&data, end, name, kDNSServiceMaxDomainName);
rrtype = get_uint16(&data, end);
return err;
}
-static void handle_addrinfo_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_addrinfo_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
char hostname[kDNSServiceMaxDomainName];
uint16_t rrtype, rrclass, rdlen;
- char *rdata;
+ const char *rdata;
uint32_t ttl;
get_string(&data, end, hostname, kDNSServiceMaxDomainName);
const struct sockaddr *const sa = (rrtype == kDNSServiceType_A) ? (struct sockaddr*)&sa4 : (struct sockaddr*)&sa6;
if (rrtype == kDNSServiceType_A)
{
- bzero(&sa4, sizeof(sa4));
+ memset(&sa4, 0, sizeof(sa4));
#ifndef NOT_HAVE_SA_LEN
sa4.sin_len = sizeof(struct sockaddr_in);
#endif
}
else
{
- bzero(&sa6, sizeof(sa6));
+ memset(&sa6, 0, sizeof(sa6));
#ifndef NOT_HAVE_SA_LEN
sa6.sin6_len = sizeof(struct sockaddr_in6);
#endif
return err;
}
-static void handle_browse_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_browse_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
char replyName[256], replyType[kDNSServiceMaxDomainName], replyDomain[kDNSServiceMaxDomainName];
get_string(&data, end, replyName, 256);
return err;
}
-static void handle_regservice_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_regservice_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
char name[256], regtype[kDNSServiceMaxDomainName], domain[kDNSServiceMaxDomainName];
get_string(&data, end, name, 256);
return err;
}
-static void handle_enumeration_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_enumeration_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
char domain[kDNSServiceMaxDomainName];
get_string(&data, end, domain, kDNSServiceMaxDomainName);
return err;
}
-static void ConnectionResponse(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void ConnectionResponse(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *const data, const char *const end)
{
DNSRecordRef rref = cbh->ipc_hdr.client_context.context;
(void)data; // Unused
if (cbh->ipc_hdr.op != reg_record_reply_op)
{
// When using kDNSServiceFlagsShareConnection, need to search the list of associated DNSServiceOps
- // to find the one this response is intended for, and then call through to its ProcessReply handler
- while (sdr && (sdr->uid.u32[0] != cbh->ipc_hdr.client_context.u32[0] || sdr->uid.u32[1] != cbh->ipc_hdr.client_context.u32[1]))
- sdr = sdr->next;
- // NOTE: We may sometimes not find a matching DNSServiceOp, in the case where the client has
+ // to find the one this response is intended for, and then call through to its ProcessReply handler.
+ // We start with our first subordinate DNSServiceRef -- don't want to accidentally match the parent DNSServiceRef.
+ DNSServiceOp *op = sdr->next;
+ while (op && (op->uid.u32[0] != cbh->ipc_hdr.client_context.u32[0] || op->uid.u32[1] != cbh->ipc_hdr.client_context.u32[1]))
+ op = op->next;
+ // Note: We may sometimes not find a matching DNSServiceOp, in the case where the client has
// cancelled the subordinate DNSServiceOp, but there are still messages in the pipeline from the daemon
- if (sdr && sdr->ProcessReply) sdr->ProcessReply(sdr, cbh, data, end);
- // WARNING: Don't touch sdr after this -- client may have called DNSServiceRefDeallocate
+ if (op && op->ProcessReply) op->ProcessReply(op, cbh, data, end);
+ // WARNING: Don't touch op or sdr after this -- client may have called DNSServiceRefDeallocate
return;
}
rref->AppCallback(rref->sdr, rref, cbh->cb_flags, cbh->cb_err, rref->AppContext);
else
{
- syslog(LOG_WARNING, "dnssd_clientstub handle_regrecord_response: sdr->op != connection_request");
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectionResponse: sdr->op != connection_request");
rref->AppCallback(rref->sdr, rref, 0, kDNSServiceErr_Unknown, rref->AppContext);
}
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
rref->record_index = sdRef->max_index++;
rref->sdr = sdRef;
*RecordRef = rref;
- hdr->client_context.context = rref;
hdr->reg_index = rref->record_index;
return deliver_request(hdr, sdRef); // Will free hdr for us
return err;
}
-static void handle_port_mapping_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
+static void handle_port_mapping_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
{
union { uint32_t l; u_char b[4]; } addr;
uint8_t protocol = 0;
- union { uint16_t s; u_char b[2]; } privatePort;
- union { uint16_t s; u_char b[2]; } publicPort;
+ union { uint16_t s; u_char b[2]; } internalPort;
+ union { uint16_t s; u_char b[2]; } externalPort;
uint32_t ttl = 0;
- if (data + 13 > end) data = NULL;
+ if (!data || data + 13 > end) data = NULL;
else
{
- addr .b[0] = *data++;
- addr .b[1] = *data++;
- addr .b[2] = *data++;
- addr .b[3] = *data++;
- protocol = *data++;
- privatePort.b[0] = *data++;
- privatePort.b[1] = *data++;
- publicPort .b[0] = *data++;
- publicPort .b[1] = *data++;
- ttl = get_uint32(&data, end);
+ addr .b[0] = *data++;
+ addr .b[1] = *data++;
+ addr .b[2] = *data++;
+ addr .b[3] = *data++;
+ protocol = *data++;
+ internalPort.b[0] = *data++;
+ internalPort.b[1] = *data++;
+ externalPort.b[0] = *data++;
+ externalPort.b[1] = *data++;
+ ttl = get_uint32(&data, end);
}
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_port_mapping_response: error reading result from daemon");
- else ((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, addr.l, protocol, privatePort.s, publicPort.s, ttl, sdr->AppContext);
+ else ((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, addr.l, protocol, internalPort.s, externalPort.s, ttl, sdr->AppContext);
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
}
DNSServiceFlags flags,
uint32_t interfaceIndex,
uint32_t protocol, /* TCP and/or UDP */
- uint16_t privatePortInNetworkByteOrder,
- uint16_t publicPortInNetworkByteOrder,
+ uint16_t internalPortInNetworkByteOrder,
+ uint16_t externalPortInNetworkByteOrder,
uint32_t ttl, /* time to live in seconds */
DNSServiceNATPortMappingReply callBack,
void *context /* may be NULL */
char *ptr;
size_t len;
ipc_msg_hdr *hdr;
- union { uint16_t s; u_char b[2]; } privatePort = { privatePortInNetworkByteOrder };
- union { uint16_t s; u_char b[2]; } publicPort = { publicPortInNetworkByteOrder };
+ union { uint16_t s; u_char b[2]; } internalPort = { internalPortInNetworkByteOrder };
+ union { uint16_t s; u_char b[2]; } externalPort = { externalPortInNetworkByteOrder };
DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(flags);
len += sizeof(interfaceIndex);
len += sizeof(protocol);
- len += sizeof(privatePort);
- len += sizeof(publicPort);
+ len += sizeof(internalPort);
+ len += sizeof(externalPort);
len += sizeof(ttl);
hdr = create_hdr(port_mapping_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
put_flags(flags, &ptr);
put_uint32(interfaceIndex, &ptr);
put_uint32(protocol, &ptr);
- *ptr++ = privatePort.b[0];
- *ptr++ = privatePort.b[1];
- *ptr++ = publicPort .b[0];
- *ptr++ = publicPort .b[1];
+ *ptr++ = internalPort.b[0];
+ *ptr++ = internalPort.b[1];
+ *ptr++ = externalPort.b[0];
+ *ptr++ = externalPort.b[1];
put_uint32(ttl, &ptr);
err = deliver_request(hdr, *sdRef); // Will free hdr for us
Change History (most recent first):
$Log: dnssd_ipc.c,v $
+Revision 1.23 2009/04/01 21:10:34 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+
+Revision 1.22 2009/02/12 20:28:31 cheshire
+Added some missing "const" declarations
+
+Revision 1.21 2008/10/23 23:21:31 cheshire
+Moved definition of dnssd_strerror() to be with the definition of dnssd_errno, in dnssd_ipc.h
+
Revision 1.20 2007/07/23 22:12:53 cheshire
<rdar://problem/5352299> Make mDNSResponder more defensive against malicious local clients
#include "dnssd_ipc.h"
+#if defined(_WIN32)
+
+char *win32_strerror(int inErrorCode)
+ {
+ static char buffer[1024];
+ DWORD n;
+ memset(buffer, 0, sizeof(buffer));
+ n = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ (DWORD) inErrorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer,
+ sizeof(buffer),
+ NULL);
+ if (n > 0)
+ {
+ // Remove any trailing CR's or LF's since some messages have them.
+ while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
+ buffer[--n] = '\0';
+ }
+ return buffer;
+ }
+
+#endif
+
void put_uint32(const uint32_t l, char **ptr)
{
(*ptr)[0] = (char)((l >> 24) & 0xFF);
*ptr += sizeof(uint32_t);
}
-uint32_t get_uint32(char **ptr, char *end)
+uint32_t get_uint32(const char **ptr, const char *end)
{
if (!*ptr || *ptr + sizeof(uint32_t) > end)
{
*ptr += sizeof(uint16_t);
}
-uint16_t get_uint16(char **ptr, char *end)
+uint16_t get_uint16(const char **ptr, const char *end)
{
if (!*ptr || *ptr + sizeof(uint16_t) > end)
{
return 0;
}
-int get_string(char **ptr, char *end, char *buffer, int buflen)
+int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
{
if (!*ptr)
{
*ptr += rdlen;
}
-char *get_rdata(char **ptr, char *end, int rdlen)
+const char *get_rdata(const char **ptr, const char *end, int rdlen)
{
if (!*ptr || *ptr + rdlen > end)
{
}
else
{
- char *rd = *ptr;
+ const char *rd = *ptr;
*ptr += rdlen;
return rd;
}
Change History (most recent first):
$Log: dnssd_ipc.h,v $
+Revision 1.46 2009/05/27 22:20:44 cheshire
+Removed unused dnssd_errno_assign() (we have no business writing to errno -- we should only read it)
+
+Revision 1.45 2009/05/26 21:31:07 herscher
+Fix compile errors on Windows
+
+Revision 1.44 2009/02/12 20:28:31 cheshire
+Added some missing "const" declarations
+
+Revision 1.43 2008/10/23 23:21:31 cheshire
+Moved definition of dnssd_strerror() to be with the definition of dnssd_errno, in dnssd_ipc.h
+
+Revision 1.42 2008/10/23 23:06:17 cheshire
+Removed () from dnssd_errno macro definition -- it's not a function and doesn't need any arguments
+
+Revision 1.41 2008/09/27 01:04:09 cheshire
+Added "send_bpf" to list of request_op_t operation codes
+
Revision 1.40 2007/09/07 20:56:03 cheshire
Renamed uint32_t field in client_context_t from "ptr64" to more accurate name "u32"
# define dnssd_sock_t SOCKET
# define dnssd_socklen_t int
# define dnssd_close(sock) closesocket(sock)
-# define dnssd_errno() WSAGetLastError()
+# define dnssd_errno WSAGetLastError()
+# define dnssd_strerror(X) win32_strerror(X)
# define ssize_t int
# define getpid _getpid
#else
# define dnssd_sock_t int
# define dnssd_socklen_t unsigned int
# define dnssd_close(sock) close(sock)
-# define dnssd_errno() errno
+# define dnssd_errno errno
+# define dnssd_strerror(X) strerror(X)
#endif
#if defined(USE_TCP_LOOPBACK)
getproperty_request, // New in B4W 1.0.4
port_mapping_request, // New in Leopard and B4W 2.0
addrinfo_request,
+ send_bpf, // New in SL
cancel_request = 63
} request_op_t;
// it is advanced to point to the next field, or the end of the message
void put_uint32(const uint32_t l, char **ptr);
-uint32_t get_uint32(char **ptr, char *end);
+uint32_t get_uint32(const char **ptr, const char *end);
void put_uint16(uint16_t s, char **ptr);
-uint16_t get_uint16(char **ptr, char *end);
+uint16_t get_uint16(const char **ptr, const char *end);
#define put_flags put_uint32
#define get_flags get_uint32
#define get_error_code get_uint32
int put_string(const char *str, char **ptr);
-int get_string(char **ptr, char *end, char *buffer, int buflen);
+int get_string(const char **ptr, const char *const end, char *buffer, int buflen);
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
-char *get_rdata(char **ptr, char *end, int rdlen); // return value is rdata pointed to by *ptr -
+const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr -
// rdata is not copied from buffer.
void ConvertHeaderBytes(ipc_msg_hdr *hdr);
Change History (most recent first):
$Log: mDNSDebug.c,v $
+Revision 1.16 2009/04/11 01:43:28 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.15 2009/04/11 00:20:26 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.14 2008/11/26 00:01:08 cheshire
+Get rid of "Unknown" tag in SIGINFO output on Leopard
+
Revision 1.13 2007/12/01 00:40:30 cheshire
Fixes from Bob Bradley for building on EFI
#include "mDNSEmbeddedAPI.h"
-mDNSexport LogLevel_t mDNS_LogLevel = MDNS_LOG_INITIAL_LEVEL;
+mDNSexport int mDNS_LoggingEnabled = 0;
+mDNSexport int mDNS_PacketLoggingEnabled = 0;
#if MDNS_DEBUGMSGS
mDNSexport int mDNS_DebugMode = mDNStrue;
// Note, this uses mDNS_vsnprintf instead of standard "vsnprintf", because mDNS_vsnprintf knows
// how to print special data types like IP addresses and length-prefixed domain names
-#if MDNS_DEBUGMSGS
-mDNSexport void debugf_(const char *format, ...)
- {
- char buffer[512];
- va_list ptr;
- va_start(ptr,format);
- buffer[mDNS_vsnprintf(buffer, sizeof(buffer), format, ptr)] = 0;
- va_end(ptr);
- mDNSPlatformWriteDebugMsg(buffer);
- }
-#endif
-
#if MDNS_DEBUGMSGS > 1
mDNSexport void verbosedebugf_(const char *format, ...)
{
#endif
// Log message with default "mDNSResponder" ident string at the start
-mDNSexport void LogMsg(const char *format, ...)
+mDNSlocal void LogMsgWithLevelv(mDNSLogLevel_t logLevel, const char *format, va_list ptr)
{
char buffer[512];
- va_list ptr;
- va_start(ptr,format);
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
- va_end(ptr);
- mDNSPlatformWriteLogMsg(ProgramName, buffer, 0);
+ mDNSPlatformWriteLogMsg(ProgramName, buffer, logLevel);
}
-// Log message with specified ident string at the start
-mDNSexport void LogMsgIdent(const char *ident, const char *format, ...)
- {
- char buffer[512];
- va_list ptr;
- va_start(ptr,format);
- buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
- va_end(ptr);
- mDNSPlatformWriteLogMsg(ident, buffer, ident && *ident ? LOG_PID : 0);
+#define LOG_HELPER_BODY(L) \
+ { \
+ va_list ptr; \
+ va_start(ptr,format); \
+ LogMsgWithLevelv(L, format, ptr); \
+ va_end(ptr); \
}
-// Log message with no ident string at the start
-mDNSexport void LogMsgNoIdent(const char *format, ...)
- {
- char buffer[512];
- va_list ptr;
- va_start(ptr,format);
- buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
- va_end(ptr);
- mDNSPlatformWriteLogMsg("", buffer, 0);
- }
+// see mDNSDebug.h
+#if !MDNS_HAS_VA_ARG_MACROS
+void debug_noop(const char *format, ...) { (void) format; }
+void LogMsg_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_MSG)
+void LogOperation_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_OPERATION)
+void LogSPS_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_SPS)
+void LogInfo_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_INFO)
+#endif
-mDNSlocal const char *CStringForLogLevel(LogLevel_t level)
- {
- switch (level)
- {
- case MDNS_LOG_NONE: return "MDNS_LOG_NONE";
-// case MDNS_LOG_ERROR: return "MDNS_LOG_ERROR";
-// case MDNS_LOG_WARN: return "MDNS_LOG_WARN";
-// case MDNS_LOG_INFO: return "MDNS_LOG_INFO";
-// case MDNS_LOG_DEBUG: return "MDNS_LOG_DEBUG";
- case MDNS_LOG_VERBOSE_DEBUG: return "MDNS_LOG_VERBOSE_DEBUG";
- default: return "MDNS_LOG_UNKNOWN";
- }
- }
+#if MDNS_DEBUGMSGS
+void debugf_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_DEBUG)
+#endif
-mDNSexport void SigLogLevel(void)
- {
- if (mDNS_LogLevel < MDNS_LOG_VERBOSE_DEBUG) mDNS_LogLevel++;
- else mDNS_LogLevel = MDNS_LOG_NONE;
- LogMsg("Log Level Changed to %s", CStringForLogLevel(mDNS_LogLevel));
- }
+// Log message with default "mDNSResponder" ident string at the start
+mDNSexport void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...)
+ LOG_HELPER_BODY(logLevel)
.\" limitations under the License.
.\"
.\" $Log: mDNSResponder.8,v $
+.\" Revision 1.10 2009/04/20 16:12:13 mcguire
+.\" <rdar://problem/6807798> manpage: roff errors
+.\"
+.\" Revision 1.9 2009/04/11 00:20:27 jessic2
+.\" <rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+.\"
.\" Revision 1.8 2006/10/06 17:31:33 mkrochma
.\" <rdar://problem/4769407> Typo in man page for mDNSResponder(8)
.\"
.\"
.Sh NAME
.Nm mDNSResponder
-.Nd Multicast DNS daemon \" Name Description for whatis database
+.Nd Multicast and Unicast DNS daemon \" Name Description for whatis database
.\"
.Sh SYNOPSIS
.Nm
(also known as
.Nm mdnsd
on some systems)
-is a daemon invoked at boot time to implement Multicast DNS
-and DNS Service Discovery.
+is a daemon invoked at boot time to implement Multicast DNS and DNS Service Discovery. On
+Mac OS X 10.6 (Snow Leopard),
+.Nm
+is also the system-wide Unicast DNS Resolver.
.Pp
.Nm
-listens UDP port 5353 for Multicast DNS Query packets.
+listens on UDP port 5353 for Multicast DNS Query packets.
When it receives a query for which it knows an answer,
.Nm
issues the appropriate Multicast DNS Reply packet.
.Pp
.Nm
-also performs Multicast DNS Queries on behalf of client processes,
-and maintains a cache of the replies.
+also performs Unicast and Multicast DNS Queries on behalf of client processes, and
+maintains a cache of the replies.
.Pp
.Nm
has no user-specifiable command-line argument, and users should not run
.Nm
manually.
.Pp
-To examine
-.Nm Ns 's internal state, for debugging and diagnostic purposes,
-send it a SIGINFO signal, and it will then dump a snapshot summary
-of its internal state to
-.Pa /var/log/system.log Ns , e.g.
+.Ss LOGGING
+There are several methods with which to examine
+.Nm Ns 's internal state for debugging and diagnostic purposes. The syslog(1)
+logging levels map as follows:
+.Pp
+.Dl Error - Error messages
+.Dl Warning - Client-initiated operations
+.Dl Notice - Sleep proxy operations
+.Dl Info - Informational messages
+.Pp
+By default, only log level Error is logged.
+.Pp
+A SIGUSR1 signal toggles additional logging, with Warning and Notice
+enabled by default:
+.Pp
+.Dl % sudo killall -USR1 mDNSResponder
+.Pp
+Once this logging is enabled, users can additionally use syslog(1)
+to change the log filter for the process. For example, to enable log levels Emergency - Debug:
+.Pp
+.Dl % sudo syslog -c mDNSResponder -d
+.Pp
+A SIGUSR2 signal toggles packet logging:
+.Pp
+.Dl % sudo killall -USR2 mDNSResponder
+.Pp
+A SIGINFO signal will dump a snapshot summary of the internal state to
+.Pa /var/log/system.log Ns :
.Pp
-.Dl sudo killall -INFO mDNSResponder
+.Dl % sudo killall -INFO mDNSResponder
.Sh FILES
.Pa /usr/sbin/mDNSResponder \" Pathname
.\"
Change History (most recent first):
$Log: uds_daemon.c,v $
+Revision 1.461 2009/06/19 23:15:07 cheshire
+<rdar://problem/6990066> Library: crash at handle_resolve_response + 183
+Made resolve_result_callback code more defensive and improved LogOperation messages
+
+Revision 1.460 2009/05/26 21:31:07 herscher
+Fix compile errors on Windows
+
+Revision 1.459 2009/04/30 20:07:51 mcguire
+<rdar://problem/6822674> Support multiple UDSs from launchd
+
+Revision 1.458 2009/04/25 00:59:06 mcguire
+Change a few stray LogInfo to LogOperation
+
+Revision 1.457 2009/04/22 01:19:57 jessic2
+<rdar://problem/6814585> Daemon: mDNSResponder is logging garbage for error codes because it's using %ld for int 32
+
+Revision 1.456 2009/04/21 01:56:34 jessic2
+<rdar://problem/6803941> BTMM: Back out change for preventing other local users from sending packets to your BTMM machines
+
+Revision 1.455 2009/04/20 19:19:57 cheshire
+<rdar://problem/6803941> BTMM: If multiple local users are logged in to same BTMM account, all but one fail
+Don't need "empty info->u.browser.browsers list" debugging message, now that we expect this to be
+a case that can legitimately happen.
+
+Revision 1.454 2009/04/18 20:56:43 jessic2
+<rdar://problem/6803941> BTMM: If multiple local users are logged in to same BTMM account, all but one fail
+
+Revision 1.453 2009/04/11 00:20:29 jessic2
+<rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically
+
+Revision 1.452 2009/04/07 01:17:42 jessic2
+<rdar://problem/6747917> BTMM: Multiple accounts lets me see others' remote services & send packets to others' remote hosts
+
+Revision 1.451 2009/04/02 22:34:26 jessic2
+<rdar://problem/6305347> Race condition: If fd has already been closed, SO_NOSIGPIPE returns errno 22 (Invalid argument)
+
+Revision 1.450 2009/04/01 21:11:28 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows. Workaround use of recvmsg.
+
+Revision 1.449 2009/03/17 19:44:25 cheshire
+<rdar://problem/6688927> Don't let negative unicast answers block Multicast DNS responses
+
+Revision 1.448 2009/03/17 04:53:40 cheshire
+<rdar://problem/6688927> Don't let negative unicast answers block Multicast DNS responses
+
+Revision 1.447 2009/03/17 04:41:32 cheshire
+Moved LogOperation message to after check for "if (answer->RecordType == kDNSRecordTypePacketNegative)"
+
+Revision 1.446 2009/03/04 01:47:35 cheshire
+Include m->ProxyRecords in SIGINFO output
+
+Revision 1.445 2009/03/03 23:04:44 cheshire
+For clarity, renamed "MAC" field to "HMAC" (Host MAC, as opposed to Interface MAC)
+
+Revision 1.444 2009/03/03 22:51:55 cheshire
+<rdar://problem/6504236> Sleep Proxy: Waking on same network but different interface will cause conflicts
+
+Revision 1.443 2009/02/27 02:28:41 cheshire
+Need to declare "const AuthRecord *ar;"
+
+Revision 1.442 2009/02/27 00:58:17 cheshire
+Improved detail of SIGINFO logging for m->DuplicateRecords
+
+Revision 1.441 2009/02/24 22:18:59 cheshire
+Include interface name for interface-specific AuthRecords
+
+Revision 1.440 2009/02/21 01:38:08 cheshire
+Added report of m->SleepState value in SIGINFO output
+
+Revision 1.439 2009/02/18 23:38:44 cheshire
+<rdar://problem/6600780> Could not write data to client 13 - aborting connection
+Eliminated unnecessary "request_state *request" field from the reply_state structure.
+
+Revision 1.438 2009/02/18 23:23:14 cheshire
+Cleaned up debugging log messages
+
+Revision 1.437 2009/02/17 23:29:05 cheshire
+Throttle logging to a slower rate when running on SnowLeopard
+
+Revision 1.436 2009/02/13 06:28:02 cheshire
+Converted LogOperation messages to LogInfo
+
+Revision 1.435 2009/02/12 20:57:26 cheshire
+Renamed 'LogAllOperation' switch to 'LogClientOperations'; added new 'LogSleepProxyActions' switch
+
+Revision 1.434 2009/02/12 20:28:31 cheshire
+Added some missing "const" declarations
+
+Revision 1.433 2009/02/10 01:44:39 cheshire
+<rdar://problem/6553729> DNSServiceUpdateRecord fails with kDNSServiceErr_BadReference for otherwise valid reference
+
+Revision 1.432 2009/02/10 01:38:56 cheshire
+Move regservice_termination_callback() earlier in file in preparation for subsequent work
+
+Revision 1.431 2009/02/07 01:48:55 cheshire
+In SIGINFO output include sequence number for proxied records
+
+Revision 1.430 2009/01/31 21:58:05 cheshire
+<rdar://problem/4786302> Implement logic to determine when to send dot-local lookups via Unicast
+Only want to do unicast dot-local lookups for address queries and conventional (RFC 2782) SRV queries
+
+Revision 1.429 2009/01/31 00:45:26 cheshire
+<rdar://problem/4786302> Implement logic to determine when to send dot-local lookups via Unicast
+Further refinements
+
+Revision 1.428 2009/01/30 19:52:31 cheshire
+Eliminated unnecessary duplicated "dnssd_sock_t sd" fields in service_instance and reply_state structures
+
+Revision 1.427 2009/01/24 01:48:43 cheshire
+<rdar://problem/4786302> Implement logic to determine when to send dot-local lookups via Unicast
+
+Revision 1.426 2009/01/16 21:07:08 cheshire
+In SIGINFO "Duplicate Records" list, show expiry time for Sleep Proxy records
+
+Revision 1.425 2009/01/16 20:53:16 cheshire
+Include information about Sleep Proxy records in SIGINFO output
+
+Revision 1.424 2009/01/12 22:43:50 cheshire
+Fixed "unused variable" warning when SO_NOSIGPIPE is not defined
+
+Revision 1.423 2009/01/10 22:54:42 mkrochma
+<rdar://problem/5797544> Fixes from Igor Seleznev to get mdnsd working on Linux
+
+Revision 1.422 2009/01/10 01:52:48 cheshire
+Include DuplicateRecords and LocalOnlyQuestions in SIGINFO output
+
+Revision 1.421 2008/12/17 05:05:26 cheshire
+Fixed alignment of NAT mapping syslog messages
+
+Revision 1.420 2008/12/12 00:52:05 cheshire
+mDNSPlatformSetBPF is now called mDNSPlatformReceiveBPF_fd
+
+Revision 1.419 2008/12/10 02:11:44 cheshire
+ARMv5 compiler doesn't like uncommented stuff after #endif
+
+Revision 1.418 2008/12/09 05:12:53 cheshire
+Updated debugging messages
+
+Revision 1.417 2008/12/04 03:38:12 cheshire
+Miscellaneous defensive coding changes and improvements to debugging log messages
+
+Revision 1.416 2008/12/02 22:02:12 cheshire
+<rdar://problem/6320621> Adding domains after TXT record updates registers stale TXT record data
+
+Revision 1.415 2008/11/26 20:35:59 cheshire
+Changed some "LogOperation" debugging messages to "debugf"
+
+Revision 1.414 2008/11/26 00:02:25 cheshire
+Improved SIGINFO output to list AutoBrowseDomains and AutoRegistrationDomains
+
+Revision 1.413 2008/11/25 04:48:58 cheshire
+Added logging to show whether Sleep Proxy Service is active
+
+Revision 1.412 2008/11/24 23:05:43 cheshire
+Additional checking in uds_validatelists()
+
+Revision 1.411 2008/11/05 21:41:39 cheshire
+Updated LogOperation message
+
+Revision 1.410 2008/11/04 20:06:20 cheshire
+<rdar://problem/6186231> Change MAX_DOMAIN_NAME to 256
+
+Revision 1.409 2008/10/31 23:44:22 cheshire
+Fixed compile error in Posix build
+
+Revision 1.408 2008/10/29 21:32:33 cheshire
+Align "DNSServiceEnumerateDomains ... RESULT" log messages
+
+Revision 1.407 2008/10/27 07:34:36 cheshire
+Additional sanity checks for debugging
+
+Revision 1.406 2008/10/23 23:55:56 cheshire
+Fixed some missing "const" declarations
+
+Revision 1.405 2008/10/23 23:21:31 cheshire
+Moved definition of dnssd_strerror() to be with the definition of dnssd_errno, in dnssd_ipc.h
+
+Revision 1.404 2008/10/23 23:06:17 cheshire
+Removed () from dnssd_errno macro definition -- it's not a function and doesn't need any arguments
+
+Revision 1.403 2008/10/23 22:33:25 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
+Revision 1.402 2008/10/22 19:47:59 cheshire
+Instead of SameRData(), use equivalent IdenticalSameNameRecord() macro
+
+Revision 1.401 2008/10/22 17:20:40 cheshire
+Don't give up if setsockopt SO_NOSIGPIPE fails
+
+Revision 1.400 2008/10/21 01:06:57 cheshire
+Pass BPF fd to mDNSMacOSX.c using mDNSPlatformSetBPF() instead of just writing it into a shared global variable
+
+Revision 1.399 2008/10/20 22:06:42 cheshire
+Updated debugging log messages
+
+Revision 1.398 2008/10/03 18:25:17 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
+Revision 1.397 2008/10/02 22:26:21 cheshire
+Moved declaration of BPF_fd from uds_daemon.c to mDNSMacOSX.c, where it really belongs
+
+Revision 1.396 2008/09/30 01:04:55 cheshire
+Made BPF code a bit more defensive, to ignore subsequent BPF fds if we get passed more than one
+
+Revision 1.395 2008/09/27 01:28:43 cheshire
+Added code to receive and store BPF fd when passed via a send_bpf message
+
+Revision 1.394 2008/09/23 04:12:40 cheshire
+<rdar://problem/6238774> Remove "local" from the end of _services._dns-sd._udp PTR records
+Added a special-case to massage these new records for Bonjour Browser's benefit
+
+Revision 1.393 2008/09/23 03:01:58 cheshire
+Added operation logging of domain enumeration results
+
+Revision 1.392 2008/09/18 22:30:06 cheshire
+<rdar://problem/6230679> device-info record not removed when last service deregisters
+
+Revision 1.391 2008/09/18 22:05:44 cheshire
+Fixed "DNSServiceRegister ... ADDED" message to have escaping consistent with
+the other DNSServiceRegister operation messages
+
+Revision 1.390 2008/09/16 21:06:56 cheshire
+Improved syslog output to show if q->LongLived flag is set for multicast questions
+
+Revision 1.389 2008/07/25 22:34:11 mcguire
+fix sizecheck issues for 64bit
+
+Revision 1.388 2008/07/01 01:40:02 mcguire
+<rdar://problem/5823010> 64-bit fixes
+
Revision 1.387 2008/02/26 21:24:13 cheshire
Fixed spelling mistake in comment
Improved SIGINFO listing of question state
Revision 1.376 2007/10/30 20:43:54 cheshire
-Fixed compiler warning when LogAllOperations is turned off
+Fixed compiler warning when LogClientOperations is turned off
Revision 1.375 2007/10/26 22:51:38 cheshire
Improved SIGINFO output to show timers for AuthRecords and ServiceRegistrations
#if defined(_WIN32)
#include <process.h>
-#define dnssd_strerror(X) win32_strerror(X)
#define usleep(X) Sleep(((X)+999)/1000)
-mDNSlocal char *win32_strerror(int inErrorCode)
- {
- static char buffer[1024];
- DWORD n;
- memset(buffer, 0, sizeof(buffer));
- n = FormatMessageA(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- (DWORD) inErrorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buffer,
- sizeof(buffer),
- NULL);
- if (n > 0)
- {
- // Remove any trailing CR's or LF's since some messages have them.
- while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
- buffer[--n] = '\0';
- }
- return buffer;
- }
#else
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
-#define dnssd_strerror(X) strerror(X)
#endif
#include <stdlib.h>
#include <stdio.h>
+
#include "mDNSEmbeddedAPI.h"
#include "DNSCommon.h"
#include "uDNS.h"
struct registered_record_entry *next;
mDNSu32 key;
AuthRecord *rr; // Pointer to variable-sized AuthRecord
- client_context_t client_context;
+ client_context_t regrec_client_context;
request_state *request;
} registered_record_entry;
{
struct service_instance *next;
request_state *request;
- dnssd_sock_t sd;
AuthRecord *subtypes;
mDNSBool renameonmemfree; // Set on config change when we deregister original name
mDNSBool clientnotified; // Has client been notified of successful registration yet?
struct request_state
{
request_state *next;
- request_state *primary; // If this operation is on a shared socket, pointer to
- // primary request_state for the original DNSServiceConnect() operation
+ request_state *primary; // If this operation is on a shared socket, pointer to primary
+ // request_state for the original DNSServiceConnect() operation
dnssd_sock_t sd;
dnssd_sock_t errsd;
mDNSu32 uid;
- // NOTE: On a shared connection these fields in the primary structure, including hdr, are re-used
+ // Note: On a shared connection these fields in the primary structure, including hdr, are re-used
// for each new request. This is because, until we've read the ipc_msg_hdr to find out what the
// operation is, we don't know if we're going to need to allocate a new request_state or not.
transfer_state ts;
- mDNSu32 hdr_bytes; // bytes of header already read
- ipc_msg_hdr hdr;
- mDNSu32 data_bytes; // bytes of message data already read
- char *msgbuf; // pointer to data storage to pass to free()
- char *msgptr; // pointer to data to be read from (may be modified)
- char *msgend; // pointer to byte after last byte of message
+ mDNSu32 hdr_bytes; // bytes of header already read
+ ipc_msg_hdr hdr;
+ mDNSu32 data_bytes; // bytes of message data already read
+ char *msgbuf; // pointer to data storage to pass to free()
+ const char *msgptr; // pointer to data to be read from (may be modified)
+ char *msgend; // pointer to byte after last byte of message
// reply, termination, error, and client context info
int no_reply; // don't send asynchronous replies to client
} pm;
struct
{
+#if 0
+ DNSServiceFlags flags;
+#endif
DNSQuestion q_all;
DNSQuestion q_default;
} enumeration;
struct
{
DNSQuestion q;
+ DNSQuestion q2;
} queryrecord;
struct
{
const ResourceRecord *srv;
mDNSs32 ReportTime;
} resolve;
- ;
} u;
};
typedef struct reply_state
{
- dnssd_sock_t sd;
- transfer_state ts;
+ struct reply_state *next; // If there are multiple unsent replies
+ mDNSu32 totallen;
mDNSu32 nwriten;
- mDNSu32 len;
- request_state *request; // the request that this answers
- struct reply_state *next; // if there are multiple unsent replies
- char *msgbuf; // pointer to malloc'd buffer
- ipc_msg_hdr *mhdr; // pointer into message buffer - allows fields to be changed after message is formatted
- reply_hdr *rhdr;
- char *sdata; // pointer to start of call-specific data
+ ipc_msg_hdr mhdr[1];
+ reply_hdr rhdr[1];
} reply_state;
// ***************************************************************************
mDNSlocal void FatalError(char *errmsg)
{
- LogMsg("%s: %s", errmsg, dnssd_strerror(dnssd_errno()));
+ LogMsg("%s: %s", errmsg, dnssd_strerror(dnssd_errno));
*(long*)0 = 0; // On OS X abort() doesn't generate a crash log, but writing to zero does
abort(); // On platforms where writing to zero doesn't generate an exception, abort instead
}
// hack to search-replace perror's to LogMsg's
mDNSlocal void my_perror(char *errmsg)
{
- LogMsg("%s: %s", errmsg, dnssd_strerror(dnssd_errno()));
+ LogMsg("%s: %d (%s)", errmsg, dnssd_errno, dnssd_strerror(dnssd_errno));
}
mDNSlocal void abort_request(request_state *req)
{
+ if (req->terminate == (req_termination_fn)~0)
+ { LogMsg("abort_request: ERROR: Attempt to abort operation %p with req->terminate %p", req, req->terminate); return; }
+
// First stop whatever mDNSCore operation we were doing
if (req->terminate) req->terminate(req);
- // Now, if this request_state is not subbordinate to some other primary, close file descriptor and discard replies
+ if (!dnssd_SocketValid(req->sd))
+ { LogMsg("abort_request: ERROR: Attempt to abort operation %p with invalid fd %d", req, req->sd); return; }
+
+ // Now, if this request_state is not subordinate to some other primary, close file descriptor and discard replies
if (!req->primary)
{
if (req->errsd != req->sd) LogOperation("%3d: Removing FD and closing errsd %d", req->sd, req->errsd);
{
reply_state *ptr = req->replies;
req->replies = req->replies->next;
- if (ptr->msgbuf) freeL("reply_state msgbuf (abort)", ptr->msgbuf);
freeL("reply_state (abort)", ptr);
}
}
-// Set req->sd to something invalid, so that udsserver_idle knows to unlink and free this structure
+ // Set req->sd to something invalid, so that udsserver_idle knows to unlink and free this structure
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
// Don't use dnssd_InvalidSocket (-1) because that's the sentinel value MACOSX_MDNS_MALLOC_DEBUGGING uses
// for detecting when the memory for an object is inadvertently freed while the object is still on some list
- req->sd = -2;
+ req->sd = req->errsd = -2;
#else
- req->sd = dnssd_InvalidSocket;
+ req->sd = req->errsd = dnssd_InvalidSocket;
#endif
+ // We also set req->terminate to a bogus value so we know if abort_request() gets called again for this request
+ req->terminate = (req_termination_fn)~0;
}
mDNSlocal void AbortUnlinkAndFree(request_state *req)
abort_request(req);
while (*p && *p != req) p=&(*p)->next;
if (*p) { *p = req->next; freeL("request_state/AbortUnlinkAndFree", req); }
+ else LogMsg("AbortUnlinkAndFree: ERROR: Attempt to abort operation %p not in list", req);
}
mDNSlocal reply_state *create_reply(const reply_op_t op, const size_t datalen, request_state *const request)
{
reply_state *reply;
- int totallen = (int) (datalen + sizeof(ipc_msg_hdr));
if ((unsigned)datalen < sizeof(reply_hdr))
{
- LogMsg("ERROR: create_reply - data length less than lenght of required fields");
+ LogMsg("ERROR: create_reply - data length less than length of required fields");
return NULL;
}
- reply = mallocL("reply_state", sizeof(reply_state));
+ reply = mallocL("reply_state", sizeof(reply_state) + datalen - sizeof(reply_hdr));
if (!reply) FatalError("ERROR: malloc");
- mDNSPlatformMemZero(reply, sizeof(reply_state));
- reply->ts = t_morecoming;
- reply->sd = request->sd;
- reply->request = request;
- reply->len = totallen;
- reply->msgbuf = mallocL("reply_state msgbuf", totallen);
- if (!reply->msgbuf) FatalError("ERROR: malloc");
- mDNSPlatformMemZero(reply->msgbuf, totallen);
- reply->mhdr = (ipc_msg_hdr *)reply->msgbuf;
- reply->rhdr = (reply_hdr *)(reply->msgbuf + sizeof(ipc_msg_hdr));
- reply->sdata = reply->msgbuf + sizeof(ipc_msg_hdr) + sizeof(reply_hdr);
- reply->mhdr->version = VERSION;
- reply->mhdr->datalen = datalen;
- reply->mhdr->ipc_flags = 0;
- reply->mhdr->op = op;
+
+ reply->next = mDNSNULL;
+ reply->totallen = datalen + sizeof(ipc_msg_hdr);
+ reply->nwriten = 0;
+
+ reply->mhdr->version = VERSION;
+ reply->mhdr->datalen = datalen;
+ reply->mhdr->ipc_flags = 0;
+ reply->mhdr->op = op;
reply->mhdr->client_context = request->hdr.client_context;
- reply->mhdr->reg_index = 0;
+ reply->mhdr->reg_index = 0;
+
return reply;
}
(*rep)->rhdr->error = dnssd_htonl(err);
// Build reply body
- data = (*rep)->sdata;
+ data = (char *)&(*rep)->rhdr[1];
put_string(namestr, &data);
put_string(typestr, &data);
put_string(domstr, &data);
}
}
+// Special support to enable the DNSServiceBrowse call made by Bonjour Browser
+// Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
+mDNSlocal void GenerateBonjourBrowserResponse(const domainname *const servicename, const mDNSInterfaceID id,
+ request_state *const request, reply_state **const rep, reply_op_t op, DNSServiceFlags flags, mStatus err)
+ {
+ char namestr[MAX_DOMAIN_LABEL+1];
+ char typestr[MAX_ESCAPED_DOMAIN_NAME];
+ static const char domstr[] = ".";
+ int len;
+ char *data;
+
+ *rep = NULL;
+
+ // 1. Put first label in namestr
+ ConvertDomainLabelToCString_unescaped((const domainlabel *)servicename, namestr);
+
+ // 2. Put second label and "local" into typestr
+ mDNS_snprintf(typestr, sizeof(typestr), "%#s.local.", SecondLabel(servicename));
+
+ // Calculate reply data length
+ len = sizeof(DNSServiceFlags);
+ len += sizeof(mDNSu32); // if index
+ len += sizeof(DNSServiceErrorType);
+ len += (int) (strlen(namestr) + 1);
+ len += (int) (strlen(typestr) + 1);
+ len += (int) (strlen(domstr) + 1);
+
+ // Build reply header
+ *rep = create_reply(op, len, request);
+ (*rep)->rhdr->flags = dnssd_htonl(flags);
+ (*rep)->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(&mDNSStorage, id));
+ (*rep)->rhdr->error = dnssd_htonl(err);
+
+ // Build reply body
+ data = (char *)&(*rep)->rhdr[1];
+ put_string(namestr, &data);
+ put_string(typestr, &data);
+ put_string(domstr, &data);
+ }
+
// Returns a resource record (allocated w/ malloc) containing the data found in an IPC message
// Data must be in the following format: flags, interfaceIndex, name, rrtype, rrclass, rdlen, rdata, (optional) ttl
// (ttl only extracted/set if ttl argument is non-zero). Returns NULL for a bad-parameter error
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
char name[256];
- int str_err = get_string(&request->msgptr, request->msgend, name, sizeof(name));
- mDNSu16 type = get_uint16(&request->msgptr, request->msgend);
- mDNSu16 class = get_uint16(&request->msgptr, request->msgend);
- mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
- char *rdata = get_rdata(&request->msgptr, request->msgend, rdlen);
+ int str_err = get_string(&request->msgptr, request->msgend, name, sizeof(name));
+ mDNSu16 type = get_uint16(&request->msgptr, request->msgend);
+ mDNSu16 class = get_uint16(&request->msgptr, request->msgend);
+ mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
+ const char *rdata = get_rdata (&request->msgptr, request->msgend, rdlen);
mDNSu32 ttl = GetTTL ? get_uint32(&request->msgptr, request->msgend) : 0;
int storage_size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
AuthRecord *rr;
// (four bytes for a typical error code return, 12 bytes for DNSServiceGetProperty(DaemonVersion)).
// If it does fail, we don't attempt to handle this failure, but we do log it so we know something is wrong.
if (n < len)
- LogMsg("ERROR: send_all(%d) wrote %d of %d errno %d %s",
- s, n, len, dnssd_errno(), dnssd_strerror(dnssd_errno()));
+ LogMsg("ERROR: send_all(%d) wrote %d of %d errno %d (%s)",
+ s, n, len, dnssd_errno, dnssd_strerror(dnssd_errno));
}
+#if 0
+mDNSlocal mDNSBool AuthorizedDomain(const request_state * const request, const domainname * const d, const DNameListElem * const doms)
+{
+ const DNameListElem *delem = mDNSNULL;
+ int bestDelta = -1; // the delta of the best match, lower is better
+ int dLabels = 0;
+ mDNSBool allow = mDNSfalse;
+
+ if (SystemUID(request->uid)) return mDNStrue;
+
+ dLabels = CountLabels(d);
+ for (delem = doms; delem; delem = delem->next)
+ {
+ if (delem->uid)
+ {
+ int delemLabels = CountLabels(&delem->name);
+ int delta = dLabels - delemLabels;
+ if ((bestDelta == -1 || delta <= bestDelta) && SameDomainName(&delem->name, SkipLeadingLabels(d, delta)))
+ {
+ bestDelta = delta;
+ allow = (allow || (delem->uid == request->uid));
+ }
+ }
+ }
+
+ return bestDelta == -1 ? mDNStrue : allow;
+}
+#endif
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
mDNSexport void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result)
{
ExtraResourceRecord *extra = (ExtraResourceRecord *)rr->RecordContext;
- (void)m; //unused
+ (void)m; // Unused
if (result != mStatus_MemFree) { LogMsg("Error: FreeExtraRR invoked with unexpected error %d", result); return; }
- LogOperation(" FreeExtraRR %s", RRDisplayString(m, &rr->resrec));
+ LogInfo(" FreeExtraRR %s", RRDisplayString(m, &rr->resrec));
if (rr->resrec.rdata != &rr->rdatastorage)
freeL("Extra RData", rr->resrec.rdata);
ServiceRecordSet *s;
for (rr = m->ResourceRecords; rr; rr=rr->next)
- if (rr->resrec.rrtype == kDNSType_SRV && SameDomainName(rr->resrec.name, r->name) && !SameRData(&rr->resrec, r))
+ if (rr->resrec.rrtype == kDNSType_SRV && SameDomainName(rr->resrec.name, r->name) && !IdenticalSameNameRecord(&rr->resrec, r))
count++;
for (s = m->ServiceRegistrations; s; s = s->uDNS_next)
- if (s->state != regState_Unregistered && SameDomainName(s->RR_SRV.resrec.name, r->name) && !SameRData(&s->RR_SRV.resrec, r))
+ if (s->state != regState_Unregistered && SameDomainName(s->RR_SRV.resrec.name, r->name) && !IdenticalSameNameRecord(&s->RR_SRV.resrec, r))
count++;
verbosedebugf("%d peer registrations for %##s", count, r->name->c);
reply_state *rep;
service_instance *instance = srs->ServiceContext;
if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, 0, mStatus_NoError) != mStatus_NoError)
- LogMsg("%3d: SendServiceRemovalNotification: %##s is not valid DNS-SD SRV name", instance->sd, srs->RR_SRV.resrec.name->c);
+ LogMsg("%3d: SendServiceRemovalNotification: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
else { append_reply(instance->request, rep); instance->clientnotified = mDNSfalse; }
}
// service registration callback performs three duties - frees memory for deregistered services,
-// handles name conflicts, and delivers completed registration information to the client (via
-// process_service_registraion())
+// handles name conflicts, and delivers completed registration information to the client
mDNSlocal void regservice_callback(mDNS *const m, ServiceRecordSet *const srs, mStatus result)
{
mStatus err;
mDNSBool SuppressError = mDNSfalse;
service_instance *instance = srs->ServiceContext;
reply_state *rep;
-#if LogAllOperations || MDNS_DEBUGMSGS
- char *fmt = (result == mStatus_NoError) ? "%3d: DNSServiceRegister(%##s, %u) REGISTERED" :
- (result == mStatus_MemFree) ? "%3d: DNSServiceRegister(%##s, %u) DEREGISTERED" :
- (result == mStatus_NameConflict) ? "%3d: DNSServiceRegister(%##s, %u) NAME CONFLICT" :
- "%3d: DNSServiceRegister(%##s, %u) %s %d";
-#endif
+ char *fmt = "";
+ if (mDNS_LoggingEnabled)
+ fmt = (result == mStatus_NoError) ? "%3d: DNSServiceRegister(%##s, %u) REGISTERED" :
+ (result == mStatus_MemFree) ? "%3d: DNSServiceRegister(%##s, %u) DEREGISTERED" :
+ (result == mStatus_NameConflict) ? "%3d: DNSServiceRegister(%##s, %u) NAME CONFLICT" :
+ "%3d: DNSServiceRegister(%##s, %u) %s %d";
(void)m; // Unused
if (!srs) { LogMsg("regservice_callback: srs is NULL %d", result); return; }
if (!instance) { LogMsg("regservice_callback: srs->ServiceContext is NULL %d", result); return; }
!instance->default_local)
SuppressError = mDNStrue;
- LogOperation(fmt, instance->sd, srs->RR_SRV.resrec.name->c, mDNSVal16(srs->RR_SRV.resrec.rdata->u.srv.port), SuppressError ? "suppressed error" : "CALLBACK", result);
+ LogOperation(fmt, instance->request ? instance->request->sd : -99,
+ srs->RR_SRV.resrec.name->c, mDNSVal16(srs->RR_SRV.resrec.rdata->u.srv.port), SuppressError ? "suppressed error" : "CALLBACK", result);
if (!instance->request && result != mStatus_MemFree) { LogMsg("regservice_callback: instance->request is NULL %d", result); return; }
}
if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, kDNSServiceFlagsAdd, result) != mStatus_NoError)
- LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->sd, srs->RR_SRV.resrec.name->c);
+ LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
else { append_reply(instance->request, rep); instance->clientnotified = mDNStrue; }
if (instance->request->u.servicereg.autoname && CountPeerRegistrations(m, srs) == 0)
{
instance->renameonmemfree = 0;
err = mDNS_RenameAndReregisterService(m, srs, &instance->request->u.servicereg.name);
- if (err) LogMsg("ERROR: regservice_callback - RenameAndReregisterService returned %ld", err);
+ if (err) LogMsg("ERROR: regservice_callback - RenameAndReregisterService returned %d", err);
// error should never happen - safest to log and continue
}
else
{
// On conflict for an autoname service, rename and reregister *all* autoname services
IncrementLabelSuffix(&m->nicelabel, mDNStrue);
- m->MainCallback(m, mStatus_ConfigChanged); // will call back into udsserver_handle_configchange()
+ mDNS_ConfigChanged(m); // Will call back into udsserver_handle_configchange()
}
else // On conflict for a non-autoname service, rename and reregister just that one service
{
if (!SuppressError)
{
if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, kDNSServiceFlagsAdd, result) != mStatus_NoError)
- LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->sd, srs->RR_SRV.resrec.name->c);
+ LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
else { append_reply(instance->request, rep); instance->clientnotified = mDNStrue; }
}
unlink_and_free_service_instance(instance);
if (!SuppressError)
{
if (GenerateNTDResponse(srs->RR_SRV.resrec.name, srs->RR_SRV.resrec.InterfaceID, instance->request, &rep, reg_service_reply_op, kDNSServiceFlagsAdd, result) != mStatus_NoError)
- LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->sd, srs->RR_SRV.resrec.name->c);
+ LogMsg("%3d: regservice_callback: %##s is not valid DNS-SD SRV name", instance->request->sd, srs->RR_SRV.resrec.name->c);
else { append_reply(instance->request, rep); instance->clientnotified = mDNStrue; }
}
}
request_state *request = re->request;
int len = sizeof(DNSServiceFlags) + sizeof(mDNSu32) + sizeof(DNSServiceErrorType);
reply_state *reply = create_reply(reg_record_reply_op, len, request);
- reply->mhdr->client_context = re->client_context;
+ reply->mhdr->client_context = re->regrec_client_context;
reply->rhdr->flags = dnssd_htonl(0);
reply->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, rr->resrec.InterfaceID));
reply->rhdr->error = dnssd_htonl(result);
{
// Since we're already doing a list traversal, we unlink the request directly instead of using AbortUnlinkAndFree()
request_state *tmp = *req;
+ if (tmp->primary == tmp) LogMsg("connection_termination ERROR (*req)->primary == *req for %p %d", tmp, tmp->sd);
+ if (tmp->replies) LogMsg("connection_termination ERROR How can subordinate req %p %d have replies queued?", tmp, tmp->sd);
abort_request(tmp);
*req = tmp->next;
freeL("request_state/connection_termination", tmp);
mDNSlocal void handle_cancel_request(request_state *request)
{
request_state **req = &all_requests;
- LogOperation("%3d: Cancel %X%08X", request->sd, request->hdr.client_context.u32[1], request->hdr.client_context.u32[0]);
+ LogOperation("%3d: Cancel %08X %08X", request->sd, request->hdr.client_context.u32[1], request->hdr.client_context.u32[0]);
while (*req)
{
if ((*req)->primary == request &&
re->key = request->hdr.reg_index;
re->rr = rr;
re->request = request;
- re->client_context = request->hdr.client_context;
+ re->regrec_client_context = request->hdr.client_context;
rr->RecordContext = re;
rr->RecordCallback = regrecord_callback;
re->next = request->u.reg_recs;
request->u.reg_recs = re;
+#if 0
+ if (!AuthorizedDomain(request, rr->resrec.name, AutoRegistrationDomains)) return (mStatus_NoError);
+#endif
if (rr->resrec.rroriginalttl == 0)
rr->resrec.rroriginalttl = DefaultTTLforRRType(rr->resrec.rrtype);
return(err);
}
-mDNSlocal mStatus add_record_to_service(request_state *request, service_instance *instance, mDNSu16 rrtype, mDNSu16 rdlen, char *rdata, mDNSu32 ttl)
+mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m);
+
+mDNSlocal void regservice_termination_callback(request_state *request)
+ {
+ if (!request) { LogMsg("regservice_termination_callback context is NULL"); return; }
+ while (request->u.servicereg.instances)
+ {
+ service_instance *p = request->u.servicereg.instances;
+ request->u.servicereg.instances = request->u.servicereg.instances->next;
+ // only safe to free memory if registration is not valid, i.e. deregister fails (which invalidates p)
+ LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP",
+ request->sd, p->srs.RR_SRV.resrec.name->c, mDNSVal16(p->srs.RR_SRV.resrec.rdata->u.srv.port));
+
+ // Clear backpointer *before* calling mDNS_DeregisterService/unlink_and_free_service_instance
+ // We don't need unlink_and_free_service_instance to cut its element from the list, because we're already advancing
+ // request->u.servicereg.instances as we work our way through the list, implicitly cutting one element at a time
+ // We can't clear p->request *after* the calling mDNS_DeregisterService/unlink_and_free_service_instance
+ // because by then we might have already freed p
+ p->request = NULL;
+ if (mDNS_DeregisterService(&mDNSStorage, &p->srs)) unlink_and_free_service_instance(p);
+ // Don't touch service_instance *p after this -- it's likely to have been freed already
+ }
+ if (request->u.servicereg.txtdata)
+ { freeL("service_info txtdata", request->u.servicereg.txtdata); request->u.servicereg.txtdata = NULL; }
+ if (request->u.servicereg.autoname)
+ {
+ // Clear autoname before calling UpdateDeviceInfoRecord() so it doesn't mistakenly include this in its count of active autoname registrations
+ request->u.servicereg.autoname = mDNSfalse;
+ UpdateDeviceInfoRecord(&mDNSStorage);
+ }
+ }
+
+mDNSlocal request_state *LocateSubordinateRequest(request_state *request)
+ {
+ request_state *req;
+ for (req = all_requests; req; req = req->next)
+ if (req->primary == request &&
+ req->hdr.client_context.u32[0] == request->hdr.client_context.u32[0] &&
+ req->hdr.client_context.u32[1] == request->hdr.client_context.u32[1]) return(req);
+ return(request);
+ }
+
+mDNSlocal mStatus add_record_to_service(request_state *request, service_instance *instance, mDNSu16 rrtype, mDNSu16 rdlen, const char *rdata, mDNSu32 ttl)
{
ServiceRecordSet *srs = &instance->srs;
mStatus result;
{
service_instance *i;
mStatus result = mStatus_UnknownErr;
- DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
- mDNSu16 rrtype = get_uint16(&request->msgptr, request->msgend);
- mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
- char *rdata = get_rdata(&request->msgptr, request->msgend, rdlen);
- mDNSu32 ttl = get_uint32(&request->msgptr, request->msgend);
+ DNSServiceFlags flags = get_flags (&request->msgptr, request->msgend);
+ mDNSu16 rrtype = get_uint16(&request->msgptr, request->msgend);
+ mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
+ const char *rdata = get_rdata (&request->msgptr, request->msgend, rdlen);
+ mDNSu32 ttl = get_uint32(&request->msgptr, request->msgend);
if (!ttl) ttl = DefaultTTLforRRType(rrtype);
(void)flags; // Unused
if (!request->msgptr) { LogMsg("%3d: DNSServiceAddRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ // If this is a shared connection, check if the operation actually applies to a subordinate request_state object
+ if (request->terminate == connection_termination) request = LocateSubordinateRequest(request);
+
+ if (request->terminate != regservice_termination_callback)
+ { LogMsg("%3d: DNSServiceAddRecord(not a registered service ref)", request->sd); return(mStatus_BadParamErr); }
+
LogOperation("%3d: DNSServiceAddRecord(%##s, %s, %d)", request->sd,
(request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL, DNSTypeName(rrtype), rdlen);
if (oldrd != &rr->rdatastorage) freeL("RData/update_callback", oldrd);
}
-mDNSlocal mStatus update_record(AuthRecord *rr, mDNSu16 rdlen, char *rdata, mDNSu32 ttl)
+mDNSlocal mStatus update_record(AuthRecord *rr, mDNSu16 rdlen, const char *rdata, mDNSu32 ttl)
{
int rdsize;
RData *newrd;
if (rr->resrec.rrtype == kDNSType_TXT && rdlen == 0) { rdlen = 1; newrd->u.txt.c[0] = 0; }
result = mDNS_Update(&mDNSStorage, rr, ttl, rdlen, newrd, update_callback);
- if (result) { LogMsg("ERROR: mDNS_Update - %ld", result); freeL("RData/update_record", newrd); }
+ if (result) { LogMsg("ERROR: mDNS_Update - %d", result); freeL("RData/update_record", newrd); }
return result;
}
mDNSlocal mStatus handle_update_request(request_state *request)
{
+ const ipc_msg_hdr *const hdr = &request->hdr;
mStatus result = mStatus_BadReferenceErr;
service_instance *i;
AuthRecord *rr = NULL;
// get the message data
- DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend); // flags unused
- mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
- char *rdata = get_rdata(&request->msgptr, request->msgend, rdlen);
- mDNSu32 ttl = get_uint32(&request->msgptr, request->msgend);
+ DNSServiceFlags flags = get_flags (&request->msgptr, request->msgend); // flags unused
+ mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
+ const char *rdata = get_rdata (&request->msgptr, request->msgend, rdlen);
+ mDNSu32 ttl = get_uint32(&request->msgptr, request->msgend);
(void)flags; // Unused
if (!request->msgptr) { LogMsg("%3d: DNSServiceUpdateRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ // If this is a shared connection, check if the operation actually applies to a subordinate request_state object
+ if (request->terminate == connection_termination) request = LocateSubordinateRequest(request);
+
if (request->terminate == connection_termination)
{
// update an individually registered record
registered_record_entry *reptr;
for (reptr = request->u.reg_recs; reptr; reptr = reptr->next)
{
- if (reptr->key == request->hdr.reg_index)
+ if (reptr->key == hdr->reg_index)
{
result = update_record(reptr->rr, rdlen, rdata, ttl);
goto end;
goto end;
}
+ if (request->terminate != regservice_termination_callback)
+ { LogMsg("%3d: DNSServiceUpdateRecord(not a registered service ref)", request->sd); return(mStatus_BadParamErr); }
+
+ // update the saved off TXT data for the service
+ if (hdr->reg_index == TXT_RECORD_INDEX)
+ {
+ if (request->u.servicereg.txtdata)
+ { freeL("service_info txtdata", request->u.servicereg.txtdata); request->u.servicereg.txtdata = NULL; }
+ if (rdlen > 0)
+ {
+ request->u.servicereg.txtdata = mallocL("service_info txtdata", rdlen);
+ if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_update_request - malloc");
+ mDNSPlatformMemCopy(request->u.servicereg.txtdata, rdata, rdlen);
+ }
+ else
+ request->u.servicereg.txtdata = NULL;
+ }
+
// update a record from a service record set
for (i = request->u.servicereg.instances; i; i = i->next)
{
- if (request->hdr.reg_index == TXT_RECORD_INDEX) rr = &i->srs.RR_TXT;
+ if (hdr->reg_index == TXT_RECORD_INDEX) rr = &i->srs.RR_TXT;
else
{
ExtraResourceRecord *e;
for (e = i->srs.Extras; e; e = e->next)
- if (e->ClientID == request->hdr.reg_index) { rr = &e->r; break; }
+ if (e->ClientID == hdr->reg_index) { rr = &e->r; break; }
}
if (!rr) { result = mStatus_BadReferenceErr; goto end; }
}
end:
- LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s)", request->sd,
- (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL,
- rr ? DNSTypeName(rr->resrec.rrtype) : "<NONE>");
+ if (request->terminate == regservice_termination_callback)
+ LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s)", request->sd,
+ (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL,
+ rr ? DNSTypeName(rr->resrec.rrtype) : "<NONE>");
return(result);
}
err = mDNS_Deregister(&mDNSStorage, e->rr);
if (err)
{
- LogMsg("ERROR: remove_record, mDNS_Deregister: %ld", err);
+ LogMsg("ERROR: remove_record, mDNS_Deregister: %d", err);
freeL("registered_record_entry AuthRecord remove_record", e->rr);
}
freeL("registered_record_entry remove_record", e);
if (!request->msgptr) { LogMsg("%3d: DNSServiceRemoveRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ // If this is a shared connection, check if the operation actually applies to a subordinate request_state object
+ if (request->terminate == connection_termination) request = LocateSubordinateRequest(request);
+
if (request->terminate == connection_termination)
err = remove_record(request); // remove individually registered record
+ else if (request->terminate != regservice_termination_callback)
+ { LogMsg("%3d: DNSServiceRemoveRecord(not a registered service ref)", request->sd); return(mStatus_BadParamErr); }
else
{
service_instance *i;
for (ptr = &request->u.servicereg.instances; *ptr; ptr = &(*ptr)->next)
{
if (SameDomainName(&(*ptr)->domain, domain))
- { LogMsg("register_service_instance: domain %##s already registered", domain->c); return mStatus_AlreadyRegistered; }
+ {
+ LogMsg("register_service_instance: domain %##s already registered for %#s.%##s",
+ domain->c, &request->u.servicereg.name, &request->u.servicereg.type);
+ return mStatus_AlreadyRegistered;
+ }
}
// Special-case hack: We don't advertise SMB service in AutoTunnel domains, because AutoTunnel
instance->next = mDNSNULL;
instance->request = request;
- instance->sd = request->sd;
instance->subtypes = AllocateSubTypes(request->u.servicereg.num_subtypes, request->u.servicereg.type_as_string);
instance->renameonmemfree = 0;
instance->clientnotified = mDNSfalse;
if (request->u.servicereg.num_subtypes && !instance->subtypes)
{ unlink_and_free_service_instance(instance); instance = NULL; FatalError("ERROR: malloc"); }
- LogOperation("%3d: DNSServiceRegister(%#s.%##s%##s, %u) ADDING",
- instance->sd, &request->u.servicereg.name, &request->u.servicereg.type, domain->c, mDNSVal16(request->u.servicereg.port));
-
result = mDNS_RegisterService(&mDNSStorage, &instance->srs,
&request->u.servicereg.name, &request->u.servicereg.type, domain,
request->u.servicereg.host.c[0] ? &request->u.servicereg.host : NULL,
instance->subtypes, request->u.servicereg.num_subtypes,
request->u.servicereg.InterfaceID, regservice_callback, instance);
- if (!result) *ptr = instance; // Append this to the end of our request->u.servicereg.instances list
+ if (!result)
+ {
+ *ptr = instance; // Append this to the end of our request->u.servicereg.instances list
+ LogOperation("%3d: DNSServiceRegister(%##s, %u) ADDED",
+ instance->request->sd, instance->srs.RR_SRV.resrec.name->c, mDNSVal16(request->u.servicereg.port));
+ }
else
{
LogMsg("register_service_instance %#s.%##s%##s error %d",
return result;
}
-mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m);
-
-mDNSlocal void regservice_termination_callback(request_state *request)
- {
- if (!request) { LogMsg("regservice_termination_callback context is NULL"); return; }
- while (request->u.servicereg.instances)
- {
- service_instance *p = request->u.servicereg.instances;
- request->u.servicereg.instances = request->u.servicereg.instances->next;
- // only safe to free memory if registration is not valid, i.e. deregister fails (which invalidates p)
- LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP",
- request->sd, p->srs.RR_SRV.resrec.name->c, mDNSVal16(p->srs.RR_SRV.resrec.rdata->u.srv.port));
-
- // Clear backpointer *before* calling mDNS_DeregisterService/unlink_and_free_service_instance
- // We don't need unlink_and_free_service_instance to cut its element from the list, because we're already advancing
- // request->u.servicereg.instances as we work our way through the list, implicitly cutting one element at a time
- // We can't clear p->request *after* the calling mDNS_DeregisterService/unlink_and_free_service_instance
- // because by then we might have already freed p
- p->request = NULL;
- if (mDNS_DeregisterService(&mDNSStorage, &p->srs)) unlink_and_free_service_instance(p);
- // Don't touch service_instance *p after this -- it's likely to have been freed already
- }
- if (request->u.servicereg.txtdata)
- { freeL("service_info txtdata", request->u.servicereg.txtdata); request->u.servicereg.txtdata = NULL; }
- if (request->u.servicereg.autoname) UpdateDeviceInfoRecord(&mDNSStorage);
- }
-
mDNSlocal void udsserver_default_reg_domain_changed(const DNameListElem *const d, const mDNSBool add)
{
request_state *request;
LogOperation("%3d: DNSServiceRegister(\"%s\", \"%s\", \"%s\", \"%s\", %u) START",
request->sd, name, request->u.servicereg.type_as_string, domain, host, mDNSVal16(request->u.servicereg.port));
+
+ // We need to unconditionally set request->terminate, because even if we didn't successfully
+ // start any registrations right now, subsequent configuration changes may cause successful
+ // registrations to be added, and we'll need to cancel them before freeing this memory.
+ // We also need to set request->terminate first, before adding additional service instances,
+ // because the uds_validatelists uses the request->terminate function pointer to determine
+ // what kind of request this is, and therefore what kind of list validation is required.
+ request->terminate = regservice_termination_callback;
+
err = register_service_instance(request, &d);
- // Set request->terminate first, before adding additional service instances, because the
- // uds_validatelists uses the request->terminate function pointer to determine what kind
- // of request this is, and therefore what kind of list validation is required.
+#if 0
+ err = AuthorizedDomain(request, &d, AutoRegistrationDomains) ? register_service_instance(request, &d) : mStatus_NoError;
+#endif
if (!err)
{
- request->terminate = regservice_termination_callback;
if (request->u.servicereg.autoname) UpdateDeviceInfoRecord(&mDNSStorage);
- }
- if (!err && !*domain)
- {
- DNameListElem *ptr;
- // note that we don't report errors for non-local, non-explicit domains
- for (ptr = AutoRegistrationDomains; ptr; ptr = ptr->next)
- if (!ptr->uid || SystemUID(request->uid) || request->uid == ptr->uid)
- register_service_instance(request, &ptr->name);
+ if (!*domain)
+ {
+ DNameListElem *ptr;
+ // Note that we don't report errors for non-local, non-explicit domains
+ for (ptr = AutoRegistrationDomains; ptr; ptr = ptr->next)
+ if (!ptr->uid || SystemUID(request->uid) || request->uid == ptr->uid)
+ register_service_instance(request, &ptr->name);
+ }
}
return(err);
if (GenerateNTDResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError) != mStatus_NoError)
{
+ if (SameDomainName(&req->u.browser.regtype, (const domainname*)"\x09_services\x07_dns-sd\x04_udp"))
+ {
+ // Special support to enable the DNSServiceBrowse call made by Bonjour Browser
+ // Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
+ GenerateBonjourBrowserResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError);
+ goto bonjourbrowserhack;
+ }
+
LogMsg("%3d: FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer",
req->sd, answer->name->c, answer->rdata->u.name.c);
return;
}
+bonjourbrowserhack:
+
LogOperation("%3d: DNSServiceBrowse(%##s, %s) RESULT %s %d: %s",
req->sd, question->qname.c, DNSTypeName(question->qtype), AddRecord ? "Add" : "Rmv",
mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID), RRDisplayString(m, answer));
{
b->next = info->u.browser.browsers;
info->u.browser.browsers = b;
+ LogOperation("%3d: DNSServiceBrowse(%##s) START", info->sd, b->q.qname.c);
}
- return err;
+ return err;
}
mDNSlocal void browse_termination_callback(request_state *info)
mStatus err;
ARListElem *ptr = mDNSPlatformMemAllocate(sizeof(*ptr));
- LogOperation("Incrementing %s refcount for %##s",
+ debugf("Incrementing %s refcount for %##s",
(type == mDNS_DomainTypeBrowse ) ? "browse domain " :
(type == mDNS_DomainTypeRegistration ) ? "registration dom" :
(type == mDNS_DomainTypeBrowseAutomatic) ? "automatic browse" : "?", d->c);
ARListElem **ptr = &LocalDomainEnumRecords;
domainname lhs; // left-hand side of PTR, for comparison
- LogOperation("Decrementing %s refcount for %##s",
+ debugf("Decrementing %s refcount for %##s",
(type == mDNS_DomainTypeBrowse ) ? "browse domain " :
(type == mDNS_DomainTypeRegistration ) ? "registration dom" :
(type == mDNS_DomainTypeBrowseAutomatic) ? "automatic browse" : "?", d->c);
{
request_state *req;
service_instance *ptr;
- DNameListElem *RegDomains;
- DNameListElem *BrowseDomains;
+ DNameListElem *RegDomains = NULL;
+ DNameListElem *BrowseDomains = NULL;
DNameListElem *p;
UpdateDeviceInfoRecord(m);
request->u.browser.browsers = NULL;
LogOperation("%3d: DNSServiceBrowse(\"%##s\", \"%s\") START", request->sd, request->u.browser.regtype.c, domain);
+
+ // We need to unconditionally set request->terminate, because even if we didn't successfully
+ // start any browses right now, subsequent configuration changes may cause successful
+ // browses to be added, and we'll need to cancel them before freeing this memory.
+ request->terminate = browse_termination_callback;
+
if (domain[0])
{
if (!MakeDomainNameFromDNSNameString(&d, domain)) return(mStatus_BadParamErr);
err = add_domain_to_browser(request, &d);
+#if 0
+ err = AuthorizedDomain(request, &d, AutoBrowseDomains) ? add_domain_to_browser(request, &d) : mStatus_NoError;
+#endif
}
-
else
{
DNameListElem *sdom;
}
}
- if (!err) request->terminate = browse_termination_callback;
-
return(err);
}
request_state *req = question->QuestionContext;
(void)m; // Unused
- LogOperation("%3d: DNSServiceResolve(%##s, %s) %s %s",
- req->sd, question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
-
- // This code used to do this trick of just keeping a copy of the pointer to
- // the answer record in the cache, but the unicast query code doesn't currently
- // put its answer records in the cache, so for now we can't do this.
+ LogOperation("%3d: DNSServiceResolve(%##s) %s %s", req->sd, question->qname.c, AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
if (!AddRecord)
{
- if (answer->rrtype == kDNSType_SRV && req->u.resolve.srv == answer) req->u.resolve.srv = mDNSNULL;
- if (answer->rrtype == kDNSType_TXT && req->u.resolve.txt == answer) req->u.resolve.txt = mDNSNULL;
+ if (req->u.resolve.srv == answer) req->u.resolve.srv = mDNSNULL;
+ if (req->u.resolve.txt == answer) req->u.resolve.txt = mDNSNULL;
return;
}
rep->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID));
rep->rhdr->error = dnssd_htonl(kDNSServiceErr_NoError);
- data = rep->sdata;
+ data = (char *)&rep->rhdr[1];
// write reply data to message
put_string(fullname, &data);
put_string(target, &data);
- *data++ = req->u.resolve.srv->rdata->u.srv.port.b[0];
- *data++ = req->u.resolve.srv->rdata->u.srv.port.b[1];
+ *data++ = req->u.resolve.srv->rdata->u.srv.port.b[0];
+ *data++ = req->u.resolve.srv->rdata->u.srv.port.b[1];
put_uint16(req->u.resolve.txt->rdlength, &data);
- put_rdata(req->u.resolve.txt->rdlength, req->u.resolve.txt->rdata->u.data, &data);
+ put_rdata (req->u.resolve.txt->rdlength, req->u.resolve.txt->rdata->u.data, &data);
+ LogOperation("%3d: DNSServiceResolve(%s) RESULT %s:%d", req->sd, fullname, target, mDNSVal16(req->u.resolve.srv->rdata->u.srv.port));
append_reply(req, rep);
}
request->u.resolve.qtxt.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
request->u.resolve.qtxt.QuestionCallback = resolve_result_callback;
request->u.resolve.qtxt.QuestionContext = request;
+
request->u.resolve.ReportTime = NonZeroTime(mDNS_TimeNow(&mDNSStorage) + 130 * mDNSPlatformOneSecond);
+#if 0
+ if (!AuthorizedDomain(request, &fqdn, AutoBrowseDomains)) return(mStatus_NoError);
+#endif
+
// ask the questions
LogOperation("%3d: DNSServiceResolve(%##s) START", request->sd, request->u.resolve.qsrv.qname.c);
err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qsrv);
{
err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qtxt);
if (err) mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
+ else request->terminate = resolve_termination_callback;
}
- if (!err) request->terminate = resolve_termination_callback;
-
return(err);
}
DNSServiceErrorType error = kDNSServiceErr_NoError;
(void)m; // Unused
- LogOperation("%3d: %s(%##s, %s) %s %s", req->sd,
- req->hdr.op == query_request ? "DNSServiceQueryRecord" : "DNSServiceGetAddrInfo",
- question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
+#if APPLE_OSX_mDNSResponder
+ if (question == &req->u.queryrecord.q2)
+ {
+ mDNS_StopQuery(&mDNSStorage, question);
+ // If we got a non-negative answer for our "local SOA" test query, start an additional parallel unicast query
+ if (answer->RecordType == kDNSRecordTypePacketNegative ||
+ (question->qtype == req->u.queryrecord.q.qtype && SameDomainName(&question->qname, &req->u.queryrecord.q.qname)))
+ question->QuestionCallback = mDNSNULL;
+ else
+ {
+ *question = req->u.queryrecord.q;
+ question->InterfaceID = mDNSInterface_Unicast;
+ question->ExpectUnique = mDNStrue;
+ mStatus err = mDNS_StartQuery(&mDNSStorage, question);
+ if (!err) LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) unicast", req->sd, question->qname.c, DNSTypeName(question->qtype));
+ else LogMsg("%3d: ERROR: queryrecord_result_callback %##s %s mDNS_StartQuery: %d", req->sd, question->qname.c, DNSTypeName(question->qtype), (int)err);
+ }
+ return;
+ }
+#endif // APPLE_OSX_mDNSResponder
if (answer->RecordType == kDNSRecordTypePacketNegative)
{
+ // When we're doing parallel unicast and multicast queries for dot-local names (for supporting Microsoft
+ // Active Directory sites) we need to ignore negative unicast answers. Otherwise we'll generate negative
+ // answers for just about every single multicast name we ever look up, since the Microsoft Active Directory
+ // server is going to assert that pretty much every single multicast name doesn't exist.
+ if (!answer->InterfaceID && IsLocalDomain(answer->name)) return;
error = kDNSServiceErr_NoSuchRecord;
- ConvertDomainNameToCString(&question->qname, name);
AddRecord = mDNStrue;
}
- else
- ConvertDomainNameToCString(answer->name, name);
+
+ ConvertDomainNameToCString(answer->name, name);
+
+ LogOperation("%3d: %s(%##s, %s) %s %s", req->sd,
+ req->hdr.op == query_request ? "DNSServiceQueryRecord" : "DNSServiceGetAddrInfo",
+ question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
len = sizeof(DNSServiceFlags); // calculate reply data length
len += sizeof(mDNSu32); // interface index
rep->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID));
rep->rhdr->error = dnssd_htonl(error);
- data = rep->sdata;
-
- put_string(name, &data);
+ data = (char *)&rep->rhdr[1];
- if (answer->RecordType == kDNSRecordTypePacketNegative)
- {
- put_uint16(question->qtype, &data);
- put_uint16(question->qclass, &data);
- put_uint16(0, &data);
- put_rdata(0, mDNSNULL, &data);
- put_uint32(0, &data);
- }
- else
- {
- put_uint16(answer->rrtype, &data);
- put_uint16(answer->rrclass, &data);
- put_uint16(answer->rdlength, &data);
- //put_rdata(answer->rdlength, answer->rdata->u.data, &data);
+ put_string(name, &data);
+ put_uint16(answer->rrtype, &data);
+ put_uint16(answer->rrclass, &data);
+ put_uint16(answer->rdlength, &data);
+ // We need to use putRData here instead of the crude put_rdata function, because the crude put_rdata
+ // function just does a blind memory copy without regard to structures that may have holes in them.
+ if (answer->rdlength)
if (!putRData(mDNSNULL, (mDNSu8 *)data, (mDNSu8 *)rep->rhdr + len, answer))
LogMsg("queryrecord_result_callback putRData failed %d", (mDNSu8 *)rep->rhdr + len - (mDNSu8 *)data);
- data += answer->rdlength;
- put_uint32(AddRecord ? answer->rroriginalttl : 0, &data);
- }
+ data += answer->rdlength;
+ put_uint32(AddRecord ? answer->rroriginalttl : 0, &data);
append_reply(req, rep);
}
LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) STOP",
request->sd, request->u.queryrecord.q.qname.c, DNSTypeName(request->u.queryrecord.q.qtype));
mDNS_StopQuery(&mDNSStorage, &request->u.queryrecord.q); // no need to error check
+ if (request->u.queryrecord.q2.QuestionCallback) mDNS_StopQuery(&mDNSStorage, &request->u.queryrecord.q2);
}
mDNSlocal mStatus handle_queryrecord_request(request_state *request)
{
+ DNSQuestion *const q = &request->u.queryrecord.q;
char name[256];
mDNSu16 rrtype, rrclass;
mStatus err;
if (!request->msgptr)
{ LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
- mDNSPlatformMemZero(&request->u.queryrecord.q, sizeof(&request->u.queryrecord.q));
+ mDNSPlatformMemZero(&request->u.queryrecord, sizeof(request->u.queryrecord));
- request->u.queryrecord.q.InterfaceID = InterfaceID;
- request->u.queryrecord.q.Target = zeroAddr;
- if (!MakeDomainNameFromDNSNameString(&request->u.queryrecord.q.qname, name)) return(mStatus_BadParamErr);
- request->u.queryrecord.q.qtype = rrtype;
- request->u.queryrecord.q.qclass = rrclass;
- request->u.queryrecord.q.LongLived = (flags & kDNSServiceFlagsLongLivedQuery ) != 0;
- request->u.queryrecord.q.ExpectUnique = mDNSfalse;
- request->u.queryrecord.q.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
- request->u.queryrecord.q.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
- request->u.queryrecord.q.QuestionCallback = queryrecord_result_callback;
- request->u.queryrecord.q.QuestionContext = request;
+ q->InterfaceID = InterfaceID;
+ q->Target = zeroAddr;
+ if (!MakeDomainNameFromDNSNameString(&q->qname, name)) return(mStatus_BadParamErr);
+#if 0
+ if (!AuthorizedDomain(request, &q->qname, AutoBrowseDomains)) return (mStatus_NoError);
+#endif
+ q->qtype = rrtype;
+ q->qclass = rrclass;
+ q->LongLived = (flags & kDNSServiceFlagsLongLivedQuery ) != 0;
+ q->ExpectUnique = mDNSfalse;
+ q->ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
+ q->ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
+ q->QuestionCallback = queryrecord_result_callback;
+ q->QuestionContext = request;
+
+ LogOperation("%3d: DNSServiceQueryRecord(%##s, %s, %X) START", request->sd, q->qname.c, DNSTypeName(q->qtype), flags);
+ err = mDNS_StartQuery(&mDNSStorage, q);
+ if (err) LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q->qname.c, DNSTypeName(q->qtype), (int)err);
+ else request->terminate = queryrecord_termination_callback;
- LogOperation("%3d: DNSServiceQueryRecord(%##s, %s, %X) START",
- request->sd, request->u.queryrecord.q.qname.c, DNSTypeName(request->u.queryrecord.q.qtype), flags);
- err = mDNS_StartQuery(&mDNSStorage, &request->u.queryrecord.q);
- if (err) LogMsg("ERROR: mDNS_StartQuery: %d", (int)err);
+#if APPLE_OSX_mDNSResponder
+ // Workaround for networks using Microsoft Active Directory using "local" as a private internal top-level domain
+ extern domainname ActiveDirectoryPrimaryDomain;
+ #define VALID_MSAD_SRV_TRANSPORT(T) (SameDomainLabel((T)->c, (const mDNSu8 *)"\x4_tcp") || SameDomainLabel((T)->c, (const mDNSu8 *)"\x4_udp"))
+ #define VALID_MSAD_SRV(Q) ((Q)->qtype == kDNSType_SRV && VALID_MSAD_SRV_TRANSPORT(SecondLabel(&(Q)->qname)))
- if (!err) request->terminate = queryrecord_termination_callback;
+ if (!q->ForceMCast && SameDomainLabel(LastLabel(&q->qname), (const mDNSu8 *)&localdomain))
+ if (q->qtype == kDNSType_A || q->qtype == kDNSType_AAAA || VALID_MSAD_SRV(q))
+ {
+ int labels = CountLabels(&q->qname);
+ DNSQuestion *const q2 = &request->u.queryrecord.q2;
+ *q2 = *q;
+ q2->InterfaceID = mDNSInterface_Unicast;
+ q2->ExpectUnique = mDNStrue;
+
+ // For names of the form "<one-or-more-labels>.bar.local." we always do a second unicast query in parallel.
+ // For names of the form "<one-label>.local." it's less clear whether we should do a unicast query.
+ // If the name being queried is exactly the same as the name in the DHCP "domain" option (e.g. the DHCP
+ // "domain" is my-small-company.local, and the user types "my-small-company.local" into their web browser)
+ // then that's a hint that it's worth doing a unicast query. Otherwise, we first check to see if the
+ // site's DNS server claims there's an SOA record for "local", and if so, that's also a hint that queries
+ // for names in the "local" domain will be safely answered privately before they hit the root name servers.
+ if (labels == 2 && !SameDomainName(&q->qname, &ActiveDirectoryPrimaryDomain))
+ {
+ AssignDomainName(&q2->qname, &localdomain);
+ q2->qtype = kDNSType_SOA;
+ q2->LongLived = mDNSfalse;
+ q2->ForceMCast = mDNSfalse;
+ q2->ReturnIntermed = mDNStrue;
+ }
+ err = mDNS_StartQuery(&mDNSStorage, q2);
+ if (!err) LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) unicast", request->sd, q2->qname.c, DNSTypeName(q2->qtype));
+ else LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q2->qname.c, DNSTypeName(q2->qtype), (int)err);
+ }
+#endif // APPLE_OSX_mDNSResponder
return(err);
}
reply = create_reply(enumeration_reply_op, len, request);
reply->rhdr->flags = dnssd_htonl(flags);
- reply->rhdr->ifi = dnssd_htonl(ifi);
+ reply->rhdr->ifi = dnssd_htonl(ifi);
reply->rhdr->error = dnssd_htonl(err);
- data = reply->sdata;
+ data = (char *)&reply->rhdr[1];
put_string(domain, &data);
return reply;
}
(void)m; // Unused
if (answer->rrtype != kDNSType_PTR) return;
-
+
+#if 0
+ if (!AuthorizedDomain(request, &answer->rdata->u.name, request->u.enumeration.flags ? AutoRegistrationDomains : AutoBrowseDomains)) return;
+#endif
+
// We only return add/remove events for the browse and registration lists
// For the default browse and registration answers, we only give an "ADD" event
if (question == &request->u.enumeration.q_default && !AddRecord) return;
// network, so we just pass kDNSServiceInterfaceIndexAny
reply = format_enumeration_reply(request, domain, flags, kDNSServiceInterfaceIndexAny, kDNSServiceErr_NoError);
if (!reply) { LogMsg("ERROR: enum_result_callback, format_enumeration_reply"); return; }
+
+ LogOperation("%3d: DNSServiceEnumerateDomains(%#2s) RESULT %s: %s", request->sd, question->qname.c, AddRecord ? "Add" : "Rmv", domain);
+
append_reply(request, reply);
}
// allocate context structures
uDNS_RegisterSearchDomains(&mDNSStorage);
+#if 0
+ // mark which kind of enumeration we're doing so we can (de)authorize certain domains
+ request->u.enumeration.flags = reg;
+#endif
+
// enumeration requires multiple questions, so we must link all the context pointers so that
// necessary context can be reached from the callbacks
request->u.enumeration.q_all .QuestionContext = request;
{
err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_default, t_default, NULL, InterfaceID, enum_result_callback, request);
if (err) mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
+ else request->terminate = enum_termination_callback;
}
- if (!err) request->terminate = enum_termination_callback;
return(err);
}
rep->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, n->InterfaceID));
rep->rhdr->error = dnssd_htonl(n->Result);
- data = rep->sdata;
+ data = (char *)&rep->rhdr[1];
*data++ = request->u.pm.NATinfo.ExternalAddress.b[0];
*data++ = request->u.pm.NATinfo.ExternalAddress.b[1];
LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) START", request->sd,
protocol, mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease);
err = mDNS_StartNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
- if (!err) request->terminate = port_mapping_termination_callback;
+ if (err) LogMsg("ERROR: mDNS_StartNATOperation: %d", (int)err);
+ else request->terminate = port_mapping_termination_callback;
return(err);
}
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
+
+ mDNSPlatformMemZero(&request->u.addrinfo, sizeof(request->u.addrinfo));
request->u.addrinfo.interface_id = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
+ request->u.addrinfo.flags = flags;
+ request->u.addrinfo.protocol = get_uint32(&request->msgptr, request->msgend);
+
if (interfaceIndex && !request->u.addrinfo.interface_id) return(mStatus_BadParamErr);
- request->u.addrinfo.flags = flags;
- request->u.addrinfo.protocol = get_uint32(&request->msgptr, request->msgend);
- if (request->u.addrinfo.protocol > (kDNSServiceProtocol_IPv4|kDNSServiceProtocol_IPv6))
- return(mStatus_BadParamErr);
+ if (request->u.addrinfo.protocol > (kDNSServiceProtocol_IPv4|kDNSServiceProtocol_IPv6)) return(mStatus_BadParamErr);
if (get_string(&request->msgptr, request->msgend, hostname, 256) < 0) return(mStatus_BadParamErr);
if (!MakeDomainNameFromDNSNameString(&d, hostname))
{ LogMsg("ERROR: handle_addrinfo_request: bad hostname: %s", hostname); return(mStatus_BadParamErr); }
+#if 0
+ if (!AuthorizedDomain(request, &d, AutoBrowseDomains)) return (mStatus_NoError);
+#endif
+
if (!request->u.addrinfo.protocol)
{
NetworkInterfaceInfo *i;
{
LogMsg("ERROR: mDNS_StartQuery: %d", (int)err);
request->u.addrinfo.q6.QuestionContext = mDNSNULL;
+ if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv4) // If we started a query for IPv4,
+ addrinfo_termination_callback(request); // we need to cancel it
}
}
{ LogMsg("%3d: ERROR: client version 0x%08X daemon version 0x%08X", req->sd, req->hdr.version, VERSION); req->ts = t_error; return; }
// Largest conceivable single request is a DNSServiceRegisterRecord() or DNSServiceAddRecord()
- // with 64kB of rdata. Adding 1005 byte for a maximal domain name, plus a safety margin
+ // with 64kB of rdata. Adding 1009 byte for a maximal domain name, plus a safety margin
// for other overhead, this means any message above 70kB is definitely bogus.
if (req->hdr.datalen > 70000)
{ LogMsg("%3d: ERROR: read_msg - hdr.datalen %lu (%X) > 70000", req->sd, req->hdr.datalen, req->hdr.datalen); req->ts = t_error; return; }
{
mDNSu32 nleft = req->hdr.datalen - req->data_bytes;
int nread;
+#if !defined(_WIN32)
struct iovec vec = { req->msgbuf + req->data_bytes, nleft }; // Tell recvmsg where we want the bytes put
struct msghdr msg;
struct cmsghdr *cmsg;
msg.msg_controllen = sizeof(cbuf);
msg.msg_flags = 0;
nread = recvmsg(req->sd, &msg, 0);
+#else
+ nread = recv(req->sd, (char *)req->msgbuf + req->data_bytes, nleft, 0);
+#endif
if (nread == 0) { req->ts = t_terminated; return; }
if (nread < 0) goto rerror;
req->data_bytes += nread;
if (req->data_bytes > req->hdr.datalen)
{ LogMsg("%3d: ERROR: read_msg - read too many data bytes", req->sd); req->ts = t_error; return; }
+#if !defined(_WIN32)
cmsg = CMSG_FIRSTHDR(&msg);
#if DEBUG_64BIT_SCM_RIGHTS
LogMsg("%3d: Expecting %d %d %d %d", req->sd, sizeof(cbuf), sizeof(cbuf), SOL_SOCKET, SCM_RIGHTS);
LogMsg("%3d: Got %d %d %d %d", req->sd, msg.msg_controllen, cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type);
-#endif DEBUG_64BIT_SCM_RIGHTS
+#endif // DEBUG_64BIT_SCM_RIGHTS
if (msg.msg_controllen == sizeof(cbuf) &&
cmsg->cmsg_len == sizeof(cbuf) &&
cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS)
{
- req->errsd = *(dnssd_sock_t *)CMSG_DATA(cmsg);
+#if APPLE_OSX_mDNSResponder
+ // Strictly speaking BPF_fd belongs solely in the platform support layer, but because
+ // of privilege separation on Mac OS X we need to get BPF_fd from mDNSResponderHelper,
+ // and it's convenient to repurpose the existing fd-passing code here for that task
+ if (req->hdr.op == send_bpf)
+ {
+ dnssd_sock_t x = *(dnssd_sock_t *)CMSG_DATA(cmsg);
+ LogOperation("%3d: Got BPF %d", req->sd, x);
+ mDNSPlatformReceiveBPF_fd(&mDNSStorage, x);
+ }
+ else
+#endif // APPLE_OSX_mDNSResponder
+ req->errsd = *(dnssd_sock_t *)CMSG_DATA(cmsg);
#if DEBUG_64BIT_SCM_RIGHTS
LogMsg("%3d: read req->errsd %d", req->sd, req->errsd);
-#endif DEBUG_64BIT_SCM_RIGHTS
+#endif // DEBUG_64BIT_SCM_RIGHTS
if (req->data_bytes < req->hdr.datalen)
{
LogMsg("%3d: Client sent error socket %d via SCM_RIGHTS with req->data_bytes %d < req->hdr.datalen %d",
return;
}
}
+#endif
}
// If our header and data are both complete, see if we need to make our separate error return socket
dnssd_sockaddr_t cliaddr;
#if defined(USE_TCP_LOOPBACK)
mDNSOpaque16 port;
+ int opt = 1;
port.b[0] = req->msgptr[0];
port.b[1] = req->msgptr[1];
req->msgptr += 2;
{
#if !defined(USE_TCP_LOOPBACK)
struct stat sb;
- LogMsg("%3d: read_msg: Couldn't connect to error return path socket “%s” errno %d %s",
- req->sd, cliaddr.sun_path, dnssd_errno(), dnssd_strerror(dnssd_errno()));
+ LogMsg("%3d: read_msg: Couldn't connect to error return path socket “%s” errno %d (%s)",
+ req->sd, cliaddr.sun_path, dnssd_errno, dnssd_strerror(dnssd_errno));
if (stat(cliaddr.sun_path, &sb) < 0)
- LogMsg("%3d: read_msg: stat failed “%s” errno %d %s", req->sd, cliaddr.sun_path, dnssd_errno(), dnssd_strerror(dnssd_errno()));
+ LogMsg("%3d: read_msg: stat failed “%s” errno %d (%s)", req->sd, cliaddr.sun_path, dnssd_errno, dnssd_strerror(dnssd_errno));
else
LogMsg("%3d: read_msg: file “%s” mode %o (octal) uid %d gid %d", req->sd, cliaddr.sun_path, sb.st_mode, sb.st_uid, sb.st_gid);
#endif
}
got_errfd:
- LogOperation("%3d: Using separate error socket %d", req->sd, req->errsd);
+ LogOperation("%3d: Error socket %d created %08X %08X", req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0]);
#if defined(_WIN32)
if (ioctlsocket(req->errsd, FIONBIO, &opt) != 0)
#else
if (fcntl(req->errsd, F_SETFL, fcntl(req->errsd, F_GETFL, 0) | O_NONBLOCK) != 0)
#endif
{
- LogMsg("%3d: ERROR: could not set control socket to non-blocking mode errno %d %s",
- req->sd, dnssd_errno(), dnssd_strerror(dnssd_errno()));
+ LogMsg("%3d: ERROR: could not set control socket to non-blocking mode errno %d (%s)",
+ req->sd, dnssd_errno, dnssd_strerror(dnssd_errno));
req->ts = t_error;
return;
}
return;
rerror:
- if (dnssd_errno() == dnssd_EWOULDBLOCK || dnssd_errno() == dnssd_EINTR) return;
- LogMsg("%3d: ERROR: read_msg errno %d %s", req->sd, dnssd_errno(), dnssd_strerror(dnssd_errno()));
+ if (dnssd_errno == dnssd_EWOULDBLOCK || dnssd_errno == dnssd_EINTR) return;
+ LogMsg("%3d: ERROR: read_msg errno %d (%s)", req->sd, dnssd_errno, dnssd_strerror(dnssd_errno));
req->ts = t_error;
}
read_msg(req);
if (req->ts == t_morecoming) return;
if (req->ts == t_terminated || req->ts == t_error) { AbortUnlinkAndFree(req); return; }
+ if (req->ts != t_complete) { LogMsg("req->ts %d != t_complete", req->ts); AbortUnlinkAndFree(req); return; }
if (req->hdr.version != VERSION)
{
case getproperty_request: min_size = 2; break;
case port_mapping_request: min_size += sizeof(mDNSu32) + 4 /* udp/tcp */ + 4 /* int/ext port */ + 4 /* ttl */; break;
case addrinfo_request: min_size += sizeof(mDNSu32) + 4 /* v4/v6 */ + 1 /* hostname */; break;
+ case send_bpf: // Same as cancel_request below
case cancel_request: min_size = 0; break;
default: LogMsg("ERROR: validate_message - unsupported req type: %d", req->hdr.op); min_size = -1; break;
}
else switch(req->hdr.op)
{
// These are all operations that have their own first-class request_state object
- case connection_request:
- LogOperation("%3d: DNSServiceCreateConnection START", req->sd);
- req->terminate = connection_termination;
- break;
- case resolve_request: err = handle_resolve_request (req); break;
- case query_request: err = handle_queryrecord_request (req); break;
- case browse_request: err = handle_browse_request (req); break;
- case reg_service_request: err = handle_regservice_request (req); break;
- case enumeration_request: err = handle_enum_request (req); break;
- case reconfirm_record_request: err = handle_reconfirm_request (req); break;
- case setdomain_request: err = handle_setdomain_request (req); break;
- case getproperty_request: handle_getproperty_request (req); break;
- case port_mapping_request: err = handle_port_mapping_request(req); break;
- case addrinfo_request: err = handle_addrinfo_request (req); break;
+ case connection_request: LogOperation("%3d: DNSServiceCreateConnection START", req->sd);
+ req->terminate = connection_termination; break;
+ case resolve_request: err = handle_resolve_request (req); break;
+ case query_request: err = handle_queryrecord_request (req); break;
+ case browse_request: err = handle_browse_request (req); break;
+ case reg_service_request: err = handle_regservice_request (req); break;
+ case enumeration_request: err = handle_enum_request (req); break;
+ case reconfirm_record_request: err = handle_reconfirm_request (req); break;
+ case setdomain_request: err = handle_setdomain_request (req); break;
+ case getproperty_request: handle_getproperty_request (req); break;
+ case port_mapping_request: err = handle_port_mapping_request(req); break;
+ case addrinfo_request: err = handle_addrinfo_request (req); break;
+ case send_bpf: /* Do nothing for send_bpf */ break;
// These are all operations that work with an existing request_state object
- case reg_record_request: err = handle_regrecord_request (req); break;
- case add_record_request: err = handle_add_request (req); break;
- case update_record_request: err = handle_update_request (req); break;
- case remove_record_request: err = handle_removerecord_request(req); break;
- case cancel_request: handle_cancel_request (req); break;
+ case reg_record_request: err = handle_regrecord_request (req); break;
+ case add_record_request: err = handle_add_request (req); break;
+ case update_record_request: err = handle_update_request (req); break;
+ case remove_record_request: err = handle_removerecord_request(req); break;
+ case cancel_request: handle_cancel_request (req); break;
default: LogMsg("%3d: ERROR: Unsupported UDS req: %d", req->sd, req->hdr.op);
}
// There's no return data for a cancel request (DNSServiceRefDeallocate returns no result)
// For a DNSServiceGetProperty call, the handler already generated the response, so no need to do it again here
- if (req->hdr.op != cancel_request && req->hdr.op != getproperty_request)
+ if (req->hdr.op != cancel_request && req->hdr.op != getproperty_request && req->hdr.op != send_bpf)
{
- err = dnssd_htonl(err);
- send_all(req->errsd, (const char *)&err, sizeof(err));
+ const mStatus err_netorder = dnssd_htonl(err);
+ send_all(req->errsd, (const char *)&err_netorder, sizeof(err_netorder));
if (req->errsd != req->sd)
{
- LogOperation("%3d: Closing error socket %d", req->sd, req->errsd);
+ LogOperation("%3d: Error socket %d closed %08X %08X (%d)",
+ req->sd, req->errsd, req->hdr.client_context.u32[1], req->hdr.client_context.u32[0], err);
dnssd_close(req->errsd);
req->errsd = req->sd;
- // Also need to reset the parent's errsd, if this is a subbordinate operation
+ // Also need to reset the parent's errsd, if this is a subordinate operation
if (req->primary) req->primary->errsd = req->primary->sd;
}
}
{
dnssd_sockaddr_t cliaddr;
dnssd_socklen_t len = (dnssd_socklen_t) sizeof(cliaddr);
- dnssd_sock_t sd = accept(listenfd, (struct sockaddr*) &cliaddr, &len);
+ dnssd_sock_t sd = accept(fd, (struct sockaddr*) &cliaddr, &len);
+#if defined(SO_NOSIGPIPE) || defined(_WIN32)
const unsigned long optval = 1;
+#endif
- (void)fd; // Unused
(void)filter; // Unused
(void)info; // Unused
if (!dnssd_SocketValid(sd))
{
- if (dnssd_errno() != dnssd_EWOULDBLOCK) my_perror("ERROR: accept");
+ if (dnssd_errno != dnssd_EWOULDBLOCK) my_perror("ERROR: accept");
return;
}
#ifdef SO_NOSIGPIPE
// Some environments (e.g. OS X) support turning off SIGPIPE for a socket
if (setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) < 0)
- {
- my_perror("ERROR: setsockopt - SO_NOSIGPIPE - aborting client");
- dnssd_close(sd);
- return;
- }
+ LogMsg("%3d: WARNING: setsockopt - SO_NOSIGPIPE %d (%s)", sd, dnssd_errno, dnssd_strerror(dnssd_errno));
#endif
#if defined(_WIN32)
request->sd = sd;
request->errsd = sd;
#if APPLE_OSX_mDNSResponder
- struct xucred x;
- socklen_t xucredlen = sizeof(x);
- if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION) request->uid = x.cr_uid;
- else my_perror("ERROR: getsockopt, LOCAL_PEERCRED");
- debugf("LOCAL_PEERCRED %d %u %u %d", xucredlen, x.cr_version, x.cr_uid, x.cr_ngroups);
-#endif APPLE_OSX_mDNSResponder
+ struct xucred x;
+ socklen_t xucredlen = sizeof(x);
+ if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION) request->uid = x.cr_uid;
+ else my_perror("ERROR: getsockopt, LOCAL_PEERCRED");
+ debugf("LOCAL_PEERCRED %d %u %u %d", xucredlen, x.cr_version, x.cr_uid, x.cr_ngroups);
+#endif // APPLE_OSX_mDNSResponder
LogOperation("%3d: Adding FD for uid %u", request->sd, request->uid);
udsSupportAddFDToEventLoop(sd, request_callback, request);
}
}
-mDNSexport int udsserver_init(dnssd_sock_t skt)
+mDNSlocal mDNSBool uds_socket_setup(dnssd_sock_t skt)
+ {
+#if defined(SO_NP_EXTENSIONS)
+ struct so_np_extensions sonpx;
+ socklen_t optlen = sizeof(struct so_np_extensions);
+ sonpx.npx_flags = SONPX_SETOPTSHUT;
+ sonpx.npx_mask = SONPX_SETOPTSHUT;
+ if (setsockopt(skt, SOL_SOCKET, SO_NP_EXTENSIONS, &sonpx, optlen) < 0)
+ my_perror("WARNING: could not set sockopt - SO_NP_EXTENSIONS");
+#endif
+#if defined(_WIN32)
+ // SEH: do we even need to do this on windows?
+ // This socket will be given to WSAEventSelect which will automatically set it to non-blocking
+ u_long opt = 1;
+ if (ioctlsocket(skt, FIONBIO, &opt) != 0)
+#else
+ if (fcntl(skt, F_SETFL, fcntl(skt, F_GETFL, 0) | O_NONBLOCK) != 0)
+#endif
+ {
+ my_perror("ERROR: could not set listen socket to non-blocking mode");
+ return mDNSfalse;
+ }
+
+ if (listen(skt, LISTENQ) != 0)
+ {
+ my_perror("ERROR: could not listen on listen socket");
+ return mDNSfalse;
+ }
+
+ if (mStatus_NoError != udsSupportAddFDToEventLoop(skt, connect_callback, (void *) NULL))
+ {
+ my_perror("ERROR: could not add listen socket to event loop");
+ return mDNSfalse;
+ }
+ else LogOperation("%3d: Listening for incoming Unix Domain Socket client requests", skt);
+
+ return mDNStrue;
+ }
+
+mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count)
{
dnssd_sockaddr_t laddr;
int ret;
+ mDNSu32 i = 0;
#if defined(_WIN32)
u_long opt = 1;
#endif
- LogOperation("udsserver_init");
+ LogInfo("udsserver_init");
// If a particular platform wants to opt out of having a PID file, define PID_FILE to be ""
if (PID_FILE[0])
}
}
- if (dnssd_SocketValid(skt))
- listenfd = skt;
+ if (skts)
+ {
+ for (i = 0; i < count; i++)
+ if (dnssd_SocketValid(skts[i]) && !uds_socket_setup(skts[i]))
+ goto error;
+ }
else
{
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
#else
{
mode_t mask = umask(0);
- unlink(MDNS_UDS_SERVERPATH); //OK if this fails
+ unlink(MDNS_UDS_SERVERPATH); // OK if this fails
laddr.sun_family = AF_LOCAL;
#ifndef NOT_HAVE_SA_LEN
// According to Stevens (section 3.2), there is no portable way to
}
}
#endif
+
+ if (!uds_socket_setup(listenfd)) goto error;
}
-#if defined(_WIN32)
- // SEH: do we even need to do this on windows?
- // This socket will be given to WSAEventSelect which will automatically set it to non-blocking
- if (ioctlsocket(listenfd, FIONBIO, &opt) != 0)
-#else
- if (fcntl(listenfd, F_SETFL, fcntl(listenfd, F_GETFL, 0) | O_NONBLOCK) != 0)
-#endif
- {
- my_perror("ERROR: could not set listen socket to non-blocking mode");
- goto error;
- }
-
- if (listen(listenfd, LISTENQ) != 0)
- {
- my_perror("ERROR: could not listen on listen socket");
- goto error;
- }
-
- if (mStatus_NoError != udsSupportAddFDToEventLoop(listenfd, connect_callback, (void *) NULL))
- {
- my_perror("ERROR: could not add listen socket to event loop");
- goto error;
- }
- else LogOperation("%3d: Listening for incoming Unix Domain Socket client requests", listenfd);
-
#if !defined(PLATFORM_NO_RLIMIT)
{
// Set maximum number of open file descriptors
return -1;
}
-mDNSexport int udsserver_exit(dnssd_sock_t skt)
+mDNSexport int udsserver_exit(void)
{
// If the launching environment created no listening socket,
// that means we created it ourselves, so we should clean it up on exit
- if (!dnssd_SocketValid(skt))
+ if (dnssd_SocketValid(listenfd))
{
dnssd_close(listenfd);
#if !defined(USE_TCP_LOOPBACK)
{
service_instance *ptr;
for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
- LogMsgNoIdent("%3d: DNSServiceRegister %##s %u", req->sd, ptr->srs.RR_SRV.resrec.name->c, SRS_PORT(&ptr->srs));
+ LogMsgNoIdent("%3d: DNSServiceRegister %##s %u/%u",
+ req->sd, ptr->srs.RR_SRV.resrec.name->c, mDNSVal16(req->u.servicereg.port), SRS_PORT(&ptr->srs));
}
else if (req->terminate == browse_termination_callback)
{
LogMsgNoIdent("%3d: Unrecognized operation %p", req->sd, req->terminate);
}
-mDNSexport void udsserver_info(mDNS *const m)
+mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *ResourceRecords, int *proxy)
{
- mDNSs32 now = mDNS_TimeNow(m);
- mDNSu32 CacheUsed = 0, CacheActive = 0;
- mDNSu32 slot;
- CacheGroup *cg;
- CacheRecord *cr;
+ if (!ResourceRecords) LogMsgNoIdent("<None>");
+ else
+ {
+ const AuthRecord *ar;
+ mDNSEthAddr owner = zeroEthAddr;
+ LogMsgNoIdent(" Int Next Expire State");
+ for (ar = ResourceRecords; ar; ar=ar->next)
+ {
+ NetworkInterfaceInfo *info = (NetworkInterfaceInfo *)ar->resrec.InterfaceID;
+ if (ar->WakeUp.HMAC.l[0]) (*proxy)++;
+ if (!mDNSSameEthAddress(&owner, &ar->WakeUp.HMAC))
+ {
+ owner = ar->WakeUp.HMAC;
+ if (ar->WakeUp.password.l[0])
+ LogMsgNoIdent("Proxying for H-MAC %.6a I-MAC %.6a Password %.6a seq %d", &ar->WakeUp.HMAC, &ar->WakeUp.IMAC, &ar->WakeUp.password, ar->WakeUp.seq);
+ else if (!mDNSSameEthAddress(&ar->WakeUp.HMAC, &ar->WakeUp.IMAC))
+ LogMsgNoIdent("Proxying for H-MAC %.6a I-MAC %.6a seq %d", &ar->WakeUp.HMAC, &ar->WakeUp.IMAC, ar->WakeUp.seq);
+ else
+ LogMsgNoIdent("Proxying for %.6a seq %d", &ar->WakeUp.HMAC, ar->WakeUp.seq);
+ }
+ if (AuthRecord_uDNS(ar))
+ LogMsgNoIdent("%7d %7d %7d %7d %s",
+ ar->ThisAPInterval / mDNSPlatformOneSecond,
+ (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
+ ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
+ ar->state, ARDisplayString(m, ar));
+ else if (ar->resrec.InterfaceID != mDNSInterface_LocalOnly)
+ LogMsgNoIdent("%7d %7d %7d %7s %s",
+ ar->ThisAPInterval / mDNSPlatformOneSecond,
+ ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
+ ar->TimeExpire ? (ar->TimeExpire - now) / mDNSPlatformOneSecond : 0,
+ info ? info->ifname : "ALL",
+ ARDisplayString(m, ar));
+ else
+ LogMsgNoIdent(" LO %s", ARDisplayString(m, ar));
+ usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
+ }
+ }
+ }
- LogMsgNoIdent("Timenow 0x%08lX (%ld)", (mDNSu32)now, now);
+mDNSexport void udsserver_info(mDNS *const m)
+ {
+ const mDNSs32 now = mDNS_TimeNow(m);
+ mDNSu32 CacheUsed = 0, CacheActive = 0, slot;
+ int ProxyA = 0, ProxyD = 0;
+ const CacheGroup *cg;
+ const CacheRecord *cr;
+ const DNSQuestion *q;
+ const DNameListElem *d;
+
+ LogMsgNoIdent("Timenow 0x%08lX (%d)", (mDNSu32)now, now);
LogMsgNoIdent("------------ Cache -------------");
- LogMsgNoIdent("Slt Q TTL if U Type rdlen");
+ LogMsgNoIdent("Slt Q TTL if U Type rdlen");
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
{
NetworkInterfaceInfo *info = (NetworkInterfaceInfo *)cr->resrec.InterfaceID;
CacheUsed++;
if (cr->CRActiveQuestion) CacheActive++;
- LogMsgNoIdent("%3d %s%8ld %-6s%s %-6s%s",
+ LogMsgNoIdent("%3d %s%8ld %-7s%s %-6s%s",
slot,
cr->CRActiveQuestion ? "*" : " ",
remain,
(cr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? " " : "+",
DNSTypeName(cr->resrec.rrtype),
CRDisplayString(m, cr));
- usleep(1000); // Limit rate a little so we don't flood syslog too fast
+ usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
}
}
LogMsgNoIdent("Cache currently contains %lu entities; %lu referenced by active questions", CacheUsed, CacheActive);
LogMsgNoIdent("--------- Auth Records ---------");
- if (!m->ResourceRecords) LogMsgNoIdent("<None>");
- else
- {
- AuthRecord *ar;
- LogMsgNoIdent(" Int Next Expire State");
- for (ar = m->ResourceRecords; ar; ar=ar->next)
- if (AuthRecord_uDNS(ar))
- LogMsgNoIdent("%7d %7d %7d %7d %s",
- ar->ThisAPInterval / mDNSPlatformOneSecond,
- (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
- ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
- ar->state, ARDisplayString(m, ar));
- else if (ar->resrec.InterfaceID != mDNSInterface_LocalOnly)
- LogMsgNoIdent("%7d %7d M %s",
- ar->ThisAPInterval / mDNSPlatformOneSecond,
- ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
- ARDisplayString(m, ar));
- else
- LogMsgNoIdent(" LO %s", ARDisplayString(m, ar));
- }
+ LogAuthRecords(m, now, m->ResourceRecords, &ProxyA);
+
+ LogMsgNoIdent("------ Duplicate Records -------");
+ LogAuthRecords(m, now, m->DuplicateRecords, &ProxyD);
LogMsgNoIdent("----- ServiceRegistrations -----");
if (!m->ServiceRegistrations) LogMsgNoIdent("<None>");
if (!m->Questions) LogMsgNoIdent("<None>");
else
{
- DNSQuestion *q;
CacheUsed = 0;
CacheActive = 0;
- LogMsgNoIdent(" Int Next if T NumAns Type Name");
+ LogMsgNoIdent(" Int Next if T NumAns Type Name");
for (q = m->Questions; q; q=q->next)
{
mDNSs32 i = q->ThisQInterval / mDNSPlatformOneSecond;
NetworkInterfaceInfo *info = (NetworkInterfaceInfo *)q->InterfaceID;
CacheUsed++;
if (q->ThisQInterval) CacheActive++;
- LogMsgNoIdent("%6d%6d %-6s%s%s %5d %-6s%##s%s",
+ LogMsgNoIdent("%6d%6d %-7s%s%s %5d %-6s%##s%s",
i, n,
info ? info->ifname : mDNSOpaque16IsZero(q->TargetQID) ? "" : "-U-",
- mDNSOpaque16IsZero(q->TargetQID) ? " " : q->LongLived ? "L" : "O", // mDNS, long-lived, or one-shot query?
+ mDNSOpaque16IsZero(q->TargetQID) ? (q->LongLived ? "l" : " ") : (q->LongLived ? "L" : "O"),
q->AuthInfo ? "P" : " ",
q->CurrentAnswers,
DNSTypeName(q->qtype), q->qname.c, q->DuplicateOf ? " (dup)" : "");
- usleep(1000); // Limit rate a little so we don't flood syslog too fast
+ usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
}
LogMsgNoIdent("%lu question%s; %lu active", CacheUsed, CacheUsed > 1 ? "s" : "", CacheActive);
}
+ LogMsgNoIdent("----- Local-Only Questions -----");
+ if (!m->LocalOnlyQuestions) LogMsgNoIdent("<None>");
+ else for (q = m->LocalOnlyQuestions; q; q=q->next)
+ LogMsgNoIdent(" %5d %-6s%##s%s",
+ q->CurrentAnswers, DNSTypeName(q->qtype), q->qname.c, q->DuplicateOf ? " (dup)" : "");
+
LogMsgNoIdent("---- Active Client Requests ----");
if (!all_requests) LogMsgNoIdent("<None>");
else
request_state *req;
for (req = all_requests; req; req=req->next)
LogClientInfo(m, req);
+ usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
}
LogMsgNoIdent("-------- NAT Traversals --------");
for (nat = m->NATTraversals; nat; nat=nat->next)
{
if (nat->Protocol)
- LogMsgNoIdent("%p %s Int %5d Ext %5d Err %d Retry %d Interval %d Expire %d",
+ LogMsgNoIdent("%p %s Int %5d Ext %5d Err %d Retry %5d Interval %5d Expire %5d",
nat, nat->Protocol == NATOp_MapTCP ? "TCP" : "UDP",
mDNSVal16(nat->IntPort), mDNSVal16(nat->ExternalPort), nat->Result,
nat->retryPortMap ? (nat->retryPortMap - now) / mDNSPlatformOneSecond : 0,
nat->retryInterval / mDNSPlatformOneSecond,
nat->ExpiryTime ? (nat->ExpiryTime - now) / mDNSPlatformOneSecond : 0);
else
- LogMsgNoIdent("%p Address Request Retry %d Interval %d", nat,
+ LogMsgNoIdent("%p Address Request Retry %5d Interval %5d", nat,
(m->retryGetAddr - now) / mDNSPlatformOneSecond,
m->retryIntervalGetAddr / mDNSPlatformOneSecond);
+ usleep((m->KnownBugs & mDNS_KnownBug_LossySyslog) ? 3333 : 1000);
}
}
}
#if APPLE_OSX_mDNSResponder
- LogMsgNoIdent("--------- TunnelClients ---------");
+ LogMsgNoIdent("--------- TunnelClients --------");
if (!m->TunnelClients) LogMsgNoIdent("<None>");
else
{
LogMsgNoIdent("%##s local %.16a %.4a remote %.16a %.4a %5d interval %d",
c->dstname.c, &c->loc_inner, &c->loc_outer, &c->rmt_inner, &c->rmt_outer, mDNSVal16(c->rmt_outer_port), c->q.ThisQInterval);
}
- #endif
+ #endif // APPLE_OSX_mDNSResponder
+
+ LogMsgNoIdent("---------- Misc State ----------");
+
+ LogMsgNoIdent("PrimaryMAC: %.6a", &m->PrimaryMAC);
+
+ LogMsgNoIdent("m->SleepState %d (%s) seq %d",
+ m->SleepState,
+ m->SleepState == SleepState_Awake ? "Awake" :
+ m->SleepState == SleepState_Transferring ? "Transferring" :
+ m->SleepState == SleepState_Sleeping ? "Sleeping" : "?",
+ m->SleepSeqNum);
+
+ if (!m->SPSSocket) LogMsgNoIdent("Not offering Sleep Proxy Service");
+ else LogMsgNoIdent("Offering Sleep Proxy Service: %#s", m->SPSRecords.RR_SRV.resrec.name->c);
+
+ if (m->ProxyRecords == ProxyA + ProxyD) LogMsgNoIdent("ProxyRecords: %d + %d = %d", ProxyA, ProxyD, ProxyA + ProxyD);
+ else LogMsgNoIdent("ProxyRecords: MISMATCH %d + %d = %d ≠ %d", ProxyA, ProxyD, ProxyA + ProxyD, m->ProxyRecords);
+
+ LogMsgNoIdent("------ Auto Browse Domains -----");
+ if (!AutoBrowseDomains) LogMsgNoIdent("<None>");
+ else for (d=AutoBrowseDomains; d; d=d->next) LogMsgNoIdent("%##s", d->name.c);
+
+ LogMsgNoIdent("--- Auto Registration Domains --");
+ if (!AutoRegistrationDomains) LogMsgNoIdent("<None>");
+ else for (d=AutoRegistrationDomains; d; d=d->next) LogMsgNoIdent("%##s", d->name.c);
}
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
mDNSexport void uds_validatelists(void)
{
- request_state *req;
+ const request_state *req, *p;
for (req = all_requests; req; req=req->next)
{
if (req->next == (request_state *)~0 || (req->sd < 0 && req->sd != -2))
LogMemCorruption("UDS request list: %p is garbage (%d)", req, req->sd);
+ if (req->primary == req)
+ LogMemCorruption("UDS request list: req->primary should not point to self %p/%d", req, req->sd);
+
+ if (req->primary && req->replies)
+ LogMemCorruption("UDS request list: Subordinate request %p/%d/%p should not have replies (%p)",
+ req, req->sd, req->primary && req->replies);
+
+ p = req->primary;
+ if ((long)p & 3)
+ LogMemCorruption("UDS request list: req %p primary %p is misaligned (%d)", req, p, req->sd);
+ else if (p && (p->next == (request_state *)~0 || (p->sd < 0 && p->sd != -2)))
+ LogMemCorruption("UDS request list: req %p primary %p is garbage (%d)", req, p, p->sd);
+
reply_state *rep;
for (rep = req->replies; rep; rep=rep->next)
if (rep->next == (reply_state *)~0)
if (req->terminate == connection_termination)
{
- registered_record_entry *p;
- for (p = req->u.reg_recs; p; p=p->next)
- if (p->next == (registered_record_entry *)~0)
- LogMemCorruption("UDS req->u.reg_recs: %p is garbage", p);
+ registered_record_entry *r;
+ for (r = req->u.reg_recs; r; r=r->next)
+ if (r->next == (registered_record_entry *)~0)
+ LogMemCorruption("UDS req->u.reg_recs: %p is garbage", r);
}
else if (req->terminate == regservice_termination_callback)
{
- service_instance *p;
- for (p = req->u.servicereg.instances; p; p=p->next)
- if (p->next == (service_instance *)~0)
- LogMemCorruption("UDS req->u.servicereg.instances: %p is garbage", p);
+ service_instance *s;
+ for (s = req->u.servicereg.instances; s; s=s->next)
+ if (s->next == (service_instance *)~0)
+ LogMemCorruption("UDS req->u.servicereg.instances: %p is garbage", s);
}
else if (req->terminate == browse_termination_callback)
{
- browser_t *p;
- for (p = req->u.browser.browsers; p; p=p->next)
- if (p->next == (browser_t *)~0)
- LogMemCorruption("UDS req->u.browser.browsers: %p is garbage", p);
+ browser_t *b;
+ for (b = req->u.browser.browsers; b; b=b->next)
+ if (b->next == (browser_t *)~0)
+ LogMemCorruption("UDS req->u.browser.browsers: %p is garbage", b);
}
}
if (d->next == (DNameListElem *)~0 || d->name.c[0] > 63)
LogMemCorruption("AutoRegistrationDomains: %p is garbage (%d)", d, d->name.c[0]);
}
-#endif
+#endif // APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
-mDNSlocal int send_msg(reply_state *rep)
+mDNSlocal int send_msg(request_state *const req)
{
+ reply_state *const rep = req->replies; // Send the first waiting reply
ssize_t nwriten;
- if (!rep->msgbuf) { LogMsg("ERROR: send_msg called with NULL message buffer"); return(rep->ts = t_error); }
- if (rep->request->no_reply) { freeL("reply_state msgbuf (no_reply)", rep->msgbuf); return(rep->ts = t_complete); }
+ if (req->no_reply) return(t_complete);
ConvertHeaderBytes(rep->mhdr);
- nwriten = send(rep->sd, rep->msgbuf + rep->nwriten, rep->len - rep->nwriten, 0);
+ nwriten = send(req->sd, (char *)&rep->mhdr + rep->nwriten, rep->totallen - rep->nwriten, 0);
ConvertHeaderBytes(rep->mhdr);
if (nwriten < 0)
{
- if (dnssd_errno() == dnssd_EINTR || dnssd_errno() == dnssd_EWOULDBLOCK) nwriten = 0;
+ if (dnssd_errno == dnssd_EINTR || dnssd_errno == dnssd_EWOULDBLOCK) nwriten = 0;
else
{
#if !defined(PLATFORM_NO_EPIPE)
- if (dnssd_errno() == EPIPE)
- return(rep->request->ts = rep->ts = t_terminated);
+ if (dnssd_errno == EPIPE)
+ return(req->ts = t_terminated);
else
#endif
{
- LogMsg("send_msg ERROR: failed to write %d bytes to fd %d errno %d %s",
- rep->len - rep->nwriten, rep->sd, dnssd_errno(), dnssd_strerror(dnssd_errno()));
- return(rep->ts = t_error);
+ LogMsg("send_msg ERROR: failed to write %d of %d bytes to fd %d errno %d (%s)",
+ rep->totallen - rep->nwriten, rep->totallen, req->sd, dnssd_errno, dnssd_strerror(dnssd_errno));
+ return(t_error);
}
}
}
rep->nwriten += nwriten;
- if (rep->nwriten == rep->len) { freeL("reply_state msgbuf (t_complete)", rep->msgbuf); rep->ts = t_complete; }
- return rep->ts;
+ return (rep->nwriten == rep->totallen) ? t_complete : t_morecoming;
}
mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
while (*req)
{
- if ((*req)->terminate == resolve_termination_callback)
- if ((*req)->u.resolve.ReportTime && now - (*req)->u.resolve.ReportTime >= 0)
+ request_state *const r = *req;
+
+ if (r->terminate == resolve_termination_callback)
+ if (r->u.resolve.ReportTime && now - r->u.resolve.ReportTime >= 0)
{
- (*req)->u.resolve.ReportTime = 0;
+ r->u.resolve.ReportTime = 0;
LogMsgNoIdent("Client application bug: DNSServiceResolve(%##s) active for over two minutes. "
- "This places considerable burden on the network.", (*req)->u.resolve.qsrv.qname.c);
+ "This places considerable burden on the network.", r->u.resolve.qsrv.qname.c);
}
- while ((*req)->replies) // Send queued replies
+ // Note: Only primary req's have reply lists, not subordinate req's.
+ while (r->replies) // Send queued replies
{
transfer_state result;
- if ((*req)->replies->next) (*req)->replies->rhdr->flags |= dnssd_htonl(kDNSServiceFlagsMoreComing);
- result = send_msg((*req)->replies); // Returns t_morecoming if buffer full because client is not reading
+ if (r->replies->next) r->replies->rhdr->flags |= dnssd_htonl(kDNSServiceFlagsMoreComing);
+ result = send_msg(r); // Returns t_morecoming if buffer full because client is not reading
if (result == t_complete)
{
- reply_state *fptr = (*req)->replies;
- (*req)->replies = (*req)->replies->next;
+ reply_state *fptr = r->replies;
+ r->replies = r->replies->next;
freeL("reply_state/udsserver_idle", fptr);
- (*req)->time_blocked = 0; // reset failure counter after successful send
+ r->time_blocked = 0; // reset failure counter after successful send
continue;
}
- else if (result == t_terminated || result == t_error) abort_request(*req);
+ else if (result == t_terminated || result == t_error)
+ {
+ LogMsg("%3d: Could not write data to client because of error - aborting connection", r->sd);
+ LogClientInfo(&mDNSStorage, r);
+ abort_request(r);
+ }
break;
}
- if ((*req)->replies) // If we failed to send everything, check our time_blocked timer
+ if (r->replies) // If we failed to send everything, check our time_blocked timer
{
- if (!(*req)->time_blocked) (*req)->time_blocked = NonZeroTime(now);
- if (now - (*req)->time_blocked >= 60 * mDNSPlatformOneSecond)
+ if (!r->time_blocked) r->time_blocked = NonZeroTime(now);
+ if (now - r->time_blocked >= 60 * mDNSPlatformOneSecond)
{
- LogMsg("Could not write data to client %d after %ld seconds - aborting connection",
- (*req)->sd, (now - (*req)->time_blocked) / mDNSPlatformOneSecond);
- LogClientInfo(&mDNSStorage, *req);
- abort_request(*req);
+ 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);
}
else if (nextevent - now > mDNSPlatformOneSecond) nextevent = now + mDNSPlatformOneSecond;
}
- if (!dnssd_SocketValid((*req)->sd)) // If this request is finished, unlink it from the list and free the memory
+ if (!dnssd_SocketValid(r->sd)) // If this request is finished, unlink it from the list and free the memory
{
// Since we're already doing a list traversal, we unlink the request directly instead of using AbortUnlinkAndFree()
- request_state *tmp = *req;
- *req = tmp->next;
- freeL("request_state/udsserver_idle", tmp);
+ *req = r->next;
+ freeL("request_state/udsserver_idle", r);
}
else
- req = &(*req)->next;
+ req = &r->next;
}
return nextevent;
}
// 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) <= 1800) ? 1 : -1];
- char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <= 30) ? 1 : -1];
- char sizecheck_service_instance [(sizeof(service_instance) <= 6000) ? 1 : -1];
- char sizecheck_browser_t [(sizeof(browser_t) <= 1000) ? 1 : -1];
- char sizecheck_reply_hdr [(sizeof(reply_hdr) <= 20) ? 1 : -1];
- char sizecheck_reply_state [(sizeof(reply_state) <= 40) ? 1 : -1];
+ char sizecheck_request_state [(sizeof(request_state) <= 1760) ? 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];
+ char sizecheck_reply_hdr [(sizeof(reply_hdr) <= 12) ? 1 : -1];
+ char sizecheck_reply_state [(sizeof(reply_state) <= 64) ? 1 : -1];
};
Change History (most recent first):
$Log: uds_daemon.h,v $
+Revision 1.27 2009/04/30 20:07:51 mcguire
+<rdar://problem/6822674> Support multiple UDSs from launchd
+
+Revision 1.26 2008/10/02 22:26:21 cheshire
+Moved declaration of BPF_fd from uds_daemon.c to mDNSMacOSX.c, where it really belongs
+
+Revision 1.25 2008/09/27 01:08:25 cheshire
+Added external declaration of "dnssd_sock_t BPF_fd"
+
Revision 1.24 2007/09/19 20:25:17 cheshire
Deleted outdated comment
#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
-extern int udsserver_init(dnssd_sock_t skt);
+extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
extern void udsserver_info(mDNS *const m); // print out info about current state
extern void udsserver_handle_configchange(mDNS *const m);
-extern int udsserver_exit(dnssd_sock_t skt); // should be called prior to app exit
+extern int udsserver_exit(void); // should be called prior to app exit
/* Routines that uds_daemon expects to link against: */
Change History (most recent first):
$Log: mDNSVxWorks.c,v $
+Revision 1.35 2009/01/13 05:31:35 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.34 2008/10/03 18:25:18 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
Revision 1.33 2007/03/22 18:31:48 cheshire
Put dst parameter first in mDNSPlatformStrCopy/mDNSPlatformMemCopy, like conventional Posix strcpy/memcpy
// Do minimal initialization to get the task started and so we can cleanup safely if an error occurs.
- memset( &gMDNSPlatformSupport, 0, sizeof( gMDNSPlatformSupport ) );
+ mDNSPlatformMemZero( &gMDNSPlatformSupport, sizeof( gMDNSPlatformSupport ) );
if( !inMDNS->p ) inMDNS->p = &gMDNSPlatformSupport;
inMDNS->p->unicastSS.info = NULL;
inMDNS->p->unicastSS.sockV4 = kInvalidSocketRef;
struct in6_ifreq ifr6;
sa6 = (struct sockaddr_in6 *) ifa->ifa_addr;
- memset( &ifr6, 0, sizeof( ifr6 ) );
+ mDNSPlatformMemZero( &ifr6, sizeof( ifr6 ) );
strcpy( ifr6.ifr_name, ifa->ifa_name );
ifr6.ifr_addr = *sa6;
if( ioctl( infoSock, SIOCGIFAFLAG_IN6, (int) &ifr6 ) != -1 )
// Start listening for packets.
- memset( &sa4, 0, sizeof( sa4 ) );
+ mDNSPlatformMemZero( &sa4, sizeof( sa4 ) );
sa4.sin_len = sizeof( sa4 );
sa4.sin_family = AF_INET;
sa4.sin_port = port.NotAnInteger;
// Start listening for packets.
- memset( &sa6, 0, sizeof( sa6 ) );
+ mDNSPlatformMemZero( &sa6, sizeof( sa6 ) );
sa6.sin6_len = sizeof( sa6 );
sa6.sin6_family = AF_INET6;
sa6.sin6_port = port.NotAnInteger;
SetupActiveInterfaces( inMDNS, utc );
mDNSPlatformUnlock( inMDNS );
- if( inMDNS->MainCallback ) inMDNS->MainCallback( inMDNS, mStatus_ConfigChanged );
+ mDNS_ConfigChanged(inMDNS);
break;
case kMDNSPipeCommandCodeQuit: // Quit: just set a flag so the task exits cleanly.
Change History (most recent first):
$Log: mDNSVxWorksIPv4Only.c,v $
+Revision 1.34 2009/01/13 05:31:35 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.33 2008/11/04 19:51:13 cheshire
+Updated comment about MAX_ESCAPED_DOMAIN_NAME size (should be 1009, not 1005)
+
+Revision 1.32 2008/10/03 18:25:18 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
Revision 1.31 2007/03/22 18:31:49 cheshire
Put dst parameter first in mDNSPlatformStrCopy/mDNSPlatformMemCopy, like conventional Posix strcpy/memcpy
Revision 1.10 2003/11/14 21:27:09 cheshire
<rdar://problem/3484766>: Security: Crashing bug in mDNSResponder
-Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1005) instead of 256-byte buffers.
+Fix code that should use buffer size MAX_ESCAPED_DOMAIN_NAME (1009) instead of 256-byte buffers.
Revision 1.9 2003/11/14 20:59:09 cheshire
Clients can't use AssignDomainName macro because mDNSPlatformMemCopy is defined in mDNSPlatformFunctions.h.
// Initialize variables.
- memset( &gMDNSPlatformSupport, 0, sizeof( gMDNSPlatformSupport ) );
+ mDNSPlatformMemZero( &gMDNSPlatformSupport, sizeof( gMDNSPlatformSupport ) );
inMDNS->p = &gMDNSPlatformSupport;
inMDNS->p->commandPipe = ERROR;
inMDNS->p->task = ERROR;
item = (MDNSInterfaceItem *) inInterfaceID;
check( item->sendingSocketRef != kInvalidSocketRef );
- memset( &addr, 0, sizeof( addr ) );
+ mDNSPlatformMemZero( &addr, sizeof( addr ) );
addr.sin_family = AF_INET;
addr.sin_port = inDstPort.NotAnInteger;
addr.sin_addr.s_addr = inDstIP->ip.v4.NotAnInteger;
// Bind to the multicast DNS address and port 5353.
- memset( &addr, 0, sizeof( addr ) );
+ mDNSPlatformMemZero( &addr, sizeof( addr ) );
addr.sin_family = AF_INET;
addr.sin_port = inPort.NotAnInteger;
addr.sin_addr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
// Bind to the interface address and multicast DNS port.
ip.NotAnInteger = ipv4->sin_addr.s_addr;
- memset( &addr, 0, sizeof( addr ) );
+ mDNSPlatformMemZero( &addr, sizeof( addr ) );
addr.sin_family = AF_INET;
addr.sin_port = MulticastDNSPort.NotAnInteger;
addr.sin_addr.s_addr = ip.NotAnInteger;
// Inform clients of the change.
- if( inMDNS->MainCallback )
- {
- inMDNS->MainCallback( inMDNS, mStatus_ConfigChanged );
- }
+ mDNS_ConfigChanged(m);
// Force mDNS to update.
- mDNSCoreMachineSleep( inMDNS, mDNSfalse );
+ mDNSCoreMachineSleep( inMDNS, mDNSfalse ); // What is this for? Mac OS X does not do this
// Bump the config ID so the main processing loop detects the configuration change.
Change History (most recent first):
$Log: ConfigPropertySheet.cpp,v $
+Revision 1.7 2009/07/01 19:20:37 herscher
+<rdar://problem/6713286> UI changes for configuring sleep proxy settings.
+
+Revision 1.6 2009/03/30 19:57:45 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.5 2006/08/14 23:25:28 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
AddPage(&m_firstPage);
AddPage(&m_secondPage);
AddPage(&m_thirdPage);
+ AddPage(&m_fourthPage );
InitializeCriticalSection( &m_lock );
}
// CConfigPropertySheet::OnDataReady
//---------------------------------------------------------------------------------------------------------------------------
-LONG
+LRESULT
CConfigPropertySheet::OnDataReady(WPARAM inWParam, LPARAM inLParam)
{
if (WSAGETSELECTERROR(inLParam) && !(HIWORD(inLParam)))
// CConfigPropertySheet::OnRegistryChanged
//---------------------------------------------------------------------------------------------------------------------------
-afx_msg LONG
+afx_msg LRESULT
CConfigPropertySheet::OnRegistryChanged( WPARAM inWParam, LPARAM inLParam )
{
DEBUG_UNUSED( inWParam );
Change History (most recent first):
$Log: ConfigPropertySheet.h,v $
+Revision 1.7 2009/07/01 19:20:37 herscher
+<rdar://problem/6713286> UI changes for configuring sleep proxy settings.
+
+Revision 1.6 2009/03/30 19:58:47 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.5 2006/08/14 23:25:28 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#include "FirstPage.h"
#include "SecondPage.h"
#include "ThirdPage.h"
+#include "FourthPage.h"
#include <RegNames.h>
#include <dns_sd.h>
CFirstPage m_firstPage;
CSecondPage m_secondPage;
CThirdPage m_thirdPage;
+ CFourthPage m_fourthPage;
//{{AFX_VIRTUAL(CConfigPropertySheet)
//}}AFX_VIRTUAL
afx_msg BOOL OnInitDialog();
afx_msg BOOL OnCommand( WPARAM wParam, LPARAM lParam );
-
- afx_msg LONG OnDataReady( WPARAM inWParam, LPARAM inLParam );
-
- afx_msg LONG OnRegistryChanged( WPARAM inWParam, LPARAM inLParam );
-
+ afx_msg LRESULT OnDataReady( WPARAM inWParam, LPARAM inLParam );
+ afx_msg LRESULT OnRegistryChanged( WPARAM inWParam, LPARAM inLParam );
void OnEndDialog();
private:
Change History (most recent first):
$Log: ControlPanel.cpp,v $
+Revision 1.5 2009/03/30 20:00:19 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.4 2007/04/27 20:42:11 herscher
<rdar://problem/5078828> mDNS: Bonjour Control Panel for Windows doesn't work on Vista
//---------------------------------------------------------------------------------------------------------------------------
LRESULT
-CCPApp::OnCplMsg(HWND hWndCPl, UINT uMsg, LONG lParam1, LONG lParam2)
+CCPApp::OnCplMsg(HWND hWndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
{
LRESULT lResult = 1;
PUSHBUTTON "Remove",IDC_REMOVE_BROWSE_DOMAIN,205,100,50,14
END
+IDR_APPLET_PAGE4 DIALOGEX 0, 0, 262, 140
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Power Management"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ CONTROL "Allow Bonjour to wake this machine on network access.",IDC_POWER_MANAGEMENT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,19,199,8
+ LTEXT "Warning: Allowing Bonjour to bring the computer out of standby may cause this computer to periodically wakeup to refresh its network state.",IDC_STATIC,13,41,227,20
+END
+
IDR_ADD_BROWSE_DOMAIN DIALOGEX 0, 0, 230, 95
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="ControlPanel"\r
- SccProjectName=""\r
- SccLocalPath=""\r
- Keyword="MFCProj">\r
+ ProjectGUID="{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}"\r
+ Keyword="MFCProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName=".\Debug/ControlPanel.tlb"\r
+ HeaderFileName=""\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;_USRDLL"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
RuntimeLibrary="1"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderThrough=""\r
PrecompiledHeaderFile=""\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
WarningLevel="4"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"\r
- DisableSpecificWarnings="4311;4312"/>\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4311;4312"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../DLL/Debug/dnssd.lib ws2_32.lib"\r
- OutputFile="Debug/Bonjour.cpl"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/Bonjour.cpl"\r
LinkIncremental="2"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
ModuleDefinitionFile=".\ControlPanel.def"\r
- GenerateDebugInformation="TRUE"\r
- ProgramDatabaseFile=".\Debug/ControlPanel.pdb"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile=".\$(IntDir)\ControlPanel.pdb"\r
SubSystem="2"\r
- ImportLibrary=".\Debug/Bonjour.lib"\r
- TargetMachine="1"/>\r
+ ImportLibrary=".\$(OutDir)\Bonjour.lib"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
TypeLibraryName=".\Debug/ControlPanel.tlb"\r
- HeaderFileName=""/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ HeaderFileName=""\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderThrough=""\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4311;4312"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
- Culture="6153"\r
- AdditionalIncludeDirectories="../"/>\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/Bonjour.cpl"\r
+ LinkIncremental="2"\r
+ SuppressStartupBanner="true"\r
+ ModuleDefinitionFile=".\ControlPanel.def"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile=".\$(IntDir)\ControlPanel.pdb"\r
+ SubSystem="2"\r
+ ImportLibrary=".\$(OutDir)\Bonjour.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel64.manifest"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="1"\r
+ TypeLibraryName=".\Release/ControlPanel.tlb"\r
+ HeaderFileName=""\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
RuntimeLibrary="0"\r
- EnableFunctionLevelLinking="TRUE"\r
+ EnableFunctionLevelLinking="true"\r
UsePrecompiledHeader="0"\r
- AssemblerListingLocation=".\Release/"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
WarningLevel="4"\r
- SuppressStartupBanner="TRUE"\r
- DisableSpecificWarnings="4702"/>\r
+ SuppressStartupBanner="true"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../DLL/Release/dnssd.lib ws2_32.lib"\r
- OutputFile="Release/Bonjour.cpl"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/Bonjour.cpl"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
+ SuppressStartupBanner="true"\r
ModuleDefinitionFile=".\ControlPanel.def"\r
- ProgramDatabaseFile=".\Release/ControlPanel.pdb"\r
+ ProgramDatabaseFile=".\$(IntDir)\ControlPanel.pdb"\r
SubSystem="2"\r
- ImportLibrary=".\Release/Bonjour.lib"\r
- TargetMachine="1"/>\r
+ ImportLibrary=".\$(OutDir)\Bonjour.lib"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="DLLBuild\$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="TRUE"\r
- SuppressStartupBanner="TRUE"\r
- TargetEnvironment="1"\r
+ MkTypLibCompatible="true"\r
+ SuppressStartupBanner="true"\r
+ TargetEnvironment="3"\r
TypeLibraryName=".\Release/ControlPanel.tlb"\r
- HeaderFileName=""/>\r
+ HeaderFileName=""\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
- <Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
+ AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
- Culture="6153"\r
- AdditionalIncludeDirectories="../"/>\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/Bonjour.cpl"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ ModuleDefinitionFile=".\ControlPanel.def"\r
+ ProgramDatabaseFile=".\$(IntDir)\ControlPanel.pdb"\r
+ SubSystem="2"\r
+ ImportLibrary=".\$(OutDir)\Bonjour.lib"\r
+ TargetMachine="17"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel64.manifest"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Source Files"\r
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+ >\r
<File\r
- RelativePath="ConfigDialog.cpp">\r
+ RelativePath="ConfigDialog.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Release|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="ConfigPropertySheet.cpp">\r
+ RelativePath="ConfigPropertySheet.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="ControlPanel.cpp">\r
+ RelativePath="ControlPanel.cpp"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="ControlPanel.def">\r
+ RelativePath="ControlPanel.def"\r
+ >\r
</File>\r
<File\r
- RelativePath="FirstPage.cpp">\r
+ RelativePath="FirstPage.cpp"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="SecondPage.cpp">\r
+ RelativePath=".\FourthPage.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="SecondPage.cpp"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Release|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="SharedSecret.cpp">\r
+ RelativePath="SharedSecret.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="stdafx.cpp">\r
+ RelativePath="stdafx.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
PreprocessorDefinitions=""\r
- UsePrecompiledHeader="0"/>\r
+ UsePrecompiledHeader="0"\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
PreprocessorDefinitions=""\r
- UsePrecompiledHeader="0"/>\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ UsePrecompiledHeader="0"\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="ThirdPage.cpp">\r
+ RelativePath="ThirdPage.cpp"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl">\r
+ Filter="h;hpp;hxx;hm;inl"\r
+ >\r
<File\r
- RelativePath="..\CommonServices.h">\r
+ RelativePath="ConfigDialog.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ConfigDialog.h">\r
+ RelativePath="ConfigPropertySheet.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ConfigPropertySheet.h">\r
+ RelativePath="ControlPanel.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ControlPanel.h">\r
+ RelativePath="FirstPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="FirstPage.h">\r
+ RelativePath=".\FourthPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="Resource.h">\r
+ RelativePath="Resource.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="SecondPage.h">\r
+ RelativePath="SecondPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="SharedSecret.h">\r
+ RelativePath="SharedSecret.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="stdafx.h">\r
+ RelativePath="stdafx.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ThirdPage.h">\r
+ RelativePath="ThirdPage.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">\r
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"\r
+ >\r
<File\r
- RelativePath="res\configurator.ico">\r
+ RelativePath="res\configurator.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\controlpanel.ico">\r
+ RelativePath="res\controlpanel.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="ControlPanelDll.rc">\r
+ RelativePath=".\res\ControlPanel.rc2"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\ControlPanelDll.rc2">\r
+ RelativePath=".\ControlPanelDll.rc"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\failure.ico">\r
+ RelativePath="res\failure.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\success.ico">\r
+ RelativePath="res\success.ico"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Support"\r
- Filter="">\r
+ >\r
+ <File\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="..\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\dns_sd.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\DebugServices.h">\r
+ RelativePath="..\Secret.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dns_sd.h">\r
+ RelativePath="..\Secret.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\WinServices.cpp">\r
+ RelativePath="..\WinServices.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\WinServices.h">\r
+ RelativePath="..\WinServices.h"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
<Globals>\r
+ <Global\r
+ Name="RESOURCE_FILE"\r
+ Value="ControlPanelDll.rc"\r
+ />\r
</Globals>\r
</VisualStudioProject>\r
END\r
\r
\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// RT_MANIFEST\r
-//\r
-\r
-2 RT_MANIFEST "res\\ControlPanel.dll.manifest"\r
-\r
-\r
-\r
#ifdef APSTUDIO_INVOKED\r
/////////////////////////////////////////////////////////////////////////////\r
//\r
END\r
\r
\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// RT_MANIFEST\r
-//\r
-\r
-1 RT_MANIFEST "res\\ControlPanel.exe.manifest"\r
-\r
-\r
-\r
#ifdef APSTUDIO_INVOKED\r
/////////////////////////////////////////////////////////////////////////////\r
//\r
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="ControlPanel (Vista)"\r
ProjectGUID="{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}"\r
- SccProjectName=""\r
- SccLocalPath=""\r
- Keyword="MFCProj">\r
+ Keyword="MFCProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
BasicRuntimeChecks="3"\r
RuntimeLibrary="1"\r
UsePrecompiledHeader="0"\r
PrecompiledHeaderThrough=""\r
PrecompiledHeaderFile=""\r
- AssemblerListingLocation=".\Debug/"\r
- ObjectFile=".\Debug/"\r
- ProgramDataBaseFileName=".\Debug/"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
WarningLevel="4"\r
- SuppressStartupBanner="TRUE"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
CallingConvention="0"\r
- DisableSpecificWarnings="4311;4312"/>\r
+ DisableSpecificWarnings="4311;4312"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../DLL/Debug/dnssd.lib ws2_32.lib"\r
- OutputFile="Debug/ControlPanel.exe"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/ControlPanel.exe"\r
LinkIncremental="2"\r
- SuppressStartupBanner="TRUE"\r
- GenerateDebugInformation="TRUE"\r
- ProgramDatabaseFile=".\Debug/ControlPanel.pdb"\r
+ SuppressStartupBanner="true"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"\r
SubSystem="2"\r
EntryPointSymbol="wWinMainCRTStartup"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="_DEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ PrecompiledHeaderThrough=""\r
+ PrecompiledHeaderFile=""\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="0"\r
+ DisableSpecificWarnings="4311;4312"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="_DEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/ControlPanel.exe"\r
+ LinkIncremental="2"\r
+ SuppressStartupBanner="true"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"\r
+ SubSystem="2"\r
+ EntryPointSymbol="wWinMainCRTStartup"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel64.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
UseOfMFC="1"\r
- CharacterSet="2">\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="false"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
InlineFunctionExpansion="1"\r
AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE"\r
- StringPooling="TRUE"\r
- MinimalRebuild="FALSE"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
RuntimeLibrary="0"\r
- EnableFunctionLevelLinking="TRUE"\r
- TreatWChar_tAsBuiltInType="TRUE"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
UsePrecompiledHeader="0"\r
- ObjectFile=".\Release/"\r
- ProgramDataBaseFileName=".\Release/"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
WarningLevel="4"\r
- SuppressStartupBanner="TRUE"\r
- DisableSpecificWarnings="4702"/>\r
+ SuppressStartupBanner="true"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../DLL/Release/dnssd.lib ws2_32.lib"\r
- OutputFile="Release/ControlPanel.exe"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/ControlPanel.exe"\r
LinkIncremental="1"\r
- SuppressStartupBanner="TRUE"\r
- ProgramDatabaseFile=".\Release/ControlPanel.pdb"\r
+ SuppressStartupBanner="true"\r
+ ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
EntryPointSymbol="wWinMainCRTStartup"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ UseOfMFC="1"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
Name="VCMIDLTool"\r
PreprocessorDefinitions="NDEBUG"\r
- MkTypLibCompatible="FALSE"/>\r
- <Tool\r
- Name="VCPostBuildEventTool"/>\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ InlineFunctionExpansion="1"\r
+ AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="false"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ TreatWChar_tAsBuiltInType="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ ObjectFile="$(IntDir)\"\r
+ ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+ WarningLevel="4"\r
+ SuppressStartupBanner="true"\r
+ DisableSpecificWarnings="4702"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
Culture="1033"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)/ControlPanel.exe"\r
+ LinkIncremental="1"\r
+ SuppressStartupBanner="true"\r
+ ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ EntryPointSymbol="wWinMainCRTStartup"\r
+ TargetMachine="17"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\ControlPanel64.manifest"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Files>\r
<Filter\r
Name="Source Files"\r
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+ >\r
<File\r
- RelativePath="ConfigDialog.cpp">\r
+ RelativePath="ConfigDialog.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="ConfigPropertySheet.cpp">\r
+ RelativePath="ConfigPropertySheet.cpp"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath=".\ControlPanelExe.cpp">\r
+ RelativePath=".\ControlPanelExe.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="FirstPage.cpp">\r
+ RelativePath="FirstPage.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|x64"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\FourthPage.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="SecondPage.cpp">\r
+ RelativePath="SecondPage.cpp"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
- PreprocessorDefinitions=""/>\r
+ PreprocessorDefinitions=""\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="SharedSecret.cpp">\r
+ RelativePath="SharedSecret.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="stdafx.cpp">\r
+ RelativePath="stdafx.cpp"\r
+ >\r
<FileConfiguration\r
- Name="Debug|Win32">\r
+ Name="Debug|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
PreprocessorDefinitions=""\r
- UsePrecompiledHeader="0"/>\r
+ UsePrecompiledHeader="0"\r
+ />\r
</FileConfiguration>\r
<FileConfiguration\r
- Name="Release|Win32">\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions=""\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="2"\r
PreprocessorDefinitions=""\r
- UsePrecompiledHeader="0"/>\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ PreprocessorDefinitions=""\r
+ UsePrecompiledHeader="0"\r
+ />\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath="ThirdPage.cpp">\r
+ RelativePath="ThirdPage.cpp"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
- Filter="h;hpp;hxx;hm;inl">\r
+ Filter="h;hpp;hxx;hm;inl"\r
+ >\r
<File\r
- RelativePath="..\CommonServices.h">\r
+ RelativePath="ConfigDialog.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ConfigDialog.h">\r
+ RelativePath="ConfigPropertySheet.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ConfigPropertySheet.h">\r
+ RelativePath=".\ControlPanelExe.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\ControlPanelExe.h">\r
+ RelativePath="FirstPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="FirstPage.h">\r
+ RelativePath=".\FourthPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="Resource.h">\r
+ RelativePath="Resource.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="SecondPage.h">\r
+ RelativePath="SecondPage.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="SharedSecret.h">\r
+ RelativePath="SharedSecret.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="stdafx.h">\r
+ RelativePath="stdafx.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="ThirdPage.h">\r
+ RelativePath="ThirdPage.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">\r
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"\r
+ >\r
<File\r
- RelativePath="res\configurator.ico">\r
+ RelativePath="res\configurator.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\controlpanel.ico">\r
+ RelativePath="res\controlpanel.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="ControlPanelExe.rc">\r
+ RelativePath=".\res\ControlPanel.rc2"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\ControlPanelExe.rc2">\r
+ RelativePath=".\ControlPanelExe.rc"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\failure.ico">\r
+ RelativePath="res\failure.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="res\success.ico">\r
+ RelativePath="res\success.ico"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Support"\r
- Filter="">\r
+ >\r
+ <File\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="..\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\dns_sd.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\DebugServices.h">\r
+ RelativePath="..\Secret.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dns_sd.h">\r
+ RelativePath="..\Secret.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\WinServices.cpp">\r
+ RelativePath="..\WinServices.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\WinServices.h">\r
+ RelativePath="..\WinServices.h"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
Change History (most recent first):
$Log: FirstPage.cpp,v $
+Revision 1.7 2009/06/22 23:25:10 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
Revision 1.6 2006/08/14 23:25:28 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
CSharedSecret dlg;
- dlg.m_key = name;
+ dlg.Load( name );
if ( dlg.DoModal() == IDOK )
{
--- /dev/null
+/* -*- 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: FourthPage.cpp,v $
+Revision 1.1 2009/07/01 19:20:37 herscher
+<rdar://problem/6713286> UI changes for configuring sleep proxy settings.
+
+
+
+*/
+
+#include "FourthPage.h"
+#include "resource.h"
+
+#include "ConfigPropertySheet.h"
+#include "SharedSecret.h"
+
+#include <WinServices.h>
+
+#define MAX_KEY_LENGTH 255
+
+
+IMPLEMENT_DYNCREATE(CFourthPage, CPropertyPage)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::CFourthPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CFourthPage::CFourthPage()
+:
+ CPropertyPage(CFourthPage::IDD)
+{
+ //{{AFX_DATA_INIT(CFourthPage)
+ //}}AFX_DATA_INIT
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::~CFourthPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CFourthPage::~CFourthPage()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CFourthPage::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CFourthPage)
+ //}}AFX_DATA_MAP
+ DDX_Control(pDX, IDC_POWER_MANAGEMENT, m_checkBox);
+}
+
+BEGIN_MESSAGE_MAP(CFourthPage, CPropertyPage)
+ //{{AFX_MSG_MAP(CFourthPage)
+ //}}AFX_MSG_MAP\r
+ ON_BN_CLICKED(IDC_POWER_MANAGEMENT, &CFourthPage::OnBnClickedPowerManagement)\r
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::SetModified
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CFourthPage::SetModified( BOOL bChanged )
+{
+ m_modified = bChanged;
+
+ CPropertyPage::SetModified( bChanged );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::OnSetActive
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CFourthPage::OnSetActive()
+{
+ CConfigPropertySheet * psheet;
+ HKEY key = NULL;
+ DWORD dwSize;
+ DWORD enabled;
+ DWORD err;
+ BOOL b = CPropertyPage::OnSetActive();
+
+ psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
+ require_quiet( psheet, exit );
+
+ m_checkBox.SetCheck( 0 );
+
+ // Now populate the browse domain box
+
+ err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key );
+ require_noerr( err, exit );
+
+ dwSize = sizeof( DWORD );
+ err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+ require_noerr( err, exit );
+
+ m_checkBox.SetCheck( enabled );
+
+exit:
+
+ if ( key )
+ {
+ RegCloseKey( key );
+ }
+
+ return b;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::OnOK
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CFourthPage::OnOK()
+{
+ if ( m_modified )
+ {
+ Commit();
+ }
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CFourthPage::Commit()
+{
+ HKEY key = NULL;
+ DWORD enabled;
+ DWORD err;
+
+ err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key );
+ require_noerr( err, exit );
+
+ enabled = m_checkBox.GetCheck();
+ err = RegSetValueEx( key, L"Enabled", NULL, REG_DWORD, (LPBYTE) &enabled, sizeof( enabled ) );
+ require_noerr( err, exit );
+
+exit:
+
+ if ( key )
+ {
+ RegCloseKey( key );
+ }
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage::OnBnClickedRemoveBrowseDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+\r
+void CFourthPage::OnBnClickedPowerManagement()\r
+{\r
+ char buf[ 256 ];\r
+\r
+ sprintf( buf, "check box: %d", m_checkBox.GetCheck() );\r
+ OutputDebugStringA( buf );\r
+ // TODO: Add your control notification handler code here\r
+\r
+ SetModified( TRUE );\r
+}\r
--- /dev/null
+/* -*- 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: FourthPage.h,v $
+Revision 1.1 2009/07/01 19:20:37 herscher
+<rdar://problem/6713286> UI changes for configuring sleep proxy settings.
+
+
+*/
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+#include <list>
+#include "afxcmn.h"
+
+#include "afxwin.h"
+
+
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// CFourthPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CFourthPage : public CPropertyPage
+{
+public:
+ CFourthPage();
+ ~CFourthPage();
+
+protected:
+
+ //{{AFX_DATA(CFourthPage)
+ enum { IDD = IDR_APPLET_PAGE4 };
+ //}}AFX_DATA
+
+ //{{AFX_VIRTUAL(CFourthPage)
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+ DECLARE_DYNCREATE(CFourthPage)
+
+ //{{AFX_MSG(CFourthPage)
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+private:
+
+ typedef std::list<CString> StringList;
+
+ afx_msg BOOL
+ OnSetActive();
+
+ afx_msg void
+ OnOK();
+
+ void
+ SetModified( BOOL bChanged = TRUE );
+
+ void
+ Commit();
+
+ BOOL m_modified;
+
+public:
+private:
+
+ CButton m_checkBox;
+
+public:
+\r
+ afx_msg void OnBnClickedPowerManagement();\r
+};
Change History (most recent first):
$Log: SharedSecret.cpp,v $
+Revision 1.7 2009/06/22 23:25:11 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
Revision 1.6 2007/06/12 20:06:06 herscher
<rdar://problem/5263387> ControlPanel was inadvertently adding a trailing dot to all key names.
// SharedSecret.cpp : implementation file
//
+
+#include <Secret.h>
#include "stdafx.h"
#include "SharedSecret.h"
+#include <WinServices.h>
#include <DebugServices.h>
-#include <ntsecapi.h>
-
-//---------------------------------------------------------------------------------------------------------------------------
-// Private declarations
-//---------------------------------------------------------------------------------------------------------------------------
-static BOOL
-InitLsaString
- (
- PLSA_UNICODE_STRING pLsaString,
- LPCWSTR pwszString
- );
// SharedSecret dialog
END_MESSAGE_MAP()
-
//---------------------------------------------------------------------------------------------------------------------------
-// CSharedSecret::Commit
+// CSharedSecret::Load
//---------------------------------------------------------------------------------------------------------------------------
void
-CSharedSecret::Commit( CString zone )
+CSharedSecret::Load( CString zone )
{
- LSA_OBJECT_ATTRIBUTES attrs;
- LSA_HANDLE handle = NULL;
- NTSTATUS res;
- LSA_UNICODE_STRING lucZoneName;
- LSA_UNICODE_STRING lucKeyName;
- LSA_UNICODE_STRING lucSecretName;
- BOOL ok;
- OSStatus err;
-
- // If there isn't a trailing dot, add one because the mDNSResponder
- // presents names with the trailing dot.
-
- if ( zone.ReverseFind( '.' ) != ( zone.GetLength() - 1 ) )
- {
- zone += '.';
- }
+ char zoneUTF8[ 256 ];
+ char outDomain[ 256 ];
+ char outKey[ 256 ];
+ char outSecret[ 256 ];
- if ( m_key.ReverseFind( '.' ) != ( m_key.GetLength() - 1 ) )
+ StringObjectToUTF8String( zone, zoneUTF8, sizeof( zoneUTF8 ) );
+
+ if ( LsaGetSecret( zoneUTF8, outDomain, sizeof( outDomain ) / sizeof( TCHAR ), outKey, sizeof( outKey ) / sizeof( TCHAR ), outSecret, sizeof( outSecret ) / sizeof( TCHAR ) ) )
{
- m_key += '.';
+ m_key = outKey;
+ m_secret = outSecret;
}
-
- // <rdar://problem/4192119>
- //
- // Prepend "$" to the key name, so that there will
- // be no conflict between the zone name and the key
- // name
-
- m_key.Insert( 0, L"$" );
-
- // attrs are reserved, so initialize to zeroes.
-
- ZeroMemory( &attrs, sizeof( attrs ) );
-
- // Get a handle to the Policy object on the local system
-
- res = LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle );
- err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
- require_noerr( err, exit );
-
- // Intializing PLSA_UNICODE_STRING structures
-
- ok = InitLsaString( &lucZoneName, zone );
- err = translate_errno( ok, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
-
- ok = InitLsaString( &lucKeyName, m_key );
- err = translate_errno( ok, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
-
- ok = InitLsaString( &lucSecretName, m_secret );
- err = translate_errno( ok, errno_compat(), kUnknownErr );
- require_noerr( err, exit );
-
- // Store the private data.
-
- res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName );
- err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
- require_noerr( err, exit );
-
- res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName );
- err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
- require_noerr( err, exit );
-
-exit:
-
- if ( handle )
+ else
{
- LsaClose( handle );
- handle = NULL;
+ m_key = zone;
}
-
- return;
}
//---------------------------------------------------------------------------------------------------------------------------
-// InitLsaString
+// CSharedSecret::Commit
//---------------------------------------------------------------------------------------------------------------------------
-static BOOL
-InitLsaString
- (
- PLSA_UNICODE_STRING pLsaString,
- LPCWSTR pwszString
- )
+void
+CSharedSecret::Commit( CString zone )
{
- size_t dwLen = 0;
- BOOL ret = FALSE;
-
- if ( pLsaString == NULL )
- {
- goto exit;
- }
-
- if ( pwszString != NULL )
- {
- dwLen = wcslen(pwszString);
-
- // String is too large
- if (dwLen > 0x7ffe)
- {
- goto exit;
- }
- }
-
- // Store the string.
-
- pLsaString->Buffer = (WCHAR *) pwszString;
- pLsaString->Length = (USHORT) dwLen * sizeof(WCHAR);
- pLsaString->MaximumLength = (USHORT)(dwLen+1) * sizeof(WCHAR);
-
- ret = TRUE;
+ char zoneUTF8[ 256 ];
+ char keyUTF8[ 256 ];
+ char secretUTF8[ 256 ];
-exit:
+ StringObjectToUTF8String( zone, zoneUTF8, sizeof( zoneUTF8 ) );
+ StringObjectToUTF8String( m_key, keyUTF8, sizeof( keyUTF8 ) );
+ StringObjectToUTF8String( m_secret, secretUTF8, sizeof( secretUTF8 ) );
- return ret;
+ LsaSetSecret( zoneUTF8, keyUTF8, secretUTF8 );
}
Change History (most recent first):
$Log: SharedSecret.h,v $
+Revision 1.5 2009/06/22 23:25:11 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
Revision 1.4 2006/08/14 23:25:28 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
// Dialog Data
enum { IDD = IDR_SECRET };
+ void
+ Load( CString zone );
+
void
Commit( CString zone );
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+ <description>Control Panel applet for configuring Wide-Area Bonjour.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
+ </dependentAssembly>
+ </dependency>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+ <description>Control Panel applet for configuring Wide-Area Bonjour.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*" />
+ </dependentAssembly>
+ </dependency>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
#define IDR_APPLET_PAGE2 132
#define IDR_SECRET 133
#define IDR_APPLET_PAGE3 134
+#define IDR_APPLET_PAGE4 135
#define IDI_FAILURE 140
#define IDI_SUCCESS 141
#define IDD_ADD_BROWSE_DOMAIN 142
#define IDC_BUTTON2 1012
#define IDC_REMOVE_BROWSE_DOMAIN 1012
#define IDC_ADD_BROWSE_DOMAIN 1013
+#define IDC_POWER_MANAGEMENT 1014
// Next default values for new objects
//
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 143
#define _APS_NEXT_COMMAND_VALUE 32771
-#define _APS_NEXT_CONTROL_VALUE 1014
+#define _APS_NEXT_CONTROL_VALUE 1015
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Change History (most recent first):
$Log: AssemblyInfo.cpp,v $
+Revision 1.6 2009/03/30 20:16:27 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.5 2006/08/14 23:25:43 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#include "stdafx.h"
#include "WinVersRes.h"
+using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
+using namespace System::Runtime::InteropServices;
+using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
[assembly:AssemblyTitleAttribute("dnssd.NET")];
[assembly:AssemblyDescriptionAttribute(".NET wrapper for DNS-SD services")];
[assembly:AssemblyConfigurationAttribute("")];
-[assembly:AssemblyCompanyAttribute("Apple Computer, Inc.")];
+[assembly:AssemblyCompanyAttribute("Apple Inc.")];
[assembly:AssemblyProductAttribute("")];
-[assembly:AssemblyCopyrightAttribute("Apple Computer, Inc.")];
+[assembly:AssemblyCopyrightAttribute("Apple Inc.")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
[assembly:AssemblyDelaySignAttribute(false)];
[assembly:AssemblyKeyFileAttribute("dnssd_NET.snk")];
[assembly:AssemblyKeyNameAttribute("")];
+
+[assembly:ComVisible(false)];
+[assembly:CLSCompliantAttribute(true)];
+[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
Change History (most recent first):
$Log: Stdafx.h,v $
+Revision 1.6 2009/03/30 20:17:57 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.5 2006/08/14 23:25:43 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#using <mscorlib.dll>
#using <System.dll>
+struct _DNSServiceRef_t {};
+struct _DNSRecordRef_t {};
+
Change History (most recent first):
$Log: dnssd_NET.cpp,v $
+Revision 1.11 2009/03/30 20:19:05 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.10 2006/08/14 23:25:43 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
m_impl->SetupEvents();
- m_thread = new Thread(new ThreadStart(this, ProcessingThread));
+ m_thread = new Thread(new ThreadStart(this, &Apple::DNSSD::ServiceRef::ProcessingThread));
m_thread->Name = S"DNSService Thread";
m_thread->IsBackground = true;
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="DLL.NET"\r
- ProjectGUID="{9C6701E2-82B7-44B7-9B5E-3897D9153F79}"\r
- Keyword="ManagedCProj">\r
+ ProjectGUID="{2A2FFA97-AF60-494F-9384-BBAA283AA3F2}"\r
+ RootNamespace="DLL2NET"\r
+ Keyword="ManagedCProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
- CharacterSet="2"\r
- ManagedExtensions="TRUE">\r
+ CharacterSet="1"\r
+ ManagedExtensions="4"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ Description="Generating keypair..."\r
+ CommandLine="sn -k dnssd_NET.snk"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="../;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_WIN32;_DEBUG;WIN32_LEAN_AND_MEAN"\r
- MinimalRebuild="FALSE"\r
- BasicRuntimeChecks="0"\r
- RuntimeLibrary="1"\r
- UsePrecompiledHeader="0"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;WIN32_LEAN_AND_MEAN"\r
+ RuntimeLibrary="3"\r
+ UsePrecompiledHeader="2"\r
WarningLevel="3"\r
DebugInformationFormat="3"\r
- CallingConvention="2"/>\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalOptions="/noentry"\r
- AdditionalDependencies="../DLL/Debug/dnssd.lib mscoree.lib ws2_32.lib msvcrtd.lib"\r
+ AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"\r
OutputFile="$(OutDir)\dnssd.NET.dll"\r
LinkIncremental="2"\r
- AdditionalLibraryDirectories=""\r
- GenerateDebugInformation="TRUE"/>\r
+ GenerateDebugInformation="true"\r
+ AssemblyDebug="1"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ EmbedManifest="false"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ CharacterSet="1"\r
+ ManagedExtensions="4"\r
+ >\r
<Tool\r
Name="VCPreBuildEventTool"\r
Description="Generating keypair..."\r
- CommandLine="sn -k dnssd_NET.snk"/>\r
+ CommandLine="sn -k dnssd_NET.snk"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="../;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;WIN32_LEAN_AND_MEAN"\r
+ RuntimeLibrary="3"\r
+ UsePrecompiledHeader="2"\r
+ WarningLevel="3"\r
+ DebugInformationFormat="3"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)\dnssd.NET.dll"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="true"\r
+ AssemblyDebug="1"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ EmbedManifest="false"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
- CharacterSet="2"\r
- ManagedExtensions="TRUE">\r
+ CharacterSet="1"\r
+ ManagedExtensions="4"\r
+ WholeProgramOptimization="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ Description="Generating keypair..."\r
+ CommandLine="sn -k dnssd_NET.snk"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
- AdditionalOptions="/Zl"\r
AdditionalIncludeDirectories="../;../../mDNSShared"\r
PreprocessorDefinitions="WIN32;NDEBUG;WIN32_LEAN_AND_MEAN"\r
- MinimalRebuild="FALSE"\r
- RuntimeLibrary="0"\r
+ RuntimeLibrary="2"\r
UsePrecompiledHeader="0"\r
WarningLevel="3"\r
- DebugInformationFormat="3"/>\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalOptions="/noentry"\r
- AdditionalDependencies="../DLL/Release/dnssd.lib mscoree.lib ws2_32.lib msvcrt.lib"\r
+ AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"\r
OutputFile="$(OutDir)\dnssd.NET.dll"\r
LinkIncremental="1"\r
- GenerateDebugInformation="TRUE"\r
- ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"/>\r
+ GenerateDebugInformation="true"\r
+ TargetMachine="1"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCManifestTool"\r
+ EmbedManifest="false"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ CharacterSet="1"\r
+ ManagedExtensions="4"\r
+ WholeProgramOptimization="1"\r
+ >\r
<Tool\r
Name="VCPreBuildEventTool"\r
Description="Generating keypair..."\r
- CommandLine="sn -k dnssd_NET.snk"/>\r
+ CommandLine="sn -k dnssd_NET.snk"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories="../;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;WIN32_LEAN_AND_MEAN"\r
+ RuntimeLibrary="2"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCLinkerTool"\r
+ AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"\r
+ OutputFile="$(OutDir)\dnssd.NET.dll"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="true"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ EmbedManifest="false"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
+ <AssemblyReference\r
+ RelativePath="System.dll"\r
+ AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"\r
+ />\r
+ <AssemblyReference\r
+ RelativePath="System.Data.dll"\r
+ AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"\r
+ />\r
+ <AssemblyReference\r
+ RelativePath="System.XML.dll"\r
+ AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"\r
+ />\r
</References>\r
<Files>\r
<Filter\r
Name="Source Files"\r
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
<File\r
- RelativePath=".\AssemblyInfo.cpp">\r
+ RelativePath=".\AssemblyInfo.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\dnssd_NET.cpp">\r
+ RelativePath=".\dnssd_NET.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\Stdafx.cpp">\r
+ RelativePath=".\Stdafx.cpp"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="1"\r
+ />\r
+ </FileConfiguration>\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
- <File\r
- RelativePath=".\dnssd_NET.h">\r
- </File>\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
<File\r
- RelativePath="PString.h">\r
+ RelativePath=".\dnssd_NET.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\resource.h">\r
+ RelativePath=".\resource.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\Stdafx.h">\r
+ RelativePath=".\Stdafx.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
<File\r
- RelativePath="dnssd_NET.ico">\r
+ RelativePath=".\dnssd_NET.ico"\r
+ >\r
</File>\r
<File\r
- RelativePath="dnssd_NET.rc">\r
+ RelativePath=".\dnssd_NET.rc"\r
+ >\r
</File>\r
</Filter>\r
<File\r
- RelativePath=".\ReadMe.txt">\r
+ RelativePath=".\ReadMe.txt"\r
+ >\r
</File>\r
</Files>\r
<Globals>\r
; Change History (most recent first):
;
; $Log: dnssd.def,v $
+; Revision 1.5 2009/03/30 20:14:27 herscher
+; <rdar://problem/5925472> Current Bonjour code does not compile on Windows
+;
; Revision 1.4 2006/09/27 00:46:18 herscher
; <rdar://problem/4249761> API: Need DNSServiceGetAddrInfo()
;
DNSServiceReconfirmRecord
DNSServiceNATPortMappingCreate
DNSServiceGetAddrInfo
+ DNSServiceGetProperty
TXTRecordCreate
TXTRecordDeallocate
TXTRecordSetValue
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="DLL"\r
ProjectGUID="{AB581101-18F0-46F6-B56A-83A6B1EA657E}"\r
- Keyword="Win32Proj">\r
+ RootNamespace="DLL"\r
+ Keyword="Win32Proj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug\"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DEBUG=1;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
- ExceptionHandling="FALSE"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DEBUG=1;NOT_HAVE_SA_LEN;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
BasicRuntimeChecks="3"\r
- SmallerTypeCheck="TRUE"\r
+ SmallerTypeCheck="true"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
+ BufferSecurityCheck="true"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
CallingConvention="2"\r
CompileAs="0"\r
- DisableSpecificWarnings="4127;4204"/>\r
+ DisableSpecificWarnings="4127;4204"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
OutputFile="$(OutDir)/dnssd.dll"\r
LinkIncremental="2"\r
ModuleDefinitionFile="dnssd.def"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/dnssd.pdb"\r
SubSystem="2"\r
BaseAddress="0x16000000"\r
- ImportLibrary="$(IntDir)\dnssd.lib"\r
- TargetMachine="1"/>\r
+ ImportLibrary="$(OutDir)\dnssd.lib"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DEBUG=1;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;NOT_HAVE_SA_LEN"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
+ BasicRuntimeChecks="3"\r
+ SmallerTypeCheck="true"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ CompileAs="0"\r
+ DisableSpecificWarnings="4127;4204"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
+ OutputFile="$(OutDir)/dnssd.dll"\r
+ LinkIncremental="2"\r
+ ModuleDefinitionFile="dnssd.def"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/dnssd.pdb"\r
+ SubSystem="2"\r
+ BaseAddress="0x16000000"\r
+ ImportLibrary="$(OutDir)\dnssd.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"\r
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;NOT_HAVE_SA_LEN"\r
RuntimeLibrary="0"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
CallingConvention="2"\r
CompileAs="0"\r
- DisableSpecificWarnings="4127;4204"/>\r
+ DisableSpecificWarnings="4127;4204"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
OutputFile="$(OutDir)/dnssd.dll"\r
LinkIncremental="1"\r
ModuleDefinitionFile="dnssd.def"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
BaseAddress="0x16000000"\r
- ImportLibrary=".\Release\dnssd.lib"\r
- TargetMachine="1"/>\r
+ ImportLibrary="$(OutDir)\dnssd.lib"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\WINDOWS\system32\$(PlatformName)" mkdir "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
if not exist "$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)"
if not exist "$(DSTROOT)\Program Files\Bonjour SDK\include" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\include"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
xcopy /I/Y "$(OutDir)\dnssd.lib" "$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)"
xcopy /I/Y "$(ProjectDir)..\..\mDNSShared\dns_sd.h" "$(DSTROOT)\Program Files\Bonjour SDK\include"
:END
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;NOT_HAVE_SA_LEN"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ CompileAs="0"\r
+ DisableSpecificWarnings="4127;4204"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
+ OutputFile="$(OutDir)/dnssd.dll"\r
+ LinkIncremental="1"\r
+ ModuleDefinitionFile="dnssd.def"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ BaseAddress="0x16000000"\r
+ ImportLibrary="$(OutDir)\dnssd.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\WINDOWS\system32\$(PlatformName)" mkdir "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
if not exist "$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)"
if not exist "$(DSTROOT)\Program Files\Bonjour SDK\include" mkdir "$(DSTROOT)\Program Files\Bonjour SDK\include"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\WINDOWS\system32\$(PlatformName)"
xcopy /I/Y "$(OutDir)\dnssd.lib" "$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)"
:END
"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Filter\r
Name="Source Files"\r
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\dllmain.c">\r
+ RelativePath=".\dllmain.c"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\dnssd.def">\r
+ RelativePath=".\dnssd.def"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_clientlib.c">\r
+ RelativePath="..\..\mDNSShared\dnssd_clientlib.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_clientstub.c">\r
+ RelativePath="..\..\mDNSShared\dnssd_clientstub.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_ipc.c">\r
+ RelativePath="..\..\mDNSShared\dnssd_ipc.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\GenLinkedList.c">\r
+ RelativePath="..\..\mDNSShared\GenLinkedList.c"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
- <File\r
- RelativePath="..\..\mDNSShared\CommonServices.h">\r
- </File>\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.h">\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dns_sd.h">\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_ipc.h">\r
+ RelativePath="..\..\mDNSShared\dns_sd.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_sock.h">\r
+ RelativePath="..\..\mDNSShared\dnssd_ipc.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\GenLinkedList.h">\r
+ RelativePath="..\..\mDNSShared\GenLinkedList.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\resource.h">\r
+ RelativePath=".\resource.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
<File\r
- RelativePath=".\dll.rc">\r
+ RelativePath=".\dll.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009, Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "DLLStub.h"
+
+static int g_defaultErrorCode = kDNSServiceErr_Unknown;
+static DLLStub g_glueLayer;
+
+
+// ------------------------------------------
+// DLLStub implementation
+// ------------------------------------------
+DLLStub * DLLStub::m_instance;
+
+DLLStub::DLLStub()
+:
+ m_library( LoadLibrary( TEXT( "dnssd.dll" ) ) )
+{
+ m_instance = this;
+}
+
+
+DLLStub::~DLLStub()
+{
+ if ( m_library != NULL )
+ {
+ FreeLibrary( m_library );
+ m_library = NULL;
+ }
+
+ m_instance = NULL;
+}
+
+
+bool
+DLLStub::GetProcAddress( FARPROC * func, LPCSTR lpProcName )
+{
+ if ( m_instance && m_instance->m_library )
+ {
+ // Only call ::GetProcAddress if *func is NULL. This allows
+ // the calling code to cache the funcptr value, and we get
+ // some performance benefit.
+
+ if ( *func == NULL )
+ {
+ *func = ::GetProcAddress( m_instance->m_library, lpProcName );
+ }
+ }
+ else
+ {
+ *func = NULL;
+ }
+
+ return ( *func != NULL );
+}
+
+
+int DNSSD_API
+DNSServiceRefSockFD(DNSServiceRef sdRef)
+{
+ typedef int (DNSSD_API * Func)(DNSServiceRef sdRef);
+ static Func func = NULL;
+ int ret = -1;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceProcessResult(DNSServiceRef sdRef)
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef sdRef);
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef );
+ }
+
+ return ret;
+}
+
+
+void DNSSD_API
+DNSServiceRefDeallocate(DNSServiceRef sdRef)
+{
+ typedef void (DNSSD_API * Func)(DNSServiceRef sdRef);
+ static Func func = NULL;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ func( sdRef );
+ }
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceEnumerateDomains
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceDomainEnumReply callBack,
+ void *context
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceDomainEnumReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceRegister
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ const char *name,
+ const char *regtype,
+ const char *domain,
+ const char *host,
+ uint16_t port,
+ uint16_t txtLen,
+ const void *txtRecord,
+ DNSServiceRegisterReply callBack,
+ void *context
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, const char*, const char*, uint16_t, uint16_t, const void*, DNSServiceRegisterReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceAddRecord
+ (
+ DNSServiceRef sdRef,
+ DNSRecordRef *RecordRef,
+ DNSServiceFlags flags,
+ uint16_t rrtype,
+ uint16_t rdlen,
+ const void *rdata,
+ uint32_t ttl
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef*, DNSServiceFlags, uint16_t, uint16_t, const void*, uint32_t );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceUpdateRecord
+ (
+ DNSServiceRef sdRef,
+ DNSRecordRef RecordRef, /* may be NULL */
+ DNSServiceFlags flags,
+ uint16_t rdlen,
+ const void *rdata,
+ uint32_t ttl
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef, DNSServiceFlags, uint16_t, const void*, uint32_t );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, RecordRef, flags, rdlen, rdata, ttl );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceRemoveRecord
+ (
+ DNSServiceRef sdRef,
+ DNSRecordRef RecordRef,
+ DNSServiceFlags flags
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef, DNSServiceFlags );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, RecordRef, flags );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceBrowse
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ const char *regtype,
+ const char *domain, /* may be NULL */
+ DNSServiceBrowseReply callBack,
+ void *context /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, DNSServiceBrowseReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, regtype, domain, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceResolve
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ const char *name,
+ const char *regtype,
+ const char *domain,
+ DNSServiceResolveReply callBack,
+ void *context /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, const char*, DNSServiceResolveReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceConstructFullName
+ (
+ char *fullName,
+ const char *service, /* may be NULL */
+ const char *regtype,
+ const char *domain
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( char*, const char*, const char*, const char* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( fullName, service, regtype, domain );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceCreateConnection(DNSServiceRef *sdRef)
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( DNSServiceRef* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceRegisterRecord
+ (
+ DNSServiceRef sdRef,
+ DNSRecordRef *RecordRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ const char *fullname,
+ uint16_t rrtype,
+ uint16_t rrclass,
+ uint16_t rdlen,
+ const void *rdata,
+ uint32_t ttl,
+ DNSServiceRegisterRecordReply callBack,
+ void *context /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef*, DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, uint16_t, const void*, uint16_t, DNSServiceRegisterRecordReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, RecordRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata, ttl, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceQueryRecord
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ const char *fullname,
+ uint16_t rrtype,
+ uint16_t rrclass,
+ DNSServiceQueryRecordReply callBack,
+ void *context /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, DNSServiceQueryRecordReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceReconfirmRecord
+ (
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ const char *fullname,
+ uint16_t rrtype,
+ uint16_t rrclass,
+ uint16_t rdlen,
+ const void *rdata
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, uint16_t, const void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceNATPortMappingCreate
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceProtocol protocol, /* TCP and/or UDP */
+ uint16_t internalPort, /* network byte order */
+ uint16_t externalPort, /* network byte order */
+ uint32_t ttl, /* time to live in seconds */
+ DNSServiceNATPortMappingReply callBack,
+ void *context /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceProtocol, uint16_t, uint16_t, uint16_t, DNSServiceNATPortMappingReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, protocol, internalPort, externalPort, ttl, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceGetAddrInfo
+ (
+ DNSServiceRef *sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceProtocol protocol,
+ const char *hostname,
+ DNSServiceGetAddrInfoReply callBack,
+ void *context /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceProtocol, const char*, DNSServiceGetAddrInfoReply, void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( sdRef, flags, interfaceIndex, protocol, hostname, callBack, context );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceGetProperty
+ (
+ const char *property, /* Requested property (i.e. kDNSServiceProperty_DaemonVersion) */
+ void *result, /* Pointer to place to store result */
+ uint32_t *size /* size of result location */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( const char*, void*, uint32_t* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( property, result, size );
+ }
+
+ return ret;
+}
+
+
+void DNSSD_API
+TXTRecordCreate
+ (
+ TXTRecordRef *txtRecord,
+ uint16_t bufferLen,
+ void *buffer
+ )
+{
+ typedef void (DNSSD_API * Func)( TXTRecordRef*, uint16_t, void* );
+ static Func func = NULL;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ func( txtRecord, bufferLen, buffer );
+ }
+}
+
+
+void DNSSD_API
+TXTRecordDeallocate
+ (
+ TXTRecordRef *txtRecord
+ )
+{
+ typedef void (DNSSD_API * Func)( TXTRecordRef* );
+ static Func func = NULL;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ func( txtRecord );
+ }
+}
+
+
+DNSServiceErrorType DNSSD_API
+TXTRecordSetValue
+ (
+ TXTRecordRef *txtRecord,
+ const char *key,
+ uint8_t valueSize, /* may be zero */
+ const void *value /* may be NULL */
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( TXTRecordRef*, const char*, uint8_t, const void* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtRecord, key, valueSize, value );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+TXTRecordRemoveValue
+ (
+ TXTRecordRef *txtRecord,
+ const char *key
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( TXTRecordRef*, const char* );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtRecord, key );
+ }
+
+ return ret;
+}
+
+
+int DNSSD_API
+TXTRecordContainsKey
+ (
+ uint16_t txtLen,
+ const void *txtRecord,
+ const char *key
+ )
+{
+ typedef int (DNSSD_API * Func)( uint16_t, const void*, const char* );
+ static Func func = NULL;
+ int ret = 0;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtLen, txtRecord, key );
+ }
+
+ return ret;
+}
+
+
+uint16_t DNSSD_API
+TXTRecordGetCount
+ (
+ uint16_t txtLen,
+ const void *txtRecord
+ )
+{
+ typedef uint16_t (DNSSD_API * Func)( uint16_t, const void* );
+ static Func func = NULL;
+ uint16_t ret = 0;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtLen, txtRecord );
+ }
+
+ return ret;
+}
+
+
+uint16_t DNSSD_API
+TXTRecordGetLength
+ (
+ const TXTRecordRef *txtRecord
+ )
+{
+ typedef uint16_t (DNSSD_API * Func)( const TXTRecordRef* );
+ static Func func = NULL;
+ uint16_t ret = 0;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtRecord );
+ }
+
+ return ret;
+}
+
+
+const void * DNSSD_API
+TXTRecordGetBytesPtr
+ (
+ const TXTRecordRef *txtRecord
+ )
+{
+ typedef const void* (DNSSD_API * Func)( const TXTRecordRef* );
+ static Func func = NULL;
+ const void* ret = NULL;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtRecord );
+ }
+
+ return ret;
+}
+
+
+const void * DNSSD_API
+TXTRecordGetValuePtr
+ (
+ uint16_t txtLen,
+ const void *txtRecord,
+ const char *key,
+ uint8_t *valueLen
+ )
+{
+ typedef const void* (DNSSD_API * Func)( uint16_t, const void*, const char*, uint8_t* );
+ static Func func = NULL;
+ const void* ret = NULL;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtLen, txtRecord, key, valueLen );
+ }
+
+ return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+TXTRecordGetItemAtIndex
+ (
+ uint16_t txtLen,
+ const void *txtRecord,
+ uint16_t itemIndex,
+ uint16_t keyBufLen,
+ char *key,
+ uint8_t *valueLen,
+ const void **value
+ )
+{
+ typedef DNSServiceErrorType (DNSSD_API * Func)( uint16_t, const void*, uint16_t, uint16_t, char*, uint8_t*, const void** );
+ static Func func = NULL;
+ DNSServiceErrorType ret = g_defaultErrorCode;
+
+ if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+ {
+ ret = func( txtLen, txtRecord, itemIndex, keyBufLen, key, valueLen, value );
+ }
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009, Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DLLStub_h
+#define _DLLStub_h
+
+#include <windows.h>
+#include <dns_sd.h>
+
+class DLLStub
+{
+public:
+
+ DLLStub();
+ ~DLLStub();
+
+ static bool
+ GetProcAddress( FARPROC * func, LPCSTR lpProcName );
+
+private:
+
+ static DLLStub * m_instance;
+ HMODULE m_library;
+};
+
+
+#endif
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="8.00"\r
+ Name="DLLStub"\r
+ ProjectGUID="{3A2B6325-3053-4236-84BD-AA9BE2E323E5}"\r
+ RootNamespace="DLLStub"\r
+ Keyword="Win32Proj"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfATL="0"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="0"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ MinimalRebuild="false"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)\dnssdStatic.lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfATL="0"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="0"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ MinimalRebuild="false"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)\dnssdStatic.lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfATL="0"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="0"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)\dnssdStatic.lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="4"\r
+ UseOfATL="0"\r
+ CharacterSet="1"\r
+ WholeProgramOptimization="0"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ OutputFile="$(OutDir)\dnssdStatic.lib"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath=".\DLLStub.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath=".\DLLStub.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ </Filter>\r
+ <File\r
+ RelativePath=".\ReadMe.txt"\r
+ >\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DLLX.cpp,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+\r
+#include "stdafx.h"\r
+#include "resource.h"\r
+#include "DLLX.h"\r
+#include "dlldatax.h"\r
+#include <DebugServices.h>\r
+\r
+\r
+class CDLLComponentModule : public CAtlDllModuleT< CDLLComponentModule >\r
+{\r
+public :\r
+ DECLARE_LIBID(LIBID_Bonjour)\r
+ DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DLLX, "{56608F9C-223B-4CB6-813D-85EDCCADFB4B}")\r
+};\r
+\r
+CDLLComponentModule _AtlModule;\r
+\r
+\r
+#ifdef _MANAGED\r
+#pragma managed(push, off)\r
+#endif\r
+\r
+// DLL Entry Point\r
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
+{\r
+ debug_initialize( kDebugOutputTypeWindowsDebugger );
+ debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );\r
+\r
+#ifdef _MERGE_PROXYSTUB\r
+ if (!PrxDllMain(hInstance, dwReason, lpReserved))\r
+ return FALSE;\r
+#endif\r
+ hInstance;\r
+ return _AtlModule.DllMain(dwReason, lpReserved); \r
+}\r
+\r
+#ifdef _MANAGED\r
+#pragma managed(pop)\r
+#endif\r
+\r
+\r
+\r
+\r
+// Used to determine whether the DLL can be unloaded by OLE\r
+STDAPI DllCanUnloadNow(void)\r
+{\r
+#ifdef _MERGE_PROXYSTUB\r
+ HRESULT hr = PrxDllCanUnloadNow();\r
+ if (hr != S_OK)\r
+ return hr;\r
+#endif\r
+ return _AtlModule.DllCanUnloadNow();\r
+}\r
+\r
+\r
+// Returns a class factory to create an object of the requested type\r
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)\r
+{\r
+#ifdef _MERGE_PROXYSTUB\r
+ if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)\r
+ return S_OK;\r
+#endif\r
+ return _AtlModule.DllGetClassObject(rclsid, riid, ppv);\r
+}\r
+\r
+\r
+// DllRegisterServer - Adds entries to the system registry\r
+STDAPI DllRegisterServer(void)\r
+{\r
+ // registers object, typelib and all interfaces in typelib\r
+ HRESULT hr = _AtlModule.DllRegisterServer();\r
+#ifdef _MERGE_PROXYSTUB\r
+ if (FAILED(hr))\r
+ return hr;\r
+ hr = PrxDllRegisterServer();\r
+#endif\r
+ return hr;\r
+}\r
+\r
+\r
+// DllUnregisterServer - Removes entries from the system registry\r
+STDAPI DllUnregisterServer(void)\r
+{\r
+ HRESULT hr = _AtlModule.DllUnregisterServer();\r
+#ifdef _MERGE_PROXYSTUB\r
+ if (FAILED(hr))\r
+ return hr;\r
+ hr = PrxDllRegisterServer();\r
+ if (FAILED(hr))\r
+ return hr;\r
+ hr = PrxDllUnregisterServer();\r
+#endif\r
+ return hr;\r
+}\r
+\r
--- /dev/null
+; -*- Mode: C; tab-width: 4 -*-
+;
+; Copyright (c) 2009 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: DLLX.def,v $
+; Revision 1.1 2009/05/26 04:43:54 herscher
+; <rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+;\r
+;\r
+;\r
+\r
+\r
+LIBRARY "dnssdX.DLL"\r
+\r
+EXPORTS\r
+ DllCanUnloadNow PRIVATE\r
+ DllGetClassObject PRIVATE\r
+ DllRegisterServer PRIVATE\r
+ DllUnregisterServer PRIVATE\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DLLX.idl,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+// This file will be processed by the MIDL tool to\r
+// produce the type library (DLLComponent.tlb) and marshalling code.\r
+\r
+typedef [ uuid(4085DD59-D0E1-4efe-B6EE-DDBF7631B9C0) ]\r
+enum DNSSDFlags\r
+{\r
+ kDNSSDFlagsMoreComing = 0x0001,\r
+ kDNSSDFlagsDefault = 0x0004,\r
+ kDNSSDFlagsNoAutoRename = 0x0008,\r
+ kDNSSDFlagsShared = 0x0010,\r
+ kDNSSDFlagsUnique = 0x0020,\r
+ kDNSSDFlagsBrowseDomains = 0x0040,\r
+ kDNSSDFlagsRegistrationDomains = 0x0080,\r
+ kDNSSDFlagsLongLivedQuery = 0x0100,\r
+ kDNSSDFlagsAllowRemoteQuery = 0x0200,\r
+ kDNSSDFlagsForceMulticast = 0x0400,\r
+ kDNSSDFlagsForce = 0x0800,\r
+ kDNSSDFlagsReturnIntermediates = 0x1000,\r
+ kDNSSDFlagsNonBrowsable = 0x2000\r
+} DNSSDFlags;\r
+\r
+\r
+typedef [ uuid(30CDF335-CA52-4b17-AFF2-E83C64C450D4) ]\r
+enum DNSSDAddressFamily\r
+{\r
+ kDNSSDAddressFamily_IPv4 = 0x1,\r
+ kDNSSDAddressFamily_IPv6 = 0x2\r
+} DNSSDAddressFamily;\r
+\r
+\r
+typedef [ uuid(98FB4702-7374-4b16-A8DB-AD35BFB8364D) ]\r
+enum DNSSDProtocol\r
+{\r
+ kDNSSDProtocol_UDP = 0x10,\r
+ kDNSSDProtocol_TCP = 0x20\r
+} DNSSDProtocol;\r
+\r
+\r
+typedef [ uuid(72BF3EC3-19BC-47e5-8D95-3B73FF37D893) ]\r
+enum DNSSDRRClass\r
+{\r
+ kDNSSDClass_IN = 1\r
+} DNSSDRRClass;\r
+\r
+\r
+typedef [ uuid(08E362DF-5468-4c9a-AC66-FD4747B917BD) ]\r
+enum DNSSDRRType\r
+{\r
+ kDNSSDType_A = 1,
+ kDNSSDType_NS = 2,
+ kDNSSDType_MD = 3,
+ kDNSSDType_MF = 4,
+ kDNSSDType_CNAME = 5,
+ kDNSSDType_SOA = 6,
+ kDNSSDType_MB = 7,
+ kDNSSDType_MG = 8,
+ kDNSSDType_MR = 9,
+ kDNSSDType_NULL = 10,
+ kDNSSDType_WKS = 11,
+ kDNSSDType_PTR = 12,
+ kDNSSDType_HINFO = 13,
+ kDNSSDType_MINFO = 14,
+ kDNSSDType_MX = 15,
+ kDNSSDType_TXT = 16,
+ kDNSSDType_RP = 17,
+ kDNSSDType_AFSDB = 18,
+ kDNSSDType_X25 = 19,
+ kDNSSDType_ISDN = 20,
+ kDNSSDType_RT = 21,
+ kDNSSDType_NSAP = 22,
+ kDNSSDType_NSAP_PTR = 23,
+ kDNSSDType_SIG = 24,
+ kDNSSDType_KEY = 25,
+ kDNSSDType_PX = 26,
+ kDNSSDType_GPOS = 27,
+ kDNSSDType_AAAA = 28,
+ kDNSSDType_LOC = 29,
+ kDNSSDType_NXT = 30,
+ kDNSSDType_EID = 31,
+ kDNSSDType_NIMLOC = 32,
+ kDNSSDType_SRV = 33,
+ kDNSSDType_ATMA = 34,
+ kDNSSDType_NAPTR = 35,
+ kDNSSDType_KX = 36,
+ kDNSSDType_CERT = 37,
+ kDNSSDType_A6 = 38,
+ kDNSSDType_DNAME = 39,
+ kDNSSDType_SINK = 40,
+ kDNSSDType_OPT = 41,
+ kDNSSDType_APL = 42,
+ kDNSSDType_DS = 43,
+ kDNSSDType_SSHFP = 44,
+ kDNSSDType_IPSECKEY = 45,
+ kDNSSDType_RRSIG = 46,
+ kDNSSDType_NSEC = 47,
+ kDNSSDType_DNSKEY = 48,
+ kDNSSDType_DHCID = 49,
+ kDNSSDType_NSEC3 = 50,
+ kDNSSDType_NSEC3PARAM= 51,
+ kDNSSDType_HIP = 55,
+ kDNSSDType_SPF = 99,
+ kDNSSDType_UINFO = 100,
+ kDNSSDType_UID = 101,
+ kDNSSDType_GID = 102,
+ kDNSSDType_UNSPEC = 103,
+ kDNSSDType_TKEY = 249,
+ kDNSSDType_TSIG = 250,
+ kDNSSDType_IXFR = 251,
+ kDNSSDType_AXFR = 252,
+ kDNSSDType_MAILB = 253,
+ kDNSSDType_MAILA = 254,
+ kDNSSDType_ANY = 255\r
+} DNSSDRRType;\r
+\r
+\r
+typedef [ uuid(3B0059E7-5297-4301-9AAB-1522F31EC8A7) ]\r
+enum DNSSDError
+{
+ kDNSSDError_NoError = 0,
+ kDNSSDError_Unknown = -65537,
+ kDNSSDError_NoSuchName = -65538,
+ kDNSSDError_NoMemory = -65539,
+ kDNSSDError_BadParam = -65540,
+ kDNSSDError_BadReference = -65541,
+ kDNSSDError_BadState = -65542,
+ kDNSSDError_BadFlags = -65543,
+ kDNSSDError_Unsupported = -65544,
+ kDNSSDError_NotInitialized = -65545,
+ kDNSSDError_AlreadyRegistered = -65547,
+ kDNSSDError_NameConflict = -65548,
+ kDNSSDError_Invalid = -65549,
+ kDNSSDError_Firewall = -65550,
+ kDNSSDError_Incompatible = -65551,
+ kDNSSDError_BadInterfaceIndex = -65552,
+ kDNSSDError_Refused = -65553,
+ kDNSSDError_NoSuchRecord = -65554,
+ kDNSSDError_NoAuth = -65555,
+ kDNSSDError_NoSuchKey = -65556,
+ kDNSSDError_NATTraversal = -65557,
+ kDNSSDError_DoubleNAT = -65558,
+ kDNSSDError_BadTime = -65559,
+ kDNSSDError_BadSig = -65560,
+ kDNSSDError_BadKey = -65561,
+ kDNSSDError_Transient = -65562,
+ kDNSSDError_ServiceNotRunning = -65563, /* Background daemon not running */
+ kDNSSDError_NATPortMappingUnsupported = -65564, /* NAT doesn't support NAT-PMP or UPnP */
+ kDNSSDError_NATPortMappingDisabled = -65565, /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
+ kDNSSDError_NoRouter = -65566, /* No router currently configured (probably no network connectivity) */
+ kDNSSDError_PollingMode = -65567
+} DNSSDError;\r
+\r
+import "oaidl.idl";\r
+import "ocidl.idl";\r
+\r
+\r
+[\r
+ object,\r
+ uuid(8FA0889C-5973-4FC9-970B-EC15C925D0CE),\r
+ dual,\r
+ nonextensible,\r
+ helpstring("ITXTRecord Interface"),\r
+ pointer_default(unique)\r
+]\r
+interface ITXTRecord : IDispatch{\r
+ [id(1), helpstring("method SetValue")] HRESULT SetValue([in] BSTR key, [in] VARIANT value);\r
+ [id(2), helpstring("method RemoveValue")] HRESULT RemoveValue([in] BSTR key);\r
+ [id(3), helpstring("method ContainsKey")] HRESULT ContainsKey([in] BSTR key, [out,retval] VARIANT_BOOL* retval);\r
+ [id(4), helpstring("method GetValueForKey")] HRESULT GetValueForKey([in] BSTR key, [out,retval] VARIANT* value);\r
+ [id(5), helpstring("method GetCount")] HRESULT GetCount([out,retval] ULONG* count);\r
+ [id(6), helpstring("method GetKeyAtIndex")] HRESULT GetKeyAtIndex([in] ULONG index, [out,retval] BSTR* retval);\r
+ [id(7), helpstring("method GetValueAtIndex")] HRESULT GetValueAtIndex([in] ULONG index, [out,retval] VARIANT* retval);\r
+};\r
+[\r
+ object,\r
+ uuid(9CE603A0-3365-4DA0-86D1-3F780ECBA110),\r
+ dual,\r
+ nonextensible,\r
+ helpstring("IDNSSDRecord Interface"),\r
+ pointer_default(unique)\r
+]\r
+interface IDNSSDRecord : IDispatch{\r
+ [id(1), helpstring("method Update")] HRESULT Update([in] DNSSDFlags flags, [in] VARIANT rdata, [in] ULONG ttl);\r
+ [id(2), helpstring("method Remove")] HRESULT Remove([in] DNSSDFlags flags);\r
+};\r
+[\r
+ object,\r
+ uuid(7FD72324-63E1-45AD-B337-4D525BD98DAD),\r
+ dual,\r
+ nonextensible,\r
+ helpstring("IDNSSDEventManager Interface"),\r
+ pointer_default(unique)\r
+]\r
+interface IDNSSDEventManager : IDispatch{\r
+};\r
+[\r
+ object,\r
+ uuid(29DE265F-8402-474F-833A-D4653B23458F),\r
+ dual,\r
+ nonextensible,\r
+ helpstring("IDNSSDService Interface"),\r
+ pointer_default(unique)\r
+]\r
+interface IDNSSDService : IDispatch{\r
+ [id(1), helpstring("method EnumerateDomains")] HRESULT EnumerateDomains([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);\r
+ [id(2), helpstring("method Browse"), local] HRESULT Browse([in] DNSSDFlags flags, [in] ULONG interfaceIndex, [in] BSTR regtype, [in] BSTR domain, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** sdref);\r
+ [id(3), helpstring("method Resolve")] HRESULT Resolve([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR serviceName, [in] BSTR regType, [in] BSTR domain, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);\r
+ [id(4), helpstring("method Register")] HRESULT Register([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR name, [in] BSTR regType, [in] BSTR domain, [in] BSTR host, [in] USHORT port, [in] ITXTRecord* record, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);\r
+ [id(5), helpstring("method QueryRecord")] HRESULT QueryRecord([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullname, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);\r
+ [id(6), helpstring("method RegisterRecord")] HRESULT RegisterRecord([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullname, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] VARIANT rdata, [in] ULONG ttl, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDRecord** record);\r
+ [id(7), helpstring("method AddRecord")] HRESULT AddRecord([in] DNSSDFlags flags, [in] DNSSDRRType rrtype, [in] VARIANT rdata, [in] ULONG ttl, [out,retval] IDNSSDRecord** record);\r
+ [id(8), helpstring("method ReconfirmRecord")] HRESULT ReconfirmRecord([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullname, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] VARIANT rdata);\r
+ [id(9), helpstring("method GetProperty")] HRESULT GetProperty([in] BSTR prop, [in,out] VARIANT * value ); \r
+ [id(10), helpstring("method GetAddrInfo")] HRESULT GetAddrInfo([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] DNSSDAddressFamily addressFamily, [in] BSTR hostname, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);\r
+ [id(11), helpstring("method NATPortMappingCreate")] HRESULT NATPortMappingCreate([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] DNSSDAddressFamily addressFamily, [in] DNSSDProtocol protocol, [in] USHORT internalPort, [in] USHORT externalPort, [in] ULONG ttl, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);\r
+ [id(12), helpstring("method Stop"), local] HRESULT Stop(void);\r
+};\r
+[\r
+ uuid(18FBED6D-F2B7-4EC8-A4A4-46282E635308),\r
+ version(1.0),\r
+ helpstring("Apple Bonjour Library 1.0")\r
+]\r
+library Bonjour\r
+{\r
+ importlib("stdole2.tlb");\r
+ [\r
+ uuid(21AE8D7F-D5FE-45cf-B632-CFA2C2C6B498),\r
+ helpstring("_IDNSSDEvents Interface")\r
+ ]\r
+ dispinterface _IDNSSDEvents\r
+ {\r
+ properties:\r
+ methods:\r
+ [id(1), helpstring("method DomainFound")] void DomainFound([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR domain);\r
+ [id(2), helpstring("method DomainLost")] void DomainLost([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR domain);\r
+ [id(3), helpstring("method ServiceFound")] void ServiceFound([in] IDNSSDService* browser, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR serviceName, [in] BSTR regType, [in] BSTR domain);\r
+ [id(4), helpstring("method ServiceLost")] void ServiceLost([in] IDNSSDService* browser, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR serviceName, [in] BSTR regType, [in] BSTR domain);\r
+ [id(5), helpstring("method ServiceResolved")] void ServiceResolved([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullName, [in] BSTR hostName, [in] USHORT port, [in] ITXTRecord* record);\r
+ [id(6), helpstring("method ServiceRegistered")] void ServiceRegistered([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] BSTR name, [in] BSTR regType, [in] BSTR domain);\r
+ [id(7), helpstring("method QueryRecordAnswered")] void QueryRecordAnswered([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullName, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] VARIANT rdata, [in] ULONG ttl);\r
+ [id(8), helpstring("method RecordRegistered")] void RecordRegistered([in] IDNSSDRecord* record, [in] DNSSDFlags flags);\r
+ [id(9), helpstring("method AddressFound")] void AddressFound([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR hostname, [in] DNSSDAddressFamily addressFamily, [in] BSTR address, [in] ULONG ttl);\r
+ [id(10), helpstring("method MappingCreated")] void MappingCreated([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] ULONG externalAddress, [in] DNSSDAddressFamily addressFamily, [in] DNSSDProtocol protocol, [in] USHORT internalPort, [in] USHORT externalPort, [in] ULONG ttl);\r
+ [id(11), helpstring("method OperationFailed")] void OperationFailed([in] IDNSSDService* service, [in] DNSSDError error);\r
+ };\r
+ [\r
+ uuid(24CD4DE9-FF84-4701-9DC1-9B69E0D1090A),\r
+ helpstring("DNSSDService Class")\r
+ ]\r
+ coclass DNSSDService\r
+ {\r
+ [default] interface IDNSSDService;\r
+ };\r
+ [\r
+ uuid(AFEE063C-05BA-4248-A26E-168477F49734),\r
+ helpstring("TXTRecord Class")\r
+ ]\r
+ coclass TXTRecord\r
+ {\r
+ [default] interface ITXTRecord;\r
+ };\r
+ [\r
+ uuid(5E93C5A9-7516-4259-A67B-41A656F6E01C),\r
+ helpstring("DNSSDRecord Class")\r
+ ]\r
+ coclass DNSSDRecord\r
+ {\r
+ [default] interface IDNSSDRecord;\r
+ };\r
+ [\r
+ uuid(BEEB932A-8D4A-4619-AEFE-A836F988B221),\r
+ helpstring("DNSSDEventManager Class")\r
+ ]\r
+ coclass DNSSDEventManager\r
+ {\r
+ [default] interface IDNSSDEventManager;\r
+ [default, source] dispinterface _IDNSSDEvents;\r
+ };\r
+ enum DNSSDFlags;\r
+ enum DNSSDAddressFamily;\r
+ enum DNSSDProtocol;\r
+ enum DNSSDRRClass;\r
+ enum DNSSDRRType;\r
+ enum DNSSDError;\r
+};\r
--- /dev/null
+// Microsoft Visual C++ generated resource script.\r
+//\r
+#include "resource.h"\r
+\r
+#define APSTUDIO_READONLY_SYMBOLS\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 2 resource.\r
+//\r
+#include "winres.h"\r
+#include "WinVersRes.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#undef APSTUDIO_READONLY_SYMBOLS\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// English (U.S.) resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+1 TEXTINCLUDE \r
+BEGIN\r
+ "resource.h\0"\r
+END\r
+\r
+2 TEXTINCLUDE \r
+BEGIN\r
+ "#include ""winres.h""\r\n"\r
+ "#include ""WinVersRes.h""\r\n"\r
+ "\0"\r
+END\r
+\r
+3 TEXTINCLUDE \r
+BEGIN\r
+ "1 TYPELIB ""BonjourLib.tlb""\r\n"\r
+ "\0"\r
+END\r
+\r
+#endif // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Version\r
+//\r
+\r
+VS_VERSION_INFO VERSIONINFO\r
+ FILEVERSION MASTER_PROD_VERS\r
+ PRODUCTVERSION MASTER_PROD_VERS\r
+ FILEFLAGSMASK 0x3fL\r
+#ifdef _DEBUG\r
+ FILEFLAGS 0x1L\r
+#else\r
+ FILEFLAGS 0x0L\r
+#endif\r
+ FILEOS 0x4L\r
+ FILETYPE 0x2L\r
+ FILESUBTYPE 0x0L\r
+BEGIN\r
+ BLOCK "StringFileInfo"\r
+ BEGIN\r
+ BLOCK "040904e4"\r
+ BEGIN\r
+ VALUE "CompanyName", MASTER_COMPANY_NAME\r
+ VALUE "FileDescription", "Bonjour COM Component Library"\r
+ VALUE "FileVersion", MASTER_PROD_VERS_STR\r
+ VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT\r
+ VALUE "InternalName", "dnssdX.dll"\r
+ VALUE "OriginalFilename", "dnssdX.dll"\r
+ VALUE "ProductName", MASTER_PROD_NAME\r
+ VALUE "ProductVersion", MASTER_PROD_VERS_STR\r
+ END\r
+ END\r
+ BLOCK "VarFileInfo"\r
+ BEGIN\r
+ VALUE "Translation", 0x409, 1252\r
+ END\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// REGISTRY\r
+//\r
+\r
+IDR_DLLX REGISTRY "DLLX.rgs"\r
+IDR_DNSSDSERVICE REGISTRY "DNSSDService.rgs"\r
+IDR_TXTRECORD REGISTRY "TXTRecord.rgs"\r
+IDR_DNSSDRECORD REGISTRY "DNSSDRecord.rgs"\r
+IDR_DNSSDEVENTMANAGER REGISTRY "DNSSDEventManager.rgs"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// String Table\r
+//\r
+\r
+STRINGTABLE \r
+BEGIN\r
+ IDS_PROJNAME "BonjourLib"\r
+END\r
+\r
+#endif // English (U.S.) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+#ifndef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 3 resource.\r
+//\r
+1 TYPELIB "dnssdX.tlb"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#endif // not APSTUDIO_INVOKED\r
+\r
--- /dev/null
+HKCR\r
+{\r
+ NoRemove AppID\r
+ {\r
+ '%APPID%' = s 'Bonjour'\r
+ 'Bonjour.DLL'\r
+ {\r
+ val AppID = s '%APPID%'\r
+ }\r
+ }\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="8.00"\r
+ Name="DLLX"\r
+ ProjectGUID="{78FBFCC5-2873-4AE2-9114-A08082F71124}"\r
+ RootNamespace="DLLX"\r
+ Keyword="AtlProj"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ UseOfMFC="0"\r
+ UseOfATL="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="1"\r
+ GenerateStublessProxies="true"\r
+ TypeLibraryName="$(IntDir)/dnssdX.tlb"\r
+ HeaderFileName="DLLX.h"\r
+ DLLDataFileName=""\r
+ InterfaceIdentifierFileName="DLLX_i.c"\r
+ ProxyFileName="DLLX_p.c"\r
+ ValidateParameters="false"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;DEBUG=1;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="..;"$(IntDir)""\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ RegisterOutput="true"\r
+ IgnoreImportLibrary="true"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"\r
+ OutputFile="$(OutDir)\dnssdX.dll"\r
+ LinkIncremental="2"\r
+ ModuleDefinitionFile=".\DLLX.def"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ UseOfMFC="0"\r
+ UseOfATL="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ GenerateStublessProxies="true"\r
+ TypeLibraryName="$(IntDir)/dnssdX.tlb"\r
+ HeaderFileName="DLLX.h"\r
+ DLLDataFileName=""\r
+ InterfaceIdentifierFileName="DLLX_i.c"\r
+ ProxyFileName="DLLX_p.c"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;DEBUG=1;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="_DEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="..;"$(IntDir)""\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ RegisterOutput="true"\r
+ IgnoreImportLibrary="true"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"\r
+ OutputFile="$(OutDir)\dnssdX.dll"\r
+ LinkIncremental="2"\r
+ ModuleDefinitionFile=".\DLLX.def"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ UseOfATL="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="1"\r
+ GenerateStublessProxies="true"\r
+ TypeLibraryName="$(IntDir)/dnssdX.tlb"\r
+ HeaderFileName="DLLX.h"\r
+ DLLDataFileName=""\r
+ InterfaceIdentifierFileName="DLLX_i.c"\r
+ ProxyFileName="DLLX_p.c"\r
+ ValidateParameters="false"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL;_MERGE_PROXYSTUB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="..;"$(IntDir)""\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ RegisterOutput="true"\r
+ IgnoreImportLibrary="true"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"\r
+ OutputFile="$(OutDir)\dnssdX.dll"\r
+ LinkIncremental="1"\r
+ ModuleDefinitionFile=".\DLLX.def"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ UseOfATL="1"\r
+ ATLMinimizesCRunTimeLibraryUsage="false"\r
+ CharacterSet="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ MkTypLibCompatible="false"\r
+ TargetEnvironment="3"\r
+ GenerateStublessProxies="true"\r
+ TypeLibraryName="$(IntDir)/dnssdX.tlb"\r
+ HeaderFileName="DLLX.h"\r
+ DLLDataFileName=""\r
+ InterfaceIdentifierFileName="DLLX_i.c"\r
+ ProxyFileName="DLLX_p.c"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="2"\r
+ AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL;_MERGE_PROXYSTUB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ PreprocessorDefinitions="NDEBUG"\r
+ Culture="1033"\r
+ AdditionalIncludeDirectories="..;"$(IntDir)""\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ RegisterOutput="true"\r
+ IgnoreImportLibrary="true"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"\r
+ OutputFile="$(OutDir)\dnssdX.dll"\r
+ LinkIncremental="1"\r
+ ModuleDefinitionFile=".\DLLX.def"\r
+ GenerateDebugInformation="true"\r
+ SubSystem="2"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath=".\dlldatax.c"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\DLLX.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DLLX.def"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DLLX.idl"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDEventManager.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDRecord.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDService.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\TXTRecord.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath=".\_IDNSSDEvents_CP.H"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\dlldatax.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDEventManager.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDRecord.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDService.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\Resource.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\stdafx.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\TXTRecord.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ <File\r
+ RelativePath=".\DLLX.rc"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DLLX.rgs"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDEventManager.rgs"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDRecord.rgs"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DNSSDService.rgs"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\TXTRecord.rgs"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Generated Files"\r
+ SourceControlFiles="false"\r
+ >\r
+ <File\r
+ RelativePath=".\DLLX.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\DLLX_i.c"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Debug|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|x64"\r
+ >\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ UsePrecompiledHeader="0"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Support Files"\r
+ >\r
+ <File\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\StringServices.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\StringServices.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r
--- /dev/null
+// DNSSD.cpp : Implementation of CDNSSD\r
+\r
+#include "stdafx.h"\r
+#include "DNSSD.h"\r
+#include "DNSSDService.h"\r
+#include "TXTRecord.h"\r
+#include <dns_sd.h>\r
+#include <CommonServices.h>\r
+#include <DebugServices.h>\r
+#include "StringServices.h"\r
+\r
+\r
+// CDNSSD\r
+\r
+STDMETHODIMP CDNSSD::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IBrowseListener* listener, IDNSSDService** browser )\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string regtypeUTF8;\r
+ std::string domainUTF8;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *browser = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( regtype, regtypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceBrowse( &sref, flags, ifIndex, regtypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceBrowseReply ) &BrowseReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *browser = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IResolveListener* listener, IDNSSDService** service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string serviceNameUTF8;\r
+ std::string regTypeUTF8;\r
+ std::string domainUTF8;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( serviceName, serviceNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( regType, regTypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceResolve( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDomainListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceEnumerateDomains( &sref, flags, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IRegisterListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string serviceNameUTF8;\r
+ std::string regTypeUTF8;\r
+ std::string domainUTF8;\r
+ std::string hostUTF8;\r
+ const void * txtRecord = NULL;\r
+ uint16_t txtLen = 0;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( serviceName, serviceNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( regType, regTypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( host, hostUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ if ( record )\r
+ {\r
+ CComObject< CTXTRecord > * realTXTRecord;\r
+\r
+ realTXTRecord = ( CComObject< CTXTRecord >* ) record;\r
+\r
+ txtRecord = realTXTRecord->GetBytes();\r
+ txtLen = realTXTRecord->GetLen();\r
+ }\r
+\r
+ err = DNSServiceRegister( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), hostUTF8.c_str(), port, txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IQueryRecordListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ std::string fullNameUTF8;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( fullname, fullNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceQueryRecord( &sref, flags, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IGetAddrInfoListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ std::string hostNameUTF8;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( hostName, hostNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceGetAddrInfo( &sref, flags, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::CreateConnection(IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceCreateConnection( &sref );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, INATPortMappingListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceProtocol prot = 0;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ prot = ( addressFamily | protocol );\r
+\r
+ err = DNSServiceNATPortMappingCreate( &sref, flags, ifIndex, prot, internalPort, externalPort, ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::GetProperty(BSTR prop, VARIANT * value )\r
+{\r
+ std::string propUTF8;\r
+ std::vector< BYTE > byteArray;\r
+ SAFEARRAY * psa = NULL;\r
+ BYTE * pData = NULL;\r
+ uint32_t elems = 0;\r
+ DNSServiceErrorType err = 0;\r
+ BOOL ok = TRUE;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( prop, propUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ // Setup the byte array\r
+ require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );\r
+ psa = V_ARRAY( value );\r
+ require_action( psa, exit, err = kDNSServiceErr_Unknown );\r
+ require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );\r
+ byteArray.reserve( psa->rgsabound[0].cElements );\r
+ byteArray.assign( byteArray.capacity(), 0 );\r
+ elems = ( uint32_t ) byteArray.capacity();\r
+\r
+ // Call the function and package the return value in the Variant\r
+ err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );\r
+ require_noerr( err, exit );\r
+ ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );\r
+ require_action( ok, exit, err = kDNSSDError_Unknown );\r
+\r
+exit:\r
+\r
+ if ( psa )\r
+ {\r
+ SafeArrayUnaccessData( psa );\r
+ psa = NULL;\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::DomainEnumReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *replyDomainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IDomainListener * listener;\r
+\r
+ listener = ( IDomainListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR replyDomain;\r
+ \r
+ UTF8ToBSTR( replyDomainUTF8, replyDomain );\r
+\r
+ if ( flags & kDNSServiceFlagsAdd )\r
+ {\r
+ listener->DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );\r
+ }\r
+ else\r
+ {\r
+ listener->DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ listener->EnumDomainsFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::BrowseReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *serviceNameUTF8,
+ const char *regTypeUTF8,
+ const char *replyDomainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IBrowseListener * listener;\r
+\r
+ listener = ( IBrowseListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR serviceName;\r
+ CComBSTR regType;\r
+ CComBSTR replyDomain;\r
+ \r
+ UTF8ToBSTR( serviceNameUTF8, serviceName );\r
+ UTF8ToBSTR( regTypeUTF8, regType );\r
+ UTF8ToBSTR( replyDomainUTF8, replyDomain );\r
+\r
+ if ( flags & kDNSServiceFlagsAdd )\r
+ {\r
+ listener->ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );\r
+ }\r
+ else\r
+ {\r
+ listener->ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ listener->BrowseFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API\r
+CDNSSD::ResolveReply\r
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullNameUTF8,
+ const char *hostNameUTF8,
+ uint16_t port,
+ uint16_t txtLen,
+ const unsigned char *txtRecord,
+ void *context\r
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IResolveListener * listener;\r
+\r
+ listener = ( IResolveListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR fullName;\r
+ CComBSTR hostName;\r
+ CComBSTR regType;\r
+ CComBSTR replyDomain;\r
+ CComObject< CTXTRecord >* record;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( fullNameUTF8, fullName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( hostNameUTF8, hostName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ try\r
+ {\r
+ record = new CComObject<CTXTRecord>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ record = NULL;\r
+ }\r
+\r
+ require_action( record, exit, err = kDNSServiceErr_NoMemory );\r
+ record->AddRef();\r
+\r
+ char buf[ 64 ];\r
+ sprintf( buf, "txtLen = %d", txtLen );\r
+ OutputDebugStringA( buf );\r
+\r
+ if ( txtLen > 0 )\r
+ {\r
+ record->SetBytes( txtRecord, txtLen );\r
+ }\r
+\r
+ listener->ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, port, record );\r
+ }\r
+ else\r
+ {\r
+ listener->ResolveFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::RegisterReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ const char *serviceNameUTF8,
+ const char *regTypeUTF8,
+ const char *domainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IRegisterListener * listener;\r
+\r
+ listener = ( IRegisterListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR serviceName;\r
+ CComBSTR regType;\r
+ CComBSTR domain;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( serviceNameUTF8, serviceName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( regTypeUTF8, regType );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( domainUTF8, domain );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ listener->ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );\r
+ }\r
+ else\r
+ {\r
+ listener->ServiceRegisterFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::QueryRecordReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullNameUTF8,
+ uint16_t rrtype,
+ uint16_t rrclass,
+ uint16_t rdlen,
+ const void *rdata,
+ uint32_t ttl,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IQueryRecordListener * listener;\r
+\r
+ listener = ( IQueryRecordListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR fullName;\r
+ VARIANT var;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( fullNameUTF8, fullName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = ByteArrayToVariant( rdata, rdlen, &var );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ listener->QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );\r
+ }\r
+ else\r
+ {\r
+ listener->QueryRecordFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::GetAddrInfoReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *hostNameUTF8,
+ const struct sockaddr *rawAddress,
+ uint32_t ttl,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IGetAddrInfoListener * listener;\r
+\r
+ listener = ( IGetAddrInfoListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR hostName;\r
+ DWORD sockaddrLen;\r
+ DNSSDAddressFamily addressFamily;\r
+ char addressUTF8[INET6_ADDRSTRLEN];\r
+ DWORD addressLen = sizeof( addressUTF8 );\r
+ CComBSTR address;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( hostNameUTF8, hostName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ switch ( rawAddress->sa_family )\r
+ {\r
+ case AF_INET:\r
+ {\r
+ addressFamily = kDNSSDAddressFamily_IPv4;\r
+ sockaddrLen = sizeof( sockaddr_in );\r
+ }\r
+ break;\r
+\r
+ case AF_INET6:\r
+ {\r
+ addressFamily = kDNSSDAddressFamily_IPv6;\r
+ sockaddrLen = sizeof( sockaddr_in6 );\r
+ }\r
+ break;\r
+ }\r
+\r
+ err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );\r
+ require_noerr( err, exit );\r
+ ok = UTF8ToBSTR( addressUTF8, address );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ listener->GetAddrInfoReply( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );\r
+ }\r
+ else\r
+ {\r
+ listener->GetAddrInfoFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::NATPortMappingReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ uint32_t externalAddress, /* four byte IPv4 address in network byte order */
+ DNSServiceProtocol protocol,
+ uint16_t internalPort,
+ uint16_t externalPort, /* may be different than the requested port */
+ uint32_t ttl, /* may be different than the requested ttl */
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ INATPortMappingListener * listener;\r
+\r
+ listener = ( INATPortMappingListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ listener->MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), internalPort, externalPort, ttl );\r
+ }\r
+ else\r
+ {\r
+ listener->MappingFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DNSSDEventManager.cpp,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#include "stdafx.h"\r
+#include "DNSSDEventManager.h"\r
+\r
+\r
+// CDNSSDEventManager\r
+\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DNSSDEventManager.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma once\r
+#include "resource.h" // main symbols\r
+\r
+#include "DLLX.h"\r
+#include "_IDNSSDEvents_CP.H"\r
+\r
+\r
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)\r
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."\r
+#endif\r
+\r
+\r
+\r
+// CDNSSDEventManager\r
+\r
+class ATL_NO_VTABLE CDNSSDEventManager :\r
+ public CComObjectRootEx<CComSingleThreadModel>,\r
+ public CComCoClass<CDNSSDEventManager, &CLSID_DNSSDEventManager>,\r
+ public IConnectionPointContainerImpl<CDNSSDEventManager>,\r
+ public CProxy_IDNSSDEvents<CDNSSDEventManager>,\r
+ public IDispatchImpl<IDNSSDEventManager, &IID_IDNSSDEventManager, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>\r
+{\r
+public:\r
+ CDNSSDEventManager()\r
+ {\r
+ }\r
+\r
+DECLARE_REGISTRY_RESOURCEID(IDR_DNSSDEVENTMANAGER)\r
+\r
+\r
+BEGIN_COM_MAP(CDNSSDEventManager)\r
+ COM_INTERFACE_ENTRY(IDNSSDEventManager)\r
+ COM_INTERFACE_ENTRY(IDispatch)\r
+ COM_INTERFACE_ENTRY(IConnectionPointContainer)\r
+END_COM_MAP()\r
+\r
+BEGIN_CONNECTION_POINT_MAP(CDNSSDEventManager)\r
+ CONNECTION_POINT_ENTRY(__uuidof(_IDNSSDEvents))\r
+END_CONNECTION_POINT_MAP()\r
+\r
+\r
+ DECLARE_PROTECT_FINAL_CONSTRUCT()\r
+\r
+ HRESULT FinalConstruct()\r
+ {\r
+ return S_OK;\r
+ }\r
+\r
+ void FinalRelease()\r
+ {\r
+ }\r
+\r
+public:\r
+\r
+};\r
+\r
+OBJECT_ENTRY_AUTO(__uuidof(DNSSDEventManager), CDNSSDEventManager)\r
--- /dev/null
+HKCR\r
+{\r
+ Bonjour.DNSSDEventManager.1 = s 'DNSSDEventManager Class'\r
+ {\r
+ CLSID = s '{BEEB932A-8D4A-4619-AEFE-A836F988B221}'\r
+ }\r
+ Bonjour.DNSSDEventManager = s 'DNSSDEventManager Class'\r
+ {\r
+ CLSID = s '{BEEB932A-8D4A-4619-AEFE-A836F988B221}'\r
+ CurVer = s 'Bonjour.DNSSDEventManager.1'\r
+ }\r
+ NoRemove CLSID\r
+ {\r
+ ForceRemove {BEEB932A-8D4A-4619-AEFE-A836F988B221} = s 'DNSSDEventManager Class'\r
+ {\r
+ ProgID = s 'Bonjour.DNSSDEventManager.1'\r
+ VersionIndependentProgID = s 'Bonjour.DNSSDEventManager'\r
+ ForceRemove 'Programmable'\r
+ InprocServer32 = s '%MODULE%'\r
+ {\r
+ val ThreadingModel = s 'Apartment'\r
+ }\r
+ val AppID = s '%APPID%'\r
+ 'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DNSSDRecord.cpp,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#include "stdafx.h"\r
+#include "DNSSDRecord.h"\r
+#include "StringServices.h"\r
+#include <DebugServices.h>\r
+\r
+\r
+// CDNSSDRecord\r
+\r
+STDMETHODIMP CDNSSDRecord::Update(DNSSDFlags flags, VARIANT rdata, ULONG ttl)\r
+{\r
+ std::vector< BYTE > byteArray;\r
+ const void * byteArrayPtr = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Convert the VARIANT\r
+ ok = VariantToByteArray( &rdata, byteArray );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ err = DNSServiceUpdateRecord( m_serviceObject->GetSubordRef(), m_rref, flags, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl );\r
+ require_noerr( err, exit );\r
+\r
+exit:\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDRecord::Remove(DNSSDFlags flags)\r
+{\r
+ DNSServiceErrorType err = 0;\r
+\r
+ err = DNSServiceRemoveRecord( m_serviceObject->GetSubordRef(), m_rref, flags );\r
+ require_noerr( err, exit );\r
+\r
+exit:\r
+\r
+ return err;\r
+}\r
+\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DNSSDRecord.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma once\r
+#include "resource.h" // main symbols\r
+\r
+#include "DLLX.h"\r
+#include "DNSSDService.h"\r
+#include <dns_sd.h>\r
+\r
+\r
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)\r
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."\r
+#endif\r
+\r
+\r
+\r
+// CDNSSDRecord\r
+\r
+class ATL_NO_VTABLE CDNSSDRecord :\r
+ public CComObjectRootEx<CComSingleThreadModel>,\r
+ public CComCoClass<CDNSSDRecord, &CLSID_DNSSDRecord>,\r
+ public IDispatchImpl<IDNSSDRecord, &IID_IDNSSDRecord, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>\r
+{\r
+public:\r
+ CDNSSDRecord()\r
+ {\r
+ }\r
+\r
+DECLARE_REGISTRY_RESOURCEID(IDR_DNSSDRECORD)\r
+\r
+\r
+BEGIN_COM_MAP(CDNSSDRecord)\r
+ COM_INTERFACE_ENTRY(IDNSSDRecord)\r
+ COM_INTERFACE_ENTRY(IDispatch)\r
+END_COM_MAP()\r
+\r
+\r
+\r
+ DECLARE_PROTECT_FINAL_CONSTRUCT()\r
+\r
+ HRESULT FinalConstruct()\r
+ {\r
+ return S_OK;\r
+ }\r
+\r
+ void FinalRelease()\r
+ {\r
+ }\r
+\r
+ inline CDNSSDService*\r
+ GetServiceObject()\r
+ {\r
+ return m_serviceObject;\r
+ }\r
+\r
+ inline void\r
+ SetServiceObject( CDNSSDService * serviceObject )\r
+ {\r
+ m_serviceObject = serviceObject;\r
+ }\r
+\r
+ inline DNSRecordRef\r
+ GetRecordRef()\r
+ {\r
+ return m_rref;\r
+ }\r
+\r
+ inline void\r
+ SetRecordRef( DNSRecordRef rref )\r
+ {\r
+ m_rref = rref;\r
+ }\r
+\r
+public:\r
+\r
+ STDMETHOD(Update)(DNSSDFlags flags, VARIANT rdata, ULONG ttl);\r
+ STDMETHOD(Remove)(DNSSDFlags flags);\r
+\r
+private:\r
+\r
+ CDNSSDService * m_serviceObject;\r
+ DNSRecordRef m_rref;\r
+};\r
+\r
+OBJECT_ENTRY_AUTO(__uuidof(DNSSDRecord), CDNSSDRecord)\r
--- /dev/null
+HKCR\r
+{\r
+ Bonjour.DNSSDRecord.1 = s 'DNSSDRecord Class'\r
+ {\r
+ CLSID = s '{5E93C5A9-7516-4259-A67B-41A656F6E01C}'\r
+ }\r
+ Bonjour.DNSSDRecord = s 'DNSSDRecord Class'\r
+ {\r
+ CLSID = s '{5E93C5A9-7516-4259-A67B-41A656F6E01C}'\r
+ CurVer = s 'Bonjour.DNSSDRecord.1'\r
+ }\r
+ NoRemove CLSID\r
+ {\r
+ ForceRemove {5E93C5A9-7516-4259-A67B-41A656F6E01C} = s 'DNSSDRecord Class'\r
+ {\r
+ ProgID = s 'Bonjour.DNSSDRecord.1'\r
+ VersionIndependentProgID = s 'Bonjour.DNSSDRecord'\r
+ ForceRemove 'Programmable'\r
+ InprocServer32 = s '%MODULE%'\r
+ {\r
+ val ThreadingModel = s 'Apartment'\r
+ }\r
+ val AppID = s '%APPID%'\r
+ 'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DNSSDService.cpp,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma warning(disable:4995)\r
+\r
+#include "stdafx.h"\r
+#include <strsafe.h>\r
+#include "DNSSDService.h"\r
+#include "DNSSDEventManager.h"\r
+#include "DNSSDRecord.h"\r
+#include "TXTRecord.h"\r
+#include "StringServices.h"\r
+#include <DebugServices.h>\r
+\r
+\r
+#define WM_SOCKET (WM_APP + 100)\r
+\r
+\r
+// CDNSSDService\r
+\r
+BOOL CDNSSDService::m_registeredWindowClass = FALSE;\r
+HWND CDNSSDService::m_hiddenWindow = NULL;\r
+CDNSSDService::SocketMap CDNSSDService::m_socketMap;\r
+\r
+\r
+HRESULT CDNSSDService::FinalConstruct()\r
+{\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = S_OK;\r
+\r
+ m_isPrimary = TRUE;\r
+ err = DNSServiceCreateConnection( &m_primary );\r
+ require_action( !err, exit, hr = E_FAIL );\r
+\r
+ if ( !m_hiddenWindow )\r
+ {\r
+ TCHAR windowClassName[ 256 ];\r
+\r
+ StringCchPrintf( windowClassName, sizeof( windowClassName ) / sizeof( TCHAR ), TEXT( "Bonjour Hidden Window %d" ), GetProcessId( NULL ) );\r
+\r
+ if ( !m_registeredWindowClass )\r
+ {\r
+ WNDCLASS wc;\r
+ ATOM atom;\r
+\r
+ wc.style = 0;\r
+ wc.lpfnWndProc = WndProc;\r
+ wc.cbClsExtra = 0;\r
+ wc.cbWndExtra = 0;\r
+ wc.hInstance = NULL;\r
+ wc.hIcon = NULL;\r
+ wc.hCursor = NULL;\r
+ wc.hbrBackground = NULL;\r
+ wc.lpszMenuName = NULL;\r
+ wc.lpszClassName = windowClassName;\r
+\r
+ atom = RegisterClass(&wc);\r
+ require_action( atom != NULL, exit, hr = E_FAIL );\r
+\r
+ m_registeredWindowClass = TRUE;\r
+ }\r
+\r
+ m_hiddenWindow = CreateWindow( windowClassName, windowClassName, WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL, GetModuleHandle( NULL ), NULL );\r
+ require_action( m_hiddenWindow != NULL, exit, hr = E_FAIL );\r
+ }\r
+\r
+ err = WSAAsyncSelect( DNSServiceRefSockFD( m_primary ), m_hiddenWindow, WM_SOCKET, FD_READ );\r
+ require_action( !err, exit, hr = E_FAIL );\r
+\r
+ m_socketMap[ DNSServiceRefSockFD( m_primary ) ] = this;\r
+\r
+exit:\r
+\r
+ return hr;\r
+}\r
+\r
+\r
+void CDNSSDService::FinalRelease()\r
+{\r
+ dlog( kDebugLevelTrace, "FinalRelease()\n" ); \r
+ Stop();\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDNSSDEventManager *eventManager, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef subord = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceEnumerateDomains( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service )\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string regtypeUTF8;\r
+ std::string domainUTF8;\r
+ DNSServiceRef subord = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( regtype, regtypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceBrowse( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, regtypeUTF8.c_str(), ( domainUTF8.size() > 0 ) ? domainUTF8.c_str() : NULL, ( DNSServiceBrowseReply ) &BrowseReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string serviceNameUTF8;\r
+ std::string regTypeUTF8;\r
+ std::string domainUTF8;\r
+ DNSServiceRef subord = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( serviceName, serviceNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( regType, regTypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceResolve( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IDNSSDEventManager *eventManager, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string serviceNameUTF8;\r
+ std::string regTypeUTF8;\r
+ std::string domainUTF8;\r
+ std::string hostUTF8;\r
+ const void * txtRecord = NULL;\r
+ uint16_t txtLen = 0;\r
+ DNSServiceRef subord = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( serviceName, serviceNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( regType, regTypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( host, hostUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ if ( record )\r
+ {\r
+ CComObject< CTXTRecord > * realTXTRecord;\r
+\r
+ realTXTRecord = ( CComObject< CTXTRecord >* ) record;\r
+\r
+ txtRecord = realTXTRecord->GetBytes();\r
+ txtLen = realTXTRecord->GetLen();\r
+ }\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceRegister( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), ( domainUTF8.size() > 0 ) ? domainUTF8.c_str() : NULL, hostUTF8.c_str(), htons( port ), txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IDNSSDEventManager *eventManager, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef subord = NULL;\r
+ std::string fullNameUTF8;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( fullname, fullNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceQueryRecord( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::RegisterRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata, ULONG ttl, IDNSSDEventManager* eventManager, IDNSSDRecord** record)\r
+{\r
+ CComObject<CDNSSDRecord> * object = NULL;\r
+ DNSRecordRef rref = NULL;\r
+ std::string fullNameUTF8;\r
+ std::vector< BYTE > byteArray;\r
+ const void * byteArrayPtr = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *object = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( fullName, fullNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ // Convert the VARIANT\r
+ ok = VariantToByteArray( &rdata, byteArray );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDRecord>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceRegisterRecord( m_primary, &rref, flags, ifIndex, fullNameUTF8.c_str(), rrtype, rrclass, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl, &RegisterRecordReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceObject( this );\r
+ object->SetRecordRef( rref );\r
+ this->SetEventManager( eventManager );\r
+\r
+ *record = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::AddRecord(DNSSDFlags flags, DNSSDRRType rrtype, VARIANT rdata, ULONG ttl, IDNSSDRecord ** record)\r
+{\r
+ CComObject<CDNSSDRecord> * object = NULL;\r
+ DNSRecordRef rref = NULL;\r
+ std::vector< BYTE > byteArray;\r
+ const void * byteArrayPtr = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *object = NULL;\r
+\r
+ // Convert the VARIANT\r
+ ok = VariantToByteArray( &rdata, byteArray );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDRecord>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceAddRecord( m_primary, &rref, flags, rrtype, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceObject( this );\r
+ object->SetRecordRef( rref );\r
+\r
+ *record = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+STDMETHODIMP CDNSSDService::ReconfirmRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata)\r
+{\r
+ std::string fullNameUTF8;\r
+ std::vector< BYTE > byteArray;\r
+ const void * byteArrayPtr = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( fullName, fullNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ // Convert the VARIANT\r
+ ok = VariantToByteArray( &rdata, byteArray );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ err = DNSServiceReconfirmRecord( flags, ifIndex, fullNameUTF8.c_str(), rrtype, rrclass, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL );\r
+ require_noerr( err, exit );\r
+\r
+exit:\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::GetProperty(BSTR prop, VARIANT * value )\r
+{\r
+ std::string propUTF8;\r
+ std::vector< BYTE > byteArray;\r
+ SAFEARRAY * psa = NULL;\r
+ BYTE * pData = NULL;\r
+ uint32_t elems = 0;\r
+ DNSServiceErrorType err = 0;\r
+ BOOL ok = TRUE;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( prop, propUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ // Setup the byte array\r
+ require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );\r
+ psa = V_ARRAY( value );\r
+ require_action( psa, exit, err = kDNSServiceErr_Unknown );\r
+ require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );\r
+ byteArray.reserve( psa->rgsabound[0].cElements );\r
+ byteArray.assign( byteArray.capacity(), 0 );\r
+ elems = ( uint32_t ) byteArray.capacity();\r
+\r
+ // Call the function and package the return value in the Variant\r
+ err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );\r
+ require_noerr( err, exit );\r
+ ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );\r
+ require_action( ok, exit, err = kDNSSDError_Unknown );\r
+\r
+exit:\r
+\r
+ if ( psa )\r
+ {\r
+ SafeArrayUnaccessData( psa );\r
+ psa = NULL;\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+STDMETHODIMP CDNSSDService::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IDNSSDEventManager *eventManager, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef subord = NULL;\r
+ std::string hostNameUTF8;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( hostName, hostNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceGetAddrInfo( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, IDNSSDEventManager *eventManager, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef subord = NULL;\r
+ DNSServiceProtocol prot = 0;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ check( m_primary );\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ object->AddRef();\r
+\r
+ prot = ( addressFamily | protocol );\r
+\r
+ subord = m_primary;\r
+ err = DNSServiceNATPortMappingCreate( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, prot, htons( internalPort ), htons( externalPort ), ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetPrimaryRef( m_primary );\r
+ object->SetSubordRef( subord );\r
+ object->SetEventManager( eventManager );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSDService::Stop(void)\r
+{\r
+ if ( !m_stopped )\r
+ {\r
+ m_stopped = TRUE;\r
+\r
+ dlog( kDebugLevelTrace, "Stop()\n" );\r
+\r
+ if ( m_isPrimary && m_primary )\r
+ {\r
+ SocketMap::iterator it;\r
+\r
+ if ( m_hiddenWindow )\r
+ {\r
+ WSAAsyncSelect( DNSServiceRefSockFD( m_primary ), m_hiddenWindow, 0, 0 );\r
+ }\r
+\r
+ it = m_socketMap.find( DNSServiceRefSockFD( m_primary ) );\r
+\r
+ if ( it != m_socketMap.end() )\r
+ {\r
+ m_socketMap.erase( it );\r
+ }\r
+\r
+ DNSServiceRefDeallocate( m_primary );\r
+ m_primary = NULL;\r
+ }\r
+ else if ( m_subord )\r
+ {\r
+ DNSServiceRefDeallocate( m_subord );\r
+ m_subord = NULL;\r
+ }\r
+\r
+ if ( m_eventManager != NULL )\r
+ {\r
+ m_eventManager->Release();\r
+ m_eventManager = NULL;\r
+ }\r
+ }\r
+\r
+ return S_OK;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::DomainEnumReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *replyDomainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ CComBSTR replyDomain;\r
+ BOOL ok;\r
+ \r
+ ok = UTF8ToBSTR( replyDomainUTF8, replyDomain );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( flags & kDNSServiceFlagsAdd )\r
+ {\r
+ eventManager->Fire_DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );\r
+ }\r
+ else\r
+ {\r
+ eventManager->Fire_DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::BrowseReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *serviceNameUTF8,
+ const char *regTypeUTF8,
+ const char *replyDomainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ CComBSTR serviceName;\r
+ CComBSTR regType;\r
+ CComBSTR replyDomain;\r
+ \r
+ UTF8ToBSTR( serviceNameUTF8, serviceName );\r
+ UTF8ToBSTR( regTypeUTF8, regType );\r
+ UTF8ToBSTR( replyDomainUTF8, replyDomain );\r
+\r
+ if ( flags & kDNSServiceFlagsAdd )\r
+ {\r
+ eventManager->Fire_ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );\r
+ }\r
+ else\r
+ {\r
+ eventManager->Fire_ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API\r
+CDNSSDService::ResolveReply\r
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullNameUTF8,
+ const char *hostNameUTF8,
+ uint16_t port,
+ uint16_t txtLen,
+ const unsigned char *txtRecord,
+ void *context\r
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ CComBSTR fullName;\r
+ CComBSTR hostName;\r
+ CComBSTR regType;\r
+ CComBSTR replyDomain;\r
+ CComObject< CTXTRecord >* record;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( fullNameUTF8, fullName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( hostNameUTF8, hostName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ try\r
+ {\r
+ record = new CComObject<CTXTRecord>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ record = NULL;\r
+ }\r
+\r
+ require_action( record, exit, err = kDNSServiceErr_NoMemory );\r
+ record->AddRef();\r
+\r
+ if ( txtLen > 0 )\r
+ {\r
+ record->SetBytes( txtRecord, txtLen );\r
+ }\r
+\r
+ eventManager->Fire_ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, ntohs( port ), record );\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::RegisterReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ const char *serviceNameUTF8,
+ const char *regTypeUTF8,
+ const char *domainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ CComBSTR serviceName;\r
+ CComBSTR regType;\r
+ CComBSTR domain;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( serviceNameUTF8, serviceName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( regTypeUTF8, regType );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( domainUTF8, domain );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ eventManager->Fire_ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::QueryRecordReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullNameUTF8,
+ uint16_t rrtype,
+ uint16_t rrclass,
+ uint16_t rdlen,
+ const void *rdata,
+ uint32_t ttl,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ CComBSTR fullName;\r
+ VARIANT var;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( fullNameUTF8, fullName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = ByteArrayToVariant( rdata, rdlen, &var );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ eventManager->Fire_QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::GetAddrInfoReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *hostNameUTF8,
+ const struct sockaddr *rawAddress,
+ uint32_t ttl,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ CComBSTR hostName;\r
+ DWORD sockaddrLen;\r
+ DNSSDAddressFamily addressFamily;\r
+ char addressUTF8[INET6_ADDRSTRLEN];\r
+ DWORD addressLen = sizeof( addressUTF8 );\r
+ CComBSTR address;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( hostNameUTF8, hostName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ switch ( rawAddress->sa_family )\r
+ {\r
+ case AF_INET:\r
+ {\r
+ addressFamily = kDNSSDAddressFamily_IPv4;\r
+ sockaddrLen = sizeof( sockaddr_in );\r
+ }\r
+ break;\r
+\r
+ case AF_INET6:\r
+ {\r
+ addressFamily = kDNSSDAddressFamily_IPv6;\r
+ sockaddrLen = sizeof( sockaddr_in6 );\r
+ }\r
+ break;\r
+ }\r
+\r
+ err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );\r
+ require_noerr( err, exit );\r
+ ok = UTF8ToBSTR( addressUTF8, address );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ eventManager->Fire_AddressFound( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::NATPortMappingReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ uint32_t externalAddress, /* four byte IPv4 address in network byte order */
+ DNSServiceProtocol protocol,
+ uint16_t internalPort,
+ uint16_t externalPort, /* may be different than the requested port */
+ uint32_t ttl, /* may be different than the requested ttl */
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ eventManager->Fire_MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), ntohs( internalPort ), ntohs( externalPort ), ttl );\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSDService::RegisterRecordReply
+ (
+ DNSServiceRef sdRef,
+ DNSRecordRef RecordRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDRecord> * record = NULL;\r
+ CDNSSDService * service = NULL;\r
+ CDNSSDEventManager * eventManager = NULL;\r
+ int err = 0;\r
+ \r
+ record = ( CComObject< CDNSSDRecord >* ) context;\r
+ require_action( record, exit, err = kDNSServiceErr_Unknown );\r
+ service = record->GetServiceObject();\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( service->ShouldHandleReply( errorCode, eventManager ) )\r
+ {\r
+ eventManager->Fire_RecordRegistered( record, ( DNSSDFlags ) flags );\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+BOOL\r
+CDNSSDService::ShouldHandleReply( DNSServiceErrorType errorCode, CDNSSDEventManager *& eventManager )\r
+{\r
+ BOOL ok = FALSE;\r
+\r
+ if ( !this->Stopped() )\r
+ {\r
+ eventManager = this->GetEventManager();\r
+ require_action( eventManager, exit, ok = FALSE );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ ok = TRUE;\r
+ }\r
+ else\r
+ {\r
+ eventManager->Fire_OperationFailed( this, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return ok;\r
+}\r
+\r
+\r
+LRESULT CALLBACK\r
+CDNSSDService::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )\r
+{\r
+ if ( msg == WM_SOCKET )\r
+ {\r
+ SocketMap::iterator it;\r
+ \r
+ it = m_socketMap.find( ( SOCKET ) wParam );\r
+ check( it != m_socketMap.end() );\r
+\r
+ if ( it != m_socketMap.end() )\r
+ {\r
+ DNSServiceProcessResult( it->second->m_primary );\r
+ }\r
+ }\r
+\r
+ return DefWindowProc(hWnd, msg, wParam, lParam);;\r
+}\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: DNSSDService.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma once\r
+#include "resource.h" // main symbols\r
+\r
+#include "DLLX.h"\r
+#include "DNSSDEventManager.h"\r
+#include <CommonServices.h>\r
+#include <DebugServices.h>\r
+#include <dns_sd.h>\r
+#include <map>\r
+\r
+\r
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)\r
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."\r
+#endif\r
+\r
+\r
+\r
+// CDNSSDService\r
+\r
+class ATL_NO_VTABLE CDNSSDService :\r
+ public CComObjectRootEx<CComSingleThreadModel>,\r
+ public CComCoClass<CDNSSDService, &CLSID_DNSSDService>,\r
+ public IDispatchImpl<IDNSSDService, &IID_IDNSSDService, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>\r
+{\r
+public:\r
+\r
+ typedef CComObjectRootEx<CComSingleThreadModel> Super;\r
+\r
+ CDNSSDService()\r
+ :\r
+ m_isPrimary( FALSE ),\r
+ m_eventManager( NULL ),\r
+ m_stopped( FALSE ),\r
+ m_primary( NULL ),\r
+ m_subord( NULL )\r
+ {\r
+ }\r
+\r
+DECLARE_REGISTRY_RESOURCEID(IDR_DNSSDSERVICE)\r
+\r
+\r
+BEGIN_COM_MAP(CDNSSDService)\r
+ COM_INTERFACE_ENTRY(IDNSSDService)\r
+ COM_INTERFACE_ENTRY(IDispatch)\r
+END_COM_MAP()\r
+\r
+ DECLARE_PROTECT_FINAL_CONSTRUCT()\r
+\r
+ HRESULT\r
+ FinalConstruct();\r
+\r
+ void \r
+ FinalRelease();\r
+\r
+public:\r
+\r
+ inline DNSServiceRef\r
+ GetPrimaryRef()\r
+ {\r
+ return m_primary;\r
+ }\r
+\r
+ inline void\r
+ SetPrimaryRef( DNSServiceRef primary )\r
+ {\r
+ m_primary = primary;\r
+ }\r
+\r
+ inline DNSServiceRef\r
+ GetSubordRef()\r
+ {\r
+ return m_subord;\r
+ }\r
+\r
+ inline void\r
+ SetSubordRef( DNSServiceRef subord )\r
+ {\r
+ m_subord = subord;\r
+ }\r
+\r
+ inline CDNSSDEventManager*\r
+ GetEventManager()\r
+ {\r
+ return m_eventManager;\r
+ }\r
+\r
+ inline void\r
+ SetEventManager( IDNSSDEventManager * eventManager )\r
+ {\r
+ if ( m_eventManager )\r
+ {\r
+ m_eventManager->Release();\r
+ m_eventManager = NULL;\r
+ }\r
+\r
+ if ( eventManager )\r
+ {\r
+ m_eventManager = dynamic_cast< CDNSSDEventManager* >( eventManager );\r
+ check( m_eventManager );\r
+ m_eventManager->AddRef();\r
+ }\r
+ }\r
+\r
+ inline BOOL\r
+ Stopped()\r
+ {\r
+ return m_stopped;\r
+ }\r
+\r
+private:\r
+\r
+ static void DNSSD_API
+ DomainEnumReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *replyDomain,
+ void *context
+ );\r
+\r
+ static void DNSSD_API
+ BrowseReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode,
+ const char *serviceName,
+ const char *regtype,
+ const char *replyDomain,
+ void *context
+ );\r
+\r
+ static void DNSSD_API\r
+ ResolveReply\r
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullname,
+ const char *hosttarget,
+ uint16_t port,
+ uint16_t txtLen,
+ const unsigned char *txtRecord,
+ void *context\r
+ );\r
+\r
+ static void DNSSD_API
+ RegisterReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ const char *name,
+ const char *regtype,
+ const char *domain,
+ void *context
+ );\r
+\r
+ static void DNSSD_API
+ QueryRecordReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullname,
+ uint16_t rrtype,
+ uint16_t rrclass,
+ uint16_t rdlen,
+ const void *rdata,
+ uint32_t ttl,
+ void *context
+ );\r
+\r
+ static void DNSSD_API
+ GetAddrInfoReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode,
+ const char *hostname,
+ const struct sockaddr *address,
+ uint32_t ttl,
+ void *context
+ );\r
+\r
+ static void DNSSD_API
+ NATPortMappingReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode,
+ uint32_t externalAddress, /* four byte IPv4 address in network byte order */
+ DNSServiceProtocol protocol,
+ uint16_t internalPort,
+ uint16_t externalPort, /* may be different than the requested port */
+ uint32_t ttl, /* may be different than the requested ttl */
+ void *context
+ );\r
+\r
+ static void DNSSD_API
+ RegisterRecordReply
+ (
+ DNSServiceRef sdRef,
+ DNSRecordRef RecordRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ void *context
+ );\r
+\r
+ inline BOOL\r
+ ShouldHandleReply( DNSServiceErrorType errorCode, CDNSSDEventManager *& eventManager );\r
+ \r
+ static LRESULT CALLBACK\r
+ WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );\r
+\r
+ typedef std::map< SOCKET, CDNSSDService* > SocketMap;\r
+\r
+ static BOOL m_registeredWindowClass;\r
+ static HWND m_hiddenWindow;\r
+ static SocketMap m_socketMap;\r
+ CDNSSDEventManager * m_eventManager;\r
+ BOOL m_stopped;\r
+ BOOL m_isPrimary;\r
+ DNSServiceRef m_primary;\r
+ DNSServiceRef m_subord;\r
+public:\r
+ STDMETHOD(EnumerateDomains)(DNSSDFlags flags, ULONG ifIndex, IDNSSDEventManager *eventManager, IDNSSDService **service); \r
+ STDMETHOD(Browse)(DNSSDFlags flags, ULONG interfaceIndex, BSTR regtype, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** sdref);\r
+ STDMETHOD(Resolve)(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service);\r
+ STDMETHOD(Register)(DNSSDFlags flags, ULONG ifIndex, BSTR name, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IDNSSDEventManager *eventManager, IDNSSDService **service);\r
+ STDMETHOD(QueryRecord)(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IDNSSDEventManager *eventManager, IDNSSDService **service); \r
+ STDMETHOD(RegisterRecord)(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata, ULONG ttl, IDNSSDEventManager* eventManager, IDNSSDRecord** record);\r
+ STDMETHOD(AddRecord)(DNSSDFlags flags, DNSSDRRType rrtype, VARIANT rdata, ULONG ttl, IDNSSDRecord ** record);\r
+ STDMETHOD(ReconfirmRecord)(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata);\r
+ STDMETHOD(GetProperty)(BSTR prop, VARIANT * value);\r
+ STDMETHOD(GetAddrInfo)(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostname, IDNSSDEventManager *eventManager, IDNSSDService **service); \r
+ STDMETHOD(NATPortMappingCreate)(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, IDNSSDEventManager *eventManager, IDNSSDService **service);\r
+ STDMETHOD(Stop)(void);\r
+};\r
+\r
+OBJECT_ENTRY_AUTO(__uuidof(DNSSDService), CDNSSDService)\r
--- /dev/null
+HKCR\r
+{\r
+ Bonjour.DNSSDService.1 = s 'DNSSDService Class'\r
+ {\r
+ CLSID = s '{24CD4DE9-FF84-4701-9DC1-9B69E0D1090A}'\r
+ }\r
+ Bonjour.DNSSDService = s 'DNSSDService Class'\r
+ {\r
+ CLSID = s '{24CD4DE9-FF84-4701-9DC1-9B69E0D1090A}'\r
+ CurVer = s 'Bonjour.DNSSDService.1'\r
+ }\r
+ NoRemove CLSID\r
+ {\r
+ ForceRemove {24CD4DE9-FF84-4701-9DC1-9B69E0D1090A} = s 'DNSSDService Class'\r
+ {\r
+ ProgID = s 'Bonjour.DNSSDService.1'\r
+ VersionIndependentProgID = s 'Bonjour.DNSSDService'\r
+ ForceRemove 'Programmable'\r
+ InprocServer32 = s '%MODULE%'\r
+ {\r
+ val ThreadingModel = s 'Apartment'\r
+ }\r
+ val AppID = s '%APPID%'\r
+ 'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: StringServices.cpp,v $
+Revision 1.2 2009/06/02 18:43:57 herscher
+<rdar://problem/3948252> Allow component consumers to pass in null strings
+
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#include "StringServices.h"\r
+#include <DebugServices.h>\r
+\r
+\r
+extern BOOL\r
+BSTRToUTF8\r
+ (\r
+ BSTR inString,\r
+ std::string & outString\r
+ )\r
+{\r
+ USES_CONVERSION;\r
+ \r
+ char * utf8String = NULL;\r
+ OSStatus err = kNoErr;\r
+\r
+ outString = "";
+
+ if ( inString )\r
+ {
+ TCHAR * utf16String = NULL;
+ size_t size = 0;
+\r
+ utf16String = OLE2T( inString );\r
+ require_action( utf16String != NULL, exit, err = kUnknownErr );\r
+\r
+ if ( wcslen( utf16String ) > 0 )\r
+ {\r
+ size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), NULL, 0, NULL, NULL );\r
+ err = translate_errno( size != 0, GetLastError(), kUnknownErr );\r
+ require_noerr( err, exit );\r
+\r
+ try\r
+ {\r
+ utf8String = new char[ size + 1 ];\r
+ }\r
+ catch ( ... )\r
+ {\r
+ utf8String = NULL;\r
+ }\r
+\r
+ require_action( utf8String != NULL, exit, err = kNoMemoryErr );\r
+ size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), utf8String, (int) size, NULL, NULL);\r
+ err = translate_errno( size != 0, GetLastError(), kUnknownErr );\r
+ require_noerr( err, exit );\r
+\r
+ // have to add the trailing 0 because WideCharToMultiByte doesn't do it,\r
+ // although it does return the correct size\r
+\r
+ utf8String[size] = '\0';\r
+ outString = utf8String;\r
+ }
+ }\r
+\r
+exit:\r
+\r
+ if ( utf8String != NULL )\r
+ {\r
+ delete [] utf8String;\r
+ }\r
+\r
+ return ( !err ) ? TRUE : FALSE;\r
+}\r
+\r
+\r
+extern BOOL\r
+UTF8ToBSTR\r
+ (\r
+ const char * inString,\r
+ CComBSTR & outString\r
+ )\r
+{\r
+ wchar_t * unicode = NULL;\r
+ OSStatus err = 0;\r
+\r
+ if ( inString )\r
+ {
+ int n;
+
+ n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, NULL, 0 );\r
+ \r
+ if ( n > 0 )\r
+ {\r
+ try\r
+ {\r
+ unicode = new wchar_t[ n ];\r
+ }\r
+ catch ( ... )\r
+ {\r
+ unicode = NULL;\r
+ }\r
+\r
+ require_action( unicode, exit, err = ERROR_INSUFFICIENT_BUFFER );\r
+\r
+ n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, unicode, n );\r
+ }\r
+\r
+ outString = unicode;\r
+ }
+\r
+exit:\r
+\r
+ if ( unicode != NULL )\r
+ {\r
+ delete [] unicode;\r
+ }\r
+\r
+ return ( !err ) ? TRUE : FALSE;\r
+}\r
+\r
+\r
+BOOL\r
+ByteArrayToVariant\r
+ (\r
+ const void * inArray,\r
+ size_t inArrayLen,\r
+ VARIANT * outVariant\r
+ )\r
+{\r
+ LPBYTE buf = NULL;\r
+ HRESULT hr = 0;\r
+ BOOL ok = TRUE;\r
+\r
+ VariantClear( outVariant );\r
+ outVariant->vt = VT_ARRAY|VT_UI1;\r
+ outVariant->parray = SafeArrayCreateVector( VT_UI1, 0, ( ULONG ) inArrayLen );\r
+ require_action( outVariant->parray, exit, ok = FALSE );\r
+ hr = SafeArrayAccessData( outVariant->parray, (LPVOID *)&buf );\r
+ require_action( hr == S_OK, exit, ok = FALSE );\r
+ memcpy( buf, inArray, inArrayLen );\r
+ hr = SafeArrayUnaccessData( outVariant->parray );\r
+ require_action( hr == S_OK, exit, ok = FALSE );\r
+\r
+exit:\r
+\r
+ return ok;\r
+}\r
+\r
+\r
+extern BOOL\r
+VariantToByteArray\r
+ (\r
+ VARIANT * inVariant,\r
+ std::vector< BYTE > & outArray\r
+ )\r
+{\r
+ SAFEARRAY * psa = NULL;\r
+ BYTE * pData = NULL;\r
+ ULONG cElements = 0;\r
+ HRESULT hr;\r
+ BOOL ok = TRUE;\r
+\r
+ require_action( V_VT( inVariant ) == ( VT_ARRAY|VT_UI1 ), exit, ok = FALSE );\r
+ psa = V_ARRAY( inVariant );\r
+ require_action( psa, exit, ok = FALSE );\r
+ require_action( SafeArrayGetDim( psa ) == 1, exit, ok = FALSE );\r
+ hr = SafeArrayAccessData( psa, ( LPVOID* )&pData );\r
+ require_action( hr == S_OK, exit, ok = FALSE );\r
+ cElements = psa->rgsabound[0].cElements;\r
+ outArray.reserve( cElements );\r
+ outArray.assign( cElements, 0 );\r
+ memcpy( &outArray[ 0 ], pData, cElements );\r
+ SafeArrayUnaccessData( psa );\r
+\r
+exit:\r
+\r
+ return ok;\r
+}
\ No newline at end of file
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: StringServices.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#ifndef _StringServices_h\r
+#define _StringServices_h\r
+\r
+#include <atlbase.h>\r
+#include <vector>\r
+#include <string>\r
+\r
+\r
+extern BOOL\r
+BSTRToUTF8\r
+ (\r
+ BSTR inString,\r
+ std::string & outString\r
+ );\r
+\r
+\r
+extern BOOL\r
+UTF8ToBSTR\r
+ (\r
+ const char * inString,\r
+ CComBSTR & outString\r
+ );\r
+\r
+\r
+extern BOOL\r
+ByteArrayToVariant\r
+ (\r
+ const void * inArray,\r
+ size_t inArrayLen,\r
+ VARIANT * outVariant\r
+ );\r
+\r
+\r
+extern BOOL\r
+VariantToByteArray\r
+ (\r
+ VARIANT * inVariant,\r
+ std::vector< BYTE > & outArray\r
+ );\r
+\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: TXTRecord.cpp,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#include "stdafx.h"\r
+#include "TXTRecord.h"\r
+#include "StringServices.h"\r
+#include <DebugServices.h>\r
+\r
+\r
+// CTXTRecord\r
+\r
+\r
+STDMETHODIMP CTXTRecord::SetValue(BSTR key, VARIANT value)\r
+{\r
+ std::string keyUTF8;\r
+ ByteArray valueArray;\r
+ BOOL ok;\r
+ DNSServiceErrorType err;\r
+ HRESULT hr = S_OK;\r
+\r
+ if ( !m_allocated )\r
+ {\r
+ TXTRecordCreate( &m_tref, 0, NULL );\r
+ m_allocated = TRUE;\r
+ }\r
+\r
+ ok = BSTRToUTF8( key, keyUTF8 );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+\r
+ ok = VariantToByteArray( &value, valueArray );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+\r
+ err = TXTRecordSetValue( &m_tref, keyUTF8.c_str(), ( uint8_t ) valueArray.size(), &valueArray[ 0 ] );\r
+ require_action( !err, exit, hr = S_FALSE );\r
+\r
+exit:\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CTXTRecord::RemoveValue(BSTR key)\r
+{\r
+ HRESULT hr = S_OK;\r
+\r
+ if ( m_allocated )\r
+ {\r
+ std::string keyUTF8;\r
+ BOOL ok;\r
+ DNSServiceErrorType err;\r
+\r
+ ok = BSTRToUTF8( key, keyUTF8 );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+\r
+ err = TXTRecordRemoveValue( &m_tref, keyUTF8.c_str() );\r
+ require_action( !err, exit, hr = S_FALSE );\r
+ }\r
+\r
+exit:\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CTXTRecord::ContainsKey(BSTR key, VARIANT_BOOL* retval)\r
+{\r
+ std::string keyUTF8;\r
+ int ret = 0;\r
+ HRESULT err = S_OK;\r
+\r
+ if ( m_byteArray.size() > 0 )\r
+ {\r
+ BOOL ok;\r
+\r
+ ok = BSTRToUTF8( key, keyUTF8 );\r
+ require_action( ok, exit, err = S_FALSE );\r
+\r
+ ret = TXTRecordContainsKey( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str() );\r
+ }\r
+\r
+ *retval = ( ret ) ? VARIANT_TRUE : VARIANT_FALSE;\r
+\r
+exit:\r
+\r
+ return err;\r
+}\r
+\r
+STDMETHODIMP CTXTRecord::GetValueForKey(BSTR key, VARIANT* value)\r
+{\r
+ std::string keyUTF8;\r
+ const void * rawValue;\r
+ uint8_t rawValueLen;\r
+ BOOL ok = TRUE;\r
+ HRESULT hr = S_OK;\r
+\r
+ VariantClear( value );\r
+\r
+ if ( m_byteArray.size() > 0 )\r
+ {\r
+ ok = BSTRToUTF8( key, keyUTF8 );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+\r
+ rawValue = TXTRecordGetValuePtr( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str(), &rawValueLen );\r
+\r
+ if ( rawValue )\r
+ {\r
+ ok = ByteArrayToVariant( rawValue, rawValueLen, value );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CTXTRecord::GetCount(ULONG* count)\r
+{\r
+ *count = 0;\r
+\r
+ if ( m_byteArray.size() > 0 )\r
+ {\r
+ *count = TXTRecordGetCount( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ] );\r
+ }\r
+\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CTXTRecord::GetKeyAtIndex(ULONG index, BSTR* retval)\r
+{\r
+ char keyBuf[ 64 ];\r
+ uint8_t rawValueLen;\r
+ const void * rawValue;\r
+ CComBSTR temp;\r
+ DNSServiceErrorType err;\r
+ BOOL ok;\r
+ HRESULT hr = S_OK;\r
+\r
+ err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue );\r
+ require_action( !err, exit, hr = S_FALSE );\r
+\r
+ ok = UTF8ToBSTR( keyBuf, temp );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+\r
+ *retval = temp;\r
+\r
+exit:\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CTXTRecord::GetValueAtIndex(ULONG index, VARIANT* retval)\r
+{\r
+ char keyBuf[ 64 ];\r
+ uint8_t rawValueLen;\r
+ const void * rawValue;\r
+ CComBSTR temp;\r
+ DNSServiceErrorType err;\r
+ BOOL ok;\r
+ HRESULT hr = S_OK;\r
+\r
+ err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue );\r
+ require_action( !err, exit, hr = S_FALSE );\r
+\r
+ ok = ByteArrayToVariant( rawValue, rawValueLen, retval );\r
+ require_action( ok, exit, hr = S_FALSE );\r
+\r
+exit:\r
+\r
+ return hr;\r
+}\r
+\r
+\r
+void\r
+CTXTRecord::SetBytes\r
+ (\r
+ const unsigned char * bytes,\r
+ uint16_t len\r
+ )\r
+{\r
+ check ( bytes != NULL );\r
+ check( len );\r
+\r
+ m_byteArray.reserve( len );\r
+ m_byteArray.assign( bytes, bytes + len );\r
+}\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: TXTRecord.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma once\r
+#include "resource.h" // main symbols\r
+#include "DLLX.h"\r
+#include <vector>\r
+#include <dns_sd.h>\r
+\r
+\r
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)\r
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."\r
+#endif\r
+\r
+\r
+\r
+// CTXTRecord\r
+\r
+class ATL_NO_VTABLE CTXTRecord :\r
+ public CComObjectRootEx<CComSingleThreadModel>,\r
+ public CComCoClass<CTXTRecord, &CLSID_TXTRecord>,\r
+ public IDispatchImpl<ITXTRecord, &IID_ITXTRecord, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>\r
+{\r
+public:\r
+ CTXTRecord()\r
+ :\r
+ m_allocated( FALSE )\r
+ {\r
+ }\r
+\r
+DECLARE_REGISTRY_RESOURCEID(IDR_TXTRECORD)\r
+\r
+\r
+BEGIN_COM_MAP(CTXTRecord)\r
+ COM_INTERFACE_ENTRY(ITXTRecord)\r
+ COM_INTERFACE_ENTRY(IDispatch)\r
+END_COM_MAP()\r
+\r
+\r
+\r
+ DECLARE_PROTECT_FINAL_CONSTRUCT()\r
+\r
+ HRESULT FinalConstruct()\r
+ {\r
+ return S_OK;\r
+ }\r
+\r
+ void FinalRelease()\r
+ {\r
+ if ( m_allocated )\r
+ {\r
+ TXTRecordDeallocate( &m_tref );\r
+ }\r
+ }\r
+\r
+public:\r
+\r
+ STDMETHOD(SetValue)(BSTR key, VARIANT value);\r
+ STDMETHOD(RemoveValue)(BSTR key);\r
+ STDMETHOD(ContainsKey)(BSTR key, VARIANT_BOOL* retval);\r
+ STDMETHOD(GetValueForKey)(BSTR key, VARIANT* value);\r
+ STDMETHOD(GetCount)(ULONG* count);\r
+ STDMETHOD(GetKeyAtIndex)(ULONG index, BSTR* retval);\r
+ STDMETHOD(GetValueAtIndex)(ULONG index, VARIANT* retval);\r
+\r
+private:\r
+\r
+ typedef std::vector< BYTE > ByteArray;\r
+ ByteArray m_byteArray;\r
+ BOOL m_allocated;\r
+ TXTRecordRef m_tref;\r
+\r
+public:\r
+\r
+ uint16_t\r
+ GetLen()\r
+ {\r
+ return TXTRecordGetLength( &m_tref );\r
+ }\r
+\r
+ const void*\r
+ GetBytes()\r
+ {\r
+ return TXTRecordGetBytesPtr( &m_tref );\r
+ }\r
+\r
+ void\r
+ SetBytes\r
+ (\r
+ const unsigned char * bytes,\r
+ uint16_t len\r
+ );\r
+};\r
+\r
+OBJECT_ENTRY_AUTO(__uuidof(TXTRecord), CTXTRecord)\r
--- /dev/null
+HKCR\r
+{\r
+ Bonjour.TXTRecord.1 = s 'TXTRecord Class'\r
+ {\r
+ CLSID = s '{AFEE063C-05BA-4248-A26E-168477F49734}'\r
+ }\r
+ Bonjour.TXTRecord = s 'TXTRecord Class'\r
+ {\r
+ CLSID = s '{AFEE063C-05BA-4248-A26E-168477F49734}'\r
+ CurVer = s 'Bonjour.TXTRecord.1'\r
+ }\r
+ NoRemove CLSID\r
+ {\r
+ ForceRemove {AFEE063C-05BA-4248-A26E-168477F49734} = s 'TXTRecord Class'\r
+ {\r
+ ProgID = s 'Bonjour.TXTRecord.1'\r
+ VersionIndependentProgID = s 'Bonjour.TXTRecord'\r
+ ForceRemove 'Programmable'\r
+ InprocServer32 = s '%MODULE%'\r
+ {\r
+ val ThreadingModel = s 'Apartment'\r
+ }\r
+ val AppID = s '%APPID%'\r
+ 'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'\r
+ }\r
+ }\r
+}\r
--- /dev/null
+\r
+// Wizard-generated connection point proxy class\r
+// WARNING: This file may be regenerated by the wizard\r
+\r
+\r
+#pragma once\r
+\r
+template<class T>\r
+class CProxy_IDNSSDEvents :\r
+ public IConnectionPointImpl<T, &__uuidof(_IDNSSDEvents)>\r
+{\r
+public:\r
+ HRESULT Fire_DomainFound( IDNSSDService * service, DNSSDFlags flags, ULONG ifIndex, BSTR domain)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[4];\r
+ avarParams[3] = service;\r
+ avarParams[2] = flags;\r
+ avarParams[1] = ifIndex;\r
+ avarParams[1].vt = VT_UI4;\r
+ avarParams[0] = domain;\r
+ avarParams[0].vt = VT_BSTR;\r
+ DISPPARAMS params = { avarParams, NULL, 4, 0 };\r
+ hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_DomainLost( IDNSSDService * service, DNSSDFlags flags, ULONG ifIndex, BSTR domain)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[4];\r
+ avarParams[3] = service;\r
+ avarParams[2] = flags;\r
+ avarParams[1] = ifIndex;\r
+ avarParams[1].vt = VT_UI4;\r
+ avarParams[0] = domain;\r
+ avarParams[0].vt = VT_BSTR;\r
+ DISPPARAMS params = { avarParams, NULL, 4, 0 };\r
+ hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_ServiceFound( IDNSSDService * browser, DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[6];\r
+ avarParams[5] = browser;\r
+ avarParams[4] = flags;\r
+ avarParams[3] = ifIndex;\r
+ avarParams[3].vt = VT_UI4;\r
+ avarParams[2] = serviceName;\r
+ avarParams[2].vt = VT_BSTR;\r
+ avarParams[1] = regType;\r
+ avarParams[1].vt = VT_BSTR;\r
+ avarParams[0] = domain;\r
+ avarParams[0].vt = VT_BSTR;\r
+ DISPPARAMS params = { avarParams, NULL, 6, 0 };\r
+ hr = pConnection->Invoke(3, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_ServiceLost( IDNSSDService * browser, DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[6];\r
+ avarParams[5] = browser;\r
+ avarParams[4] = flags;\r
+ avarParams[3] = ifIndex;\r
+ avarParams[3].vt = VT_UI4;\r
+ avarParams[2] = serviceName;\r
+ avarParams[2].vt = VT_BSTR;\r
+ avarParams[1] = regType;\r
+ avarParams[1].vt = VT_BSTR;\r
+ avarParams[0] = domain;\r
+ avarParams[0].vt = VT_BSTR;\r
+ DISPPARAMS params = { avarParams, NULL, 6, 0 };\r
+ hr = pConnection->Invoke(4, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_ServiceResolved( IDNSSDService * service, DNSSDFlags flags, ULONG ifIndex, BSTR fullName, BSTR hostName, USHORT port, ITXTRecord * record)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[7];\r
+ avarParams[6] = service;\r
+ avarParams[5] = flags;\r
+ avarParams[4] = ifIndex;\r
+ avarParams[4].vt = VT_UI4;\r
+ avarParams[3] = fullName;\r
+ avarParams[3].vt = VT_BSTR;\r
+ avarParams[2] = hostName;\r
+ avarParams[2].vt = VT_BSTR;\r
+ avarParams[1] = port;\r
+ avarParams[1].vt = VT_UI2;\r
+ avarParams[0] = record;\r
+ DISPPARAMS params = { avarParams, NULL, 7, 0 };\r
+ hr = pConnection->Invoke(5, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_ServiceRegistered( IDNSSDService * service, DNSSDFlags flags, BSTR name, BSTR regType, BSTR domain)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[5];\r
+ avarParams[4] = service;\r
+ avarParams[3] = flags;\r
+ avarParams[2] = name;\r
+ avarParams[2].vt = VT_BSTR;\r
+ avarParams[1] = regType;\r
+ avarParams[1].vt = VT_BSTR;\r
+ avarParams[0] = domain;\r
+ avarParams[0].vt = VT_BSTR;\r
+ DISPPARAMS params = { avarParams, NULL, 5, 0 };\r
+ hr = pConnection->Invoke(6, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_QueryRecordAnswered( IDNSSDService * service, DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata, ULONG ttl)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[8];\r
+ avarParams[7] = service;\r
+ avarParams[6] = flags;\r
+ avarParams[5] = ifIndex;\r
+ avarParams[5].vt = VT_UI4;\r
+ avarParams[4] = fullName;\r
+ avarParams[4].vt = VT_BSTR;\r
+ avarParams[3] = rrtype;\r
+ avarParams[2] = rrclass;\r
+ avarParams[1] = rdata;\r
+ avarParams[0] = ttl;\r
+ avarParams[0].vt = VT_UI4;\r
+ DISPPARAMS params = { avarParams, NULL, 8, 0 };\r
+ hr = pConnection->Invoke(7, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_RecordRegistered( IDNSSDRecord * record, DNSSDFlags flags)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[2];\r
+ avarParams[1] = record;\r
+ avarParams[0] = flags;\r
+ DISPPARAMS params = { avarParams, NULL, 2, 0 };\r
+ hr = pConnection->Invoke(8, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_AddressFound( IDNSSDService * service, DNSSDFlags flags, ULONG ifIndex, BSTR hostname, DNSSDAddressFamily addressFamily, BSTR address, ULONG ttl)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[7];\r
+ avarParams[6] = service;\r
+ avarParams[5] = flags;\r
+ avarParams[4] = ifIndex;\r
+ avarParams[4].vt = VT_UI4;\r
+ avarParams[3] = hostname;\r
+ avarParams[3].vt = VT_BSTR;\r
+ avarParams[2] = addressFamily;\r
+ avarParams[1] = address;\r
+ avarParams[1].vt = VT_BSTR;\r
+ avarParams[0] = ttl;\r
+ avarParams[0].vt = VT_UI4;\r
+ DISPPARAMS params = { avarParams, NULL, 7, 0 };\r
+ hr = pConnection->Invoke(9, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_MappingCreated( IDNSSDService * service, DNSSDFlags flags, ULONG ifIndex, ULONG externalAddress, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[9];\r
+ avarParams[8] = service;\r
+ avarParams[7] = flags;\r
+ avarParams[6] = ifIndex;\r
+ avarParams[6].vt = VT_UI4;\r
+ avarParams[5] = externalAddress;\r
+ avarParams[5].vt = VT_UI4;\r
+ avarParams[4] = addressFamily;\r
+ avarParams[3] = protocol;\r
+ avarParams[2] = internalPort;\r
+ avarParams[2].vt = VT_UI2;\r
+ avarParams[1] = externalPort;\r
+ avarParams[1].vt = VT_UI2;\r
+ avarParams[0] = ttl;\r
+ avarParams[0].vt = VT_UI4;\r
+ DISPPARAMS params = { avarParams, NULL, 9, 0 };\r
+ hr = pConnection->Invoke(10, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+ HRESULT Fire_OperationFailed( IDNSSDService * service, DNSSDError error)\r
+ {\r
+ HRESULT hr = S_OK;\r
+ T * pThis = static_cast<T *>(this);\r
+ int cConnections = m_vec.GetSize();\r
+\r
+ for (int iConnection = 0; iConnection < cConnections; iConnection++)\r
+ {\r
+ pThis->Lock();\r
+ CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);\r
+ pThis->Unlock();\r
+\r
+ IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);\r
+\r
+ if (pConnection)\r
+ {\r
+ CComVariant avarParams[2];\r
+ avarParams[1] = service;\r
+ avarParams[0] = error;\r
+ DISPPARAMS params = { avarParams, NULL, 2, 0 };\r
+ hr = pConnection->Invoke(11, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL);\r
+ }\r
+ }\r
+ return hr;\r
+ }\r
+};\r
+\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-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: dlldatax.c,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#ifdef _MERGE_PROXYSTUB // merge proxy stub DLL\r
+\r
+#define REGISTER_PROXY_DLL //DllRegisterServer, etc.\r
+\r
+#define _WIN32_WINNT 0x0500 //for WinNT 4.0 or Win95 with DCOM\r
+#define USE_STUBLESS_PROXY //defined only with MIDL switch /Oicf\r
+\r
+#pragma comment(lib, "rpcns4.lib")\r
+#pragma comment(lib, "rpcrt4.lib")\r
+\r
+#define ENTRY_PREFIX Prx\r
+\r
+#include "dlldata.c"\r
+#include "DLLX_p.c"\r
+\r
+#endif //_MERGE_PROXYSTUB\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-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: dlldatax.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma once\r
+\r
+#ifdef _MERGE_PROXYSTUB\r
+\r
+extern "C" \r
+{\r
+BOOL WINAPI PrxDllMain(HINSTANCE hInstance, DWORD dwReason, \r
+ LPVOID lpReserved);\r
+STDAPI PrxDllCanUnloadNow(void);\r
+STDAPI PrxDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv);\r
+STDAPI PrxDllRegisterServer(void);\r
+STDAPI PrxDllUnregisterServer(void);\r
+}\r
+\r
+#endif\r
--- /dev/null
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Visual C++ generated include file.\r
+// Used by DLLX.rc\r
+//\r
+#define IDS_PROJNAME 100\r
+#define IDR_DLLX 101\r
+#define IDR_DNSSD 102\r
+#define IDR_DNSSDSERVICE 103\r
+#define IDR_BROWSELISTENER 104\r
+#define IDR_RESOLVELISTENER 105\r
+#define IDR_TXTRECORD 106\r
+#define IDR_ENUMERATEDOMAINSLISTENER 107\r
+#define IDR_REGISTERLISTENER 108\r
+#define IDR_QUERYRECORDLISTENER 109\r
+#define IDR_GETADDRINFOLISTENER 110\r
+#define IDR_DNSSDRECORD 111\r
+#define IDR_REGISTERRECORDLISTENER 112\r
+#define IDR_NATPORTMAPPINGLISTENER 113\r
+#define IDR_DNSSDEVENTMANAGER 114\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NEXT_RESOURCE_VALUE 201\r
+#define _APS_NEXT_COMMAND_VALUE 32768\r
+#define _APS_NEXT_CONTROL_VALUE 201\r
+#define _APS_NEXT_SYMED_VALUE 115\r
+#endif\r
+#endif\r
--- /dev/null
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 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: stdafx.h,v $
+Revision 1.1 2009/05/26 04:43:54 herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#pragma once\r
+\r
+#ifndef STRICT\r
+#define STRICT\r
+#endif\r
+\r
+// Modify the following defines if you have to target a platform prior to the ones specified below.\r
+// Refer to MSDN for the latest info on corresponding values for different platforms.\r
+#ifndef WINVER // Allow use of features specific to Windows XP or later.\r
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.\r
+#endif\r
+\r
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. \r
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.\r
+#endif \r
+\r
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.\r
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.\r
+#endif\r
+\r
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.\r
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.\r
+#endif\r
+\r
+#define _ATL_APARTMENT_THREADED\r
+#define _ATL_NO_AUTOMATIC_NAMESPACE\r
+\r
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit\r
+\r
+\r
+#include "resource.h"\r
+#include <atlbase.h>\r
+#include <atlcom.h>\r
+\r
+using namespace ATL;
\ No newline at end of file
Change History (most recent first):
$Log: AboutDialog.cpp,v $
+Revision 1.4 2008/10/23 22:33:26 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
Revision 1.3 2006/08/14 23:25:49 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
: CDialog(AboutDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(AboutDialog)
- // NOTE: the ClassWizard will add member initialization here
+ // Note: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(AboutDialog)
- // NOTE: the ClassWizard will add DDX and DDV calls here
+ // Note: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
Change History (most recent first):
$Log: AboutDialog.h,v $
+Revision 1.4 2008/10/23 22:33:26 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
Revision 1.3 2006/08/14 23:25:49 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
//{{AFX_DATA(AboutDialog)
enum { IDD = IDD_ABOUT_DIALOG };
- // NOTE: the ClassWizard will add data members here
+ // Note: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
Change History (most recent first):
$Log: ChooserDialog.cpp,v $
+Revision 1.5 2008/10/23 22:33:26 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
Revision 1.4 2006/08/14 23:25:49 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
: CDialog( ChooserDialog::IDD, inParent)
{
//{{AFX_DATA_INIT(ChooserDialog)
- // NOTE: the ClassWizard will add member initialization here
+ // Note: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Load menu accelerator table.
Change History (most recent first):
$Log: BrowserDialog.cpp,v $
+Revision 1.4 2008/10/23 22:33:26 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
Revision 1.3 2006/08/14 23:25:55 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
: CDialog( BrowserDialog::IDD, inParent )
{
//{{AFX_DATA_INIT(BrowserDialog)
- // NOTE: the ClassWizard will add member initialization here
+ // Note: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32.
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="Java"\r
ProjectGUID="{9CE2568A-3170-41C6-9F20-A0188A9EC114}"\r
- Keyword="MakeFileProj">\r
+ Keyword="MakeFileProj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
OutputDirectory="Debug"\r
IntermediateDirectory="Debug"\r
- ConfigurationType="0">\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
<Tool\r
Name="VCNMakeTool"\r
BuildCommandLine="nmake /f makefile DEBUG=1"\r
ReBuildCommandLine="nmake /f makefile DEBUG=1"\r
- CleanCommandLine="nmake /f makefile DEBUG=1 clean"/>\r
+ CleanCommandLine="nmake /f makefile DEBUG=1 clean"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
OutputDirectory="Release"\r
IntermediateDirectory="Release"\r
- ConfigurationType="0">\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake /f makefile"\r
+ ReBuildCommandLine="nmake /f makefile"\r
+ CleanCommandLine="nmake /f makefile clean"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
+ <Tool\r
+ Name="VCNMakeTool"\r
+ BuildCommandLine="nmake /f makefile DEBUG=1"\r
+ ReBuildCommandLine="nmake /f makefile DEBUG=1"\r
+ CleanCommandLine="nmake /f makefile DEBUG=1 clean"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="0"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ >\r
<Tool\r
Name="VCNMakeTool"\r
BuildCommandLine="nmake /f makefile"\r
ReBuildCommandLine="nmake /f makefile"\r
- CleanCommandLine="nmake /f makefile clean"/>\r
+ CleanCommandLine="nmake /f makefile clean"\r
+ Output=""\r
+ PreprocessorDefinitions=""\r
+ IncludeSearchPath=""\r
+ ForcedIncludes=""\r
+ AssemblySearchPath=""\r
+ ForcedUsingAssemblies=""\r
+ CompileAsManaged=""\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
# limitations under the License.
#
# $Log: makefile,v $
+# Revision 1.10 2009/03/30 20:22:43 herscher
+# <rdar://problem/5925472> Current Bonjour code does not compile on Windows
+# Update LIBDIR to work with new build directory structure
+# Create postbuild rules for new buildtrain
+#
# Revision 1.9 2006/08/14 23:26:04 cheshire
# Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#
OBJDIR = objects\debug
BUILDDIR = build\debug
INSTALLDIR = root\"Program Files"\Bonjour
-LIBDIR = ..\DLL\Debug
+LIBDIR = ..\DLL\Win32\Debug
!else
CFLAGS_DEBUG = -Os -DMDNS_DEBUGMSGS=0
OBJDIR = objects\prod
BUILDDIR = build\prod
INSTALLDIR = root\"Program Files"\Bonjour
-LIBDIR = ..\DLL\Release
+LIBDIR = ..\DLL\Win32\Release
!endif
CFLAGS = $(CFLAGS_COMMON) $(CFLAGS_DEBUG)
@if not exist $(BUILDDIR) mkdir $(BUILDDIR)
postbuild:
- @if not exist root mkdir root
+ @if not "%RC_XBS%"=="YES" GOTO CONT
+ @if not exist "$(DSTROOT)\WINDOWS\system32\Win32" mkdir "$(DSTROOT)\WINDOWS\system32\Win32"
+ @if not exist "$(DSTROOT)\Program Files\Bonjour\Win32" mkdir "$(DSTROOT)\Program Files\Bonjour\Win32"
+ @copy $(BUILDDIR)\jdns_sd.dll "$(DSTROOT)\WINDOWS\system32\Win32"
+ @copy $(BUILDDIR)\dns_sd.jar "$(DSTROOT)\Program Files\Bonjour\Win32"
+ @:CONT
+ @if not exist root mkdir root
@if not exist root\"Program Files" mkdir root\"Program Files"
@if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
copy $(BUILDDIR)\dns_sd.jar $(INSTALLDIR)
$(OBJDIR)\com\apple\dnssd\DNSRecord.class \
$(OBJDIR)\com\apple\dnssd\TXTRecord.class \
$(OBJDIR)\com\apple\dnssd\DNSSDRegistration.class \
+ $(OBJDIR)\com\apple\dnssd\DNSSDRecordRegistrar.class \
$(OBJDIR)\com\apple\dnssd\BaseListener.class \
$(OBJDIR)\com\apple\dnssd\BrowseListener.class \
$(OBJDIR)\com\apple\dnssd\ResolveListener.class \
$(OBJDIR)\com\apple\dnssd\RegisterListener.class \
+ $(OBJDIR)\com\apple\dnssd\RegisterRecordListener.class \
$(OBJDIR)\com\apple\dnssd\QueryListener.class \
$(OBJDIR)\com\apple\dnssd\DomainListener.class \
- $(OBJDIR)\com\apple\dnssd\DNSSDRecordRegistrar.class \
- $(OBJDIR)\com\apple\dnssd\RegisterRecordListener.class \
$(OBJDIR)\com\apple\dnssd\DNSSD.class
$(BUILDDIR)\dns_sd.jar: $(JARCONTENTS)
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="NSPTool"\r
ProjectGUID="{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}"\r
- Keyword="Win32Proj">\r
+ Keyword="Win32Proj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- AdditionalIncludeDirectories=".;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
- ExceptionHandling="FALSE"\r
+ AdditionalIncludeDirectories=".;..;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
BasicRuntimeChecks="3"\r
- SmallerTypeCheck="TRUE"\r
+ SmallerTypeCheck="true"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
- EnableFunctionLevelLinking="FALSE"\r
+ BufferSecurityCheck="true"\r
+ EnableFunctionLevelLinking="false"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="4"\r
- CallingConvention="0"/>\r
+ CallingConvention="0"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="..\"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
OutputFile="$(OutDir)/NSPTool.exe"\r
LinkIncremental="2"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/NSPTool.pdb"\r
SubSystem="1"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCPreBuildEventTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCCustomBuildTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories=".;..;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
+ BasicRuntimeChecks="3"\r
+ SmallerTypeCheck="true"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ EnableFunctionLevelLinking="false"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="0"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="..\"/>\r
+ AdditionalIncludeDirectories="..\"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
+ OutputFile="$(OutDir)/NSPTool.exe"\r
+ LinkIncremental="2"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/NSPTool.pdb"\r
+ SubSystem="1"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=".;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN"\r
+ AdditionalIncludeDirectories=".;..;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"\r
RuntimeLibrary="0"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="3"/>\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="..\"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
OutputFile="$(OutDir)/NSPTool.exe"\r
LinkIncremental="1"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="1"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCCustomBuildTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=".;..;../../mDNSShared"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="..\"/>\r
+ AdditionalIncludeDirectories="..\"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
+ OutputFile="$(OutDir)/NSPTool.exe"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="1"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Filter\r
Name="Source Files"\r
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\NSPTool.c">\r
+ RelativePath=".\NSPTool.c"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\CommonServices.h">\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.h">\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\resource.h">\r
+ RelativePath=".\resource.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
<File\r
- RelativePath=".\NSPTool.rc">\r
+ RelativePath=".\NSPTool.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
Change History (most recent first):
$Log: RegNames.h,v $
+Revision 1.5 2009/03/30 21:47:35 herscher
+Fix file corruption during previous checkin
+
Revision 1.3 2006/08/14 23:25:20 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#if defined(UNICODE)
-# define kServiceParametersNode L"SOFTWARE\\Apple Computer, Inc.\\Bonjour"
+# define kServiceParametersSoftware L"SOFTWARE"
+# define kServiceParametersAppleComputer L"Apple Computer, Inc."
+# define kServiceParametersBonjour L"Bonjour"
+# define kServiceParametersNode L"SOFTWARE\\Apple Inc.\\Bonjour"
# define kServiceName L"Bonjour Service"
# define kServiceDynDNSBrowseDomains L"BrowseDomains"
# define kServiceDynDNSHostNames L"HostNames"
# else
-# define kServiceParametersNode "SOFTWARE\\Apple Computer, Inc.\\Bonjour"
+# define kServiceParametersSoftware "SOFTWARE"
+# define kServiceParametersAppleComputer "Apple Computer, Inc."
+# define kServiceParametersBonjour "Bonjour"
+# define kServiceParametersNode "SOFTWARE\\Apple Inc.\\Bonjour"
# define kServiceName "Bonjour Service"
# define kServiceDynDNSBrowseDomains "BrowseDomains"
# define kServiceDynDNSHostNames "HostNames"
--- /dev/null
+/* -*- 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: Secret.c,v $
+Revision 1.2 2009/06/25 21:11:52 herscher
+Fix compilation error when building Control Panel.
+
+Revision 1.1 2009/06/22 23:25:04 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
+
+*/
+
+#include "Secret.h"
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <process.h>
+#include <ntsecapi.h>
+#include <lm.h>
+#include "DebugServices.h"
+
+
+mDNSlocal OSStatus MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input );
+mDNSlocal OSStatus MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input );
+
+
+BOOL
+LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, char * outKey, unsigned outKeyLength, char * outSecret, unsigned outSecretLength )
+{
+ PLSA_UNICODE_STRING domainLSA;
+ PLSA_UNICODE_STRING keyLSA;
+ PLSA_UNICODE_STRING secretLSA;
+ size_t i;
+ size_t dlen;
+ LSA_OBJECT_ATTRIBUTES attrs;
+ LSA_HANDLE handle = NULL;
+ NTSTATUS res;
+ OSStatus err;
+
+ check( inDomain );
+ check( outDomain );
+ check( outKey );
+ check( outSecret );
+
+ // Initialize
+
+ domainLSA = NULL;
+ keyLSA = NULL;
+ secretLSA = NULL;
+
+ // 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';
+ }
+
+ // 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
+ }
+
+ // attrs are reserved, so initialize to zeroes.
+
+ ZeroMemory( &attrs, sizeof( attrs ) );
+
+ // Get a handle to the Policy object on the local system
+
+ res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle );
+ err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+ require_noerr( err, exit );
+
+ // Get the encrypted data
+
+ domainLSA = ( PLSA_UNICODE_STRING ) malloc( sizeof( LSA_UNICODE_STRING ) );
+ require_action( domainLSA != NULL, exit, err = mStatus_NoMemoryErr );
+ err = MakeLsaStringFromUTF8String( domainLSA, outDomain );
+ require_noerr( err, exit );
+
+ // Retrieve the key
+
+ res = LsaRetrievePrivateData( handle, domainLSA, &keyLSA );
+ err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+ require_noerr_quiet( err, exit );
+
+ // <rdar://problem/4192119> 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.
+
+ // Strip off the "$" prefix.
+
+ err = MakeUTF8StringFromLsaString( outKey, outKeyLength, keyLSA );
+ require_noerr( err, exit );
+ require_action( outKey[0] == '$', exit, err = kUnknownErr );
+ memcpy( outKey, outKey + 1, strlen( outKey ) );
+
+ // Retrieve the secret
+
+ res = LsaRetrievePrivateData( handle, keyLSA, &secretLSA );
+ err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+ require_noerr_quiet( err, exit );
+
+ // Convert the secret to UTF8 string
+
+ err = MakeUTF8StringFromLsaString( outSecret, outSecretLength, secretLSA );
+ require_noerr( err, exit );
+
+exit:
+
+ if ( domainLSA != NULL )
+ {
+ if ( domainLSA->Buffer != NULL )
+ {
+ free( domainLSA->Buffer );
+ }
+
+ free( domainLSA );
+ }
+
+ if ( keyLSA != NULL )
+ {
+ LsaFreeMemory( keyLSA );
+ }
+
+ if ( secretLSA != NULL )
+ {
+ LsaFreeMemory( secretLSA );
+ }
+
+ if ( handle )
+ {
+ LsaClose( handle );
+ handle = NULL;
+ }
+
+ return ( !err ) ? TRUE : FALSE;
+}
+
+
+mDNSBool
+LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret )
+{
+ size_t inDomainLength;
+ size_t inKeyLength;
+ char domain[ 1024 ];
+ char key[ 1024 ];
+ LSA_OBJECT_ATTRIBUTES attrs;
+ LSA_HANDLE handle = NULL;
+ NTSTATUS res;
+ LSA_UNICODE_STRING lucZoneName;
+ LSA_UNICODE_STRING lucKeyName;
+ LSA_UNICODE_STRING lucSecretName;
+ BOOL ok = TRUE;
+ OSStatus err;
+
+ require_action( inDomain != NULL, exit, ok = FALSE );
+ 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 );
+
+ if ( domain[ strlen( domain ) - 1 ] != '.' )
+ {
+ domain[ strlen( domain ) - 1 ] = '.';
+ }
+
+ // <rdar://problem/4192119>
+ //
+ // Prepend "$" to the key name, so that there will
+ // be no conflict between the zone name and the key
+ // name
+
+ ZeroMemory( key, sizeof( key ) );
+ key[ 0 ] = '$';
+ strcpy_s( key + 1, sizeof( key ) - 1, inKey );
+
+ if ( key[ strlen( key ) - 1 ] != '.' )
+ {
+ key[ strlen( key ) - 1 ] = '.';
+ }
+
+ // attrs are reserved, so initialize to zeroes.
+
+ ZeroMemory( &attrs, sizeof( attrs ) );
+
+ // Get a handle to the Policy object on the local system
+
+ res = LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle );
+ err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+ require_noerr( err, exit );
+
+ // Intializing PLSA_UNICODE_STRING structures
+
+ ok = MakeLsaStringFromUTF8String( &lucZoneName, domain );
+ err = translate_errno( ok, errno_compat(), kUnknownErr );
+ require_noerr( err, exit );
+
+ ok = MakeLsaStringFromUTF8String( &lucKeyName, key );
+ err = translate_errno( ok, errno_compat(), kUnknownErr );
+ require_noerr( err, exit );
+
+ ok = MakeLsaStringFromUTF8String( &lucSecretName, inSecret );
+ err = translate_errno( ok, errno_compat(), kUnknownErr );
+ require_noerr( err, exit );
+
+ // Store the private data.
+
+ res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName );
+ err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+ require_noerr( err, exit );
+
+ res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName );
+ err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+ require_noerr( err, exit );
+
+exit:
+
+ if ( handle )
+ {
+ LsaClose( handle );
+ handle = NULL;
+ }
+
+ return ok;
+}
+
+
+//===========================================================================================================================
+// MakeLsaStringFromUTF8String
+//===========================================================================================================================
+
+mDNSlocal OSStatus
+MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input )
+{
+ int size;
+ OSStatus err;
+
+ check( input );
+ check( output );
+
+ output->Buffer = NULL;
+
+ size = MultiByteToWideChar( CP_UTF8, 0, input, -1, NULL, 0 );
+ err = translate_errno( size > 0, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ output->Length = (USHORT)( size * sizeof( wchar_t ) );
+ output->Buffer = (PWCHAR) malloc( output->Length );
+ require_action( output->Buffer, exit, err = mStatus_NoMemoryErr );
+ size = MultiByteToWideChar( CP_UTF8, 0, input, -1, output->Buffer, size );
+ err = translate_errno( size > 0, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ // We're going to subtrace one wchar_t from the size, because we didn't
+ // include it when we encoded the string
+
+ output->MaximumLength = output->Length;
+ output->Length -= sizeof( wchar_t );
+
+exit:
+
+ if ( err && output->Buffer )
+ {
+ free( output->Buffer );
+ output->Buffer = NULL;
+ }
+
+ return( err );
+}
+
+
+
+//===========================================================================================================================
+// MakeUTF8StringFromLsaString
+//===========================================================================================================================
+
+mDNSlocal OSStatus
+MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input )
+{
+ size_t size;
+ OSStatus err = kNoErr;
+
+ // The Length field of this structure holds the number of bytes,
+ // but WideCharToMultiByte expects the number of wchar_t's. So
+ // we divide by sizeof(wchar_t) to get the correct number.
+
+ size = (size_t) WideCharToMultiByte(CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), NULL, 0, NULL, NULL);
+ err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ // Ensure that we have enough space (Add one for trailing '\0')
+
+ require_action( ( size + 1 ) <= len, exit, err = mStatus_NoMemoryErr );
+
+ // Convert the string
+
+ size = (size_t) WideCharToMultiByte( CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), output, (int) size, NULL, NULL);
+ err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ // have to add the trailing 0 because WideCharToMultiByte doesn't do it,
+ // although it does return the correct size
+
+ output[size] = '\0';
+
+exit:
+
+ return err;
+}
+
--- /dev/null
+/* -*- 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: Secret.h,v $
+Revision 1.2 2009/06/25 21:11:52 herscher
+Fix compilation error when building Control Panel.
+
+Revision 1.1 2009/06/22 23:25:04 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
+
+*/
+
+#ifndef _Secret_h
+#define _Secret_h
+
+#include "mDNSEmbeddedAPI.h"
+
+
+#if defined(__cplusplus )
+extern "C" {
+#endif
+
+
+extern mDNSBool
+LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, char * outKey, unsigned outKeyLength, char * outSecret, unsigned outSecretLength );
+
+
+extern mDNSBool
+LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret );
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif
\ No newline at end of file
Change History (most recent first):
$Log: Firewall.cpp,v $
+Revision 1.6 2009/04/24 04:55:26 herscher
+<rdar://problem/3496833> Advertise SMB file sharing via Bonjour
+
+Revision 1.5 2009/03/30 20:39:29 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5712486> Put in extra defensive checks to prevent NULL pointer dereferencing crash
+<rdar://problem/5187308> Move build train to Visual Studio 2005
+
Revision 1.4 2006/08/14 23:26:07 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#endif
-#if !defined(_WSPIAPI_COUNTOF)
-# define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
-#endif
-
#include "Firewall.h"
#include <windows.h>
#include <crtdbg.h>
// call will fail on anything other than XP SP2
err = CoCreateInstance( __uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&fwMgr );
- require(SUCCEEDED(err), exit);
+ require(SUCCEEDED(err) && ( fwMgr != NULL ), exit);
// Use the reference to get the local firewall policy
err = fwMgr->get_LocalPolicy(&fwPolicy);
- require(SUCCEEDED(err), exit);
+ require(SUCCEEDED(err) && ( fwPolicy != NULL ), exit);
// Use the reference to get the extant profile. Empirical evidence
// suggests that there is the potential for a race condition when a system
// Get the list of authorized applications
err = fwProfile->get_AuthorizedApplications(&fwApps);
- require(SUCCEEDED(err), exit);
+ require(SUCCEEDED(err) && ( fwApps != NULL ), exit);
fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName);
- require_action(SysStringLen(fwBstrProcessImageFileName) > 0, exit, err = kNoMemoryErr);
+ require_action( ( fwProcessImageFileName != NULL ) && ( SysStringLen(fwBstrProcessImageFileName) > 0 ), exit, err = kNoMemoryErr);
// Look for us
err = fwApps->Item(fwBstrProcessImageFileName, &fwApp);
- if (SUCCEEDED(err))
+ if (SUCCEEDED(err) && ( fwApp != NULL ) )
{
// It's listed, but is it enabled?
// Deallocate the BSTR
- SysFreeString(fwBstrProcessImageFileName);
+ if ( fwBstrProcessImageFileName != NULL )
+ {
+ SysFreeString(fwBstrProcessImageFileName);
+ }
// Release the COM objects
// Get the list of authorized applications
err = fwProfile->get_AuthorizedApplications(&fwApps);
- require(SUCCEEDED(err), exit);
+ require(SUCCEEDED(err) && ( fwApps != NULL ), exit);
// Create an instance of an authorized application.
err = CoCreateInstance( __uuidof(NetFwAuthorizedApplication), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwAuthorizedApplication), (void**)&fwApp );
- require(SUCCEEDED(err), exit);
+ require(SUCCEEDED(err) && ( fwApp != NULL ), exit);
fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName);
- require_action(SysStringLen(fwBstrProcessImageFileName) > 0, exit, err = kNoMemoryErr);
+ require_action(( fwProcessImageFileName != NULL ) && ( SysStringLen(fwBstrProcessImageFileName) > 0 ), exit, err = kNoMemoryErr);
// Set the executable file name
require(SUCCEEDED(err), exit);
fwBstrName = SysAllocString(fwName);
- require_action(SysStringLen(fwBstrName) > 0, exit, err = kNoMemoryErr);
+ require_action( ( fwBstrName != NULL ) && ( SysStringLen(fwBstrName) > 0 ), exit, err = kNoMemoryErr);
// Set the friendly name
// Deallocate the BSTR objects
- SysFreeString(fwBstrName);
- SysFreeString(fwBstrProcessImageFileName);
+ if ( fwBstrName != NULL )
+ {
+ SysFreeString(fwBstrName);
+ }
+
+ if ( fwBstrProcessImageFileName != NULL )
+ {
+ SysFreeString(fwBstrProcessImageFileName);
+ }
// Release the COM objects
}
return err;
+}\r
+\r
+\r
+static OSStatus\r
+mDNSFirewallIsFileAndPrintSharingEnabled\r
+ (\r
+ IN INetFwProfile * fwProfile,\r
+ OUT BOOL * fwServiceEnabled\r
+ )\r
+{\r
+ VARIANT_BOOL fwEnabled;\r
+ INetFwService* fwService = NULL;\r
+ INetFwServices* fwServices = NULL;\r
+ OSStatus err = S_OK;\r
+\r
+ _ASSERT(fwProfile != NULL);\r
+ _ASSERT(fwServiceEnabled != NULL);\r
+\r
+ *fwServiceEnabled = FALSE;\r
+\r
+ // Retrieve the globally open ports collection.\r
+ err = fwProfile->get_Services(&fwServices);\r
+ require( SUCCEEDED( err ), exit );\r
+\r
+ // Attempt to retrieve the globally open port.\r
+ err = fwServices->Item(NET_FW_SERVICE_FILE_AND_PRINT, &fwService);\r
+ require( SUCCEEDED( err ), exit );\r
+ \r
+ // Find out if the globally open port is enabled.\r
+ err = fwService->get_Enabled(&fwEnabled);\r
+ require( SUCCEEDED( err ), exit );\r
+ if (fwEnabled != VARIANT_FALSE)\r
+ {\r
+ *fwServiceEnabled = TRUE;\r
+ }\r
+\r
+exit:\r
+\r
+ // Release the globally open port.\r
+ if (fwService != NULL)\r
+ {\r
+ fwService->Release();\r
+ }\r
+\r
+ // Release the globally open ports collection.\r
+ if (fwServices != NULL)\r
+ {\r
+ fwServices->Release();\r
+ }\r
+\r
+ return err;\r
}
// Connect to the firewall
err = mDNSFirewallInitialize(&fwProfile);
- require_noerr(err, exit);
+ require( SUCCEEDED( err ) && ( fwProfile != NULL ), exit);
// Add us to the list of exempt programs
// Disconnect from the firewall
- mDNSFirewallCleanup(fwProfile);
+ if ( fwProfile != NULL )
+ {
+ mDNSFirewallCleanup(fwProfile);
+ }
// De-initialize COM
return err;
}
+
+
+BOOL
+mDNSIsFileAndPrintSharingEnabled()
+{
+ INetFwProfile * fwProfile = NULL;
+ HRESULT comInit = E_FAIL;
+ BOOL enabled = FALSE;
+ OSStatus err = kNoErr;
+
+ // Initialize COM.
+
+ comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE );
+
+ // Ignore this case. RPC_E_CHANGED_MODE means that COM has already been
+ // initialized with a different mode.
+
+ if (comInit != RPC_E_CHANGED_MODE)
+ {
+ err = comInit;
+ require(SUCCEEDED(err), exit);
+ }
+
+ // Connect to the firewall
+
+ err = mDNSFirewallInitialize(&fwProfile);
+ require( SUCCEEDED( err ) && ( fwProfile != NULL ), exit);
+
+ err = mDNSFirewallIsFileAndPrintSharingEnabled( fwProfile, &enabled );
+ require_noerr( err, exit );
+
+exit:
+
+ // Disconnect from the firewall
+
+ if ( fwProfile != NULL )
+ {
+ mDNSFirewallCleanup(fwProfile);
+ }
+
+ // De-initialize COM
+
+ if (SUCCEEDED(comInit))
+ {
+ CoUninitialize();
+ }
+
+ return enabled;
+}
Change History (most recent first):
$Log: Firewall.h,v $
+Revision 1.3 2009/04/24 04:55:26 herscher
+<rdar://problem/3496833> Advertise SMB file sharing via Bonjour
+
Revision 1.2 2006/08/14 23:26:07 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
);
+BOOL
+mDNSIsFileAndPrintSharingEnabled();
+
+
Change History (most recent first):
$Log: Service.c,v $
+Revision 1.46 2009/06/05 18:28:24 herscher
+<rdar://problem/6125087> mDNSResponder should be able to identify VPN adapters generically
+<rdar://problem/6885843> WIN7: Bonjour removes the default gateway entry and thereby breaks network connectivity
+
+Revision 1.45 2009/04/30 20:07:51 mcguire
+<rdar://problem/6822674> Support multiple UDSs from launchd
+
+Revision 1.44 2009/03/30 20:41:36 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/6330821> Bonjour for Windows incompatible w/Juniper Network Connect. Do a substring search for "Juniper" in the description field
+ of the network adapter.
+<rdar://problem/6122028> Bonjour for Windows incompatible w/Cisco AnyConnect VPN Client
+<rdar://problem/5652098> Bonjour for Windows incompatible w/Juniper Network Connect. Update the adapter name per info received from Juniper
+<rdar://problem/5781566> Core: Default Gateway set to 0.0.0.0 on Vista causes ARP flood
+<rdar://problem/5991983> Change the registry values from Apple Computer, Inc. to Apple Inc.
+<rdar://problem/5301328> wchar/sizeof mismatch in CheckFirewall()
+
+Revision 1.43 2009/01/13 05:31:35 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
Revision 1.42 2007/02/14 01:58:19 cheshire
<rdar://problem/4995831> Don't delete Unix Domain Socket on exit if we didn't create it on startup
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
+#include <stddef.h>
#include "CommonServices.h"
#include <mswsock.h>
#include <process.h>
#include <ipExport.h>
+ #include <ws2def.h>
+ #include <ws2ipdef.h>
#include <iphlpapi.h>
+ #include <netioapi.h>
#include <iptypes.h>
#endif
+#ifndef HeapEnableTerminationOnCorruption
+# define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1
+#endif
+
#if 0
#pragma mark == Constants ==
#endif
#define kServiceDependencies TEXT("Tcpip\0\0")
#define kDNSServiceCacheEntryCountDefault 512
#define kRetryFirewallPeriod 30 * 1000
+#define kDefValueSize MAX_PATH + 1
+#define kZeroIndex 0
+#define kDefaultRouteMetric 399
#define RR_CACHE_SIZE 500
static CacheEntity gRRCache[RR_CACHE_SIZE];
static void HostDescriptionChanged(mDNS * const inMDNS);
static OSStatus GetRouteDestination(DWORD * ifIndex, DWORD * address);
static OSStatus SetLLRoute( mDNS * const inMDNS );
-static bool HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr );
+static bool HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric );
static bool IsValidAddress( const char * addr );
+static bool IsNortelVPN( IP_ADAPTER_INFO * pAdapter );
+static bool IsJuniperVPN( IP_ADAPTER_INFO * pAdapter );
+static bool IsCiscoVPN( IP_ADAPTER_INFO * pAdapter );
+static const char * strnistr( const char * string, const char * subString, size_t max );
#if defined(UNICODE)
# define StrLen(X) wcslen(X)
DEBUG_LOCAL CRITICAL_SECTION gEventSourceLock;
DEBUG_LOCAL GenLinkedList gEventSources;
DEBUG_LOCAL BOOL gRetryFirewall = FALSE;
+DEBUG_LOCAL DWORD gOSMajorVersion;
+DEBUG_LOCAL DWORD gOSMinorVersion;
+
+typedef DWORD ( WINAPI * GetIpInterfaceEntryFunctionPtr )( PMIB_IPINTERFACE_ROW );
+mDNSlocal HMODULE gIPHelperLibraryInstance = NULL;
+mDNSlocal GetIpInterfaceEntryFunctionPtr gGetIpInterfaceEntryFunctionPtr = NULL;
#if 0
BOOL ok;
BOOL start;
int i;
+
+ HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
debug_initialize( kDebugOutputTypeMetaConsole );
debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
// Get a full path to the executable
- size = GetModuleFileNameW( NULL, fullPath, sizeof( fullPath ) );
+ size = GetModuleFileNameW( NULL, fullPath, MAX_PATH );
err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
require_noerr( err, exit );
initialized = FALSE;
- // Initialize the service-specific stuff and mark the service as running.
+ // <rdar://problem/5727548> Make the service as running before we call ServiceSpecificInitialize. We've
+ // had reports that some machines with McAfee firewall installed cause a problem with iTunes installation.
+ // We think that the firewall product is interferring with code in ServiceSpecificInitialize. So as a
+ // simple workaround, we'll mark us as running *before* we call ServiceSpecificInitialize. This will unblock
+ // any installers that are waiting for our state to change.
+
+ gServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
+ check_translated_errno( ok, GetLastError(), kParamErr );
+
+ // Initialize the service-specific stuff
err = ServiceSpecificInitialize( argc, argv );
require_noerr( err, exit );
initialized = TRUE;
- gServiceStatus.dwCurrentState = SERVICE_RUNNING;
- ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
- check_translated_errno( ok, GetLastError(), kParamErr );
-
err = CheckFirewall();
check_noerr( err );
static OSStatus ServiceSpecificInitialize( int argc, LPTSTR argv[] )
{
- OSStatus err;
+ OSVERSIONINFO osInfo;
+ OSStatus err;
+ BOOL ok;
DEBUG_UNUSED( argc );
DEBUG_UNUSED( argv );
- memset( &gMDNSRecord, 0, sizeof gMDNSRecord);
- memset( &gPlatformStorage, 0, sizeof gPlatformStorage);
+ mDNSPlatformMemZero( &gMDNSRecord, sizeof gMDNSRecord);
+ mDNSPlatformMemZero( &gPlatformStorage, sizeof gPlatformStorage);
gPlatformStorage.idleThreadCallback = udsIdle;
gPlatformStorage.hostDescriptionChangedCallback = HostDescriptionChanged;
err = mDNS_Init( &gMDNSRecord, &gPlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, CoreCallback, mDNS_Init_NoInitCallbackContext);
require_noerr( err, exit);
- err = udsserver_init(dnssd_InvalidSocket);
+ err = udsserver_init(mDNSNULL, 0);
require_noerr( err, exit);
//
- // <rdar://problem/4096464> Don't call SetLLRoute on loopback
- //
- // Otherwise, set a route to link local addresses (169.254.0.0)
+ // Get the version of Windows that we're running on
//
+ osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+ ok = GetVersionEx( &osInfo );
+ err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+ gOSMajorVersion = osInfo.dwMajorVersion;
+ gOSMinorVersion = osInfo.dwMinorVersion;
- if ( gServiceManageLLRouting && !gPlatformStorage.registeredLoopback4 )
- {
- SetLLRoute( &gMDNSRecord );
- }
+ SetLLRoute( &gMDNSRecord );
exit:
if( err != kNoErr )
//
// give a chance for the udsserver code to clean up
//
- udsserver_exit(dnssd_InvalidSocket);
+ udsserver_exit();
//
// and finally close down the mDNSCore
// clean up the event sources mutex...no one should be using it now
//
DeleteCriticalSection(&gEventSourceLock);
+
+ //
+ // clean up loaded library
+ //
+
+ if( gIPHelperLibraryInstance )
+ {
+ gGetIpInterfaceEntryFunctionPtr = NULL;
+
+ FreeLibrary( gIPHelperLibraryInstance );
+ gIPHelperLibraryInstance = NULL;
+ }
}
{
if (status == mStatus_ConfigChanged)
{
- //
- // <rdar://problem/4096464> Don't call SetLLRoute on loopback
- //
- // Otherwise, set a route to link local addresses (169.254.0.0)
- //
-
- if ( gServiceManageLLRouting && !inMDNS->p->registeredLoopback4 )
- {
- SetLLRoute( inMDNS );
- }
+ SetLLRoute( inMDNS );
}
}
//
if (result == WAIT_OBJECT_0)
{
- source->callback(source->context);
+ source->callback( (int) source->sock, 0, source->context);
}
//
// close event
// so we'll go in here and it will clean up for us
//
shutdown(source->sock, 2);
- source->callback(source->context);
+ source->callback( (int) source->sock, 0, source->context);
break;
}
newSource = malloc(sizeof(Win32EventSource));
require_action( newSource, exit, err = mStatus_NoMemoryErr );
- memset(newSource, 0, sizeof(Win32EventSource));
+ mDNSPlatformMemZero(newSource, sizeof(Win32EventSource));
newSource->flags = 0;
newSource->sock = (SOCKET) fd;
//===========================================================================================================================
static bool
-HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr )
+HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric )
{
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
DWORD dwSize = 0;
//
for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
{
- if ( pIpForwardTable->table[i].dwForwardDest == addr )
+ if ( ( pIpForwardTable->table[i].dwForwardDest == addr ) && ( !metric || ( pIpForwardTable->table[i].dwForwardMetric1 == metric ) ) )
{
memcpy( rowExtant, &(pIpForwardTable->table[i]), sizeof(*rowExtant) );
found = true;
//===========================================================================================================================
-// SetLLRoute
+// GetAdditionalMetric
//===========================================================================================================================
-static OSStatus
-SetLLRoute( mDNS * const inMDNS )
+static ULONG
+GetAdditionalMetric( DWORD ifIndex )
{
- DWORD ifIndex;
- MIB_IPFORWARDROW rowExtant;
- bool addRoute;
- MIB_IPFORWARDROW row;
- OSStatus err;
+ ULONG metric = 0;
- ZeroMemory(&row, sizeof(row));
-
- err = GetRouteDestination(&ifIndex, &row.dwForwardNextHop);
- require_noerr( err, exit );
- row.dwForwardDest = inet_addr(kLLNetworkAddr);
- row.dwForwardIfIndex = ifIndex;
- row.dwForwardMask = inet_addr(kLLNetworkAddrMask);
- row.dwForwardType = 3;
- row.dwForwardProto = MIB_IPPROTO_NETMGMT;
- row.dwForwardAge = 0;
- row.dwForwardPolicy = 0;
- row.dwForwardMetric1 = 30;
- row.dwForwardMetric2 = (DWORD) - 1;
- row.dwForwardMetric3 = (DWORD) - 1;
- row.dwForwardMetric4 = (DWORD) - 1;
- row.dwForwardMetric5 = (DWORD) - 1;
-
- addRoute = true;
-
- //
- // check to make sure we don't already have a route
- //
- if ( HaveRoute( &rowExtant, inet_addr( kLLNetworkAddr ) ) )
+ if( !gIPHelperLibraryInstance )
{
- //
- // set the age to 0 so that we can do a memcmp.
- //
- rowExtant.dwForwardAge = 0;
+ gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
- //
- // check to see if this route is the same as our route
- //
- if (memcmp(&row, &rowExtant, sizeof(row)) != 0)
- {
- //
- // if it isn't then delete this entry
- //
- DeleteIpForwardEntry(&rowExtant);
- }
- else
- {
- //
- // else it is, so we don't want to create another route
- //
- addRoute = false;
+ gGetIpInterfaceEntryFunctionPtr =
+ (GetIpInterfaceEntryFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetIpInterfaceEntry" );
+
+ if( !gGetIpInterfaceEntryFunctionPtr )
+ {
+ BOOL ok;
+
+ ok = FreeLibrary( gIPHelperLibraryInstance );
+ check_translated_errno( ok, GetLastError(), kUnknownErr );
+ gIPHelperLibraryInstance = NULL;
}
}
- if (addRoute && row.dwForwardNextHop)
+ if ( gGetIpInterfaceEntryFunctionPtr )
{
- err = CreateIpForwardEntry(&row);
+ MIB_IPINTERFACE_ROW row;
+ DWORD err;
+ ZeroMemory( &row, sizeof( MIB_IPINTERFACE_ROW ) );
+ row.Family = AF_INET;
+ row.InterfaceIndex = ifIndex;
+ err = gGetIpInterfaceEntryFunctionPtr( &row );
require_noerr( err, exit );
+ metric = row.Metric + 256;
}
+exit:
+
+ return metric;
+}
+
+
+//===========================================================================================================================
+// SetLLRoute
+//===========================================================================================================================
+
+static OSStatus
+SetLLRoute( mDNS * const inMDNS )
+{
+ OSStatus err = kNoErr;
+
+ DEBUG_UNUSED( inMDNS );
+
//
- // Now we want to see if we should install a default route for this interface.
- // We want to do this if the following are true:
- //
- // 1. This interface has a link-local address
- // 2. This is the only IPv4 interface
+ // <rdar://problem/4096464> Don't call SetLLRoute on loopback
+ // <rdar://problem/6885843> Default route on Windows 7 breaks network connectivity
+ //
+ // Don't mess w/ the routing table on Vista and later OSes, as
+ // they have a permanent route to link-local addresses. Otherwise,
+ // set a route to link local addresses (169.254.0.0)
//
-
- if ( ( row.dwForwardNextHop & 0xFFFF ) == row.dwForwardDest )
+ if ( ( gOSMajorVersion < 6 ) && gServiceManageLLRouting && !gPlatformStorage.registeredLoopback4 )
{
- mDNSInterfaceData * ifd;
- int numLinkLocalInterfaces = 0;
- int numInterfaces = 0;
-
- for ( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
- {
- if ( ifd->defaultAddr.type == mDNSAddrType_IPv4 )
- {
- numInterfaces++;
+ DWORD ifIndex;
+ MIB_IPFORWARDROW rowExtant;
+ bool addRoute;
+ MIB_IPFORWARDROW row;
- if ( ( ifd->interfaceInfo.ip.ip.v4.b[0] == 169 ) && ( ifd->interfaceInfo.ip.ip.v4.b[1] == 254 ) )
- {
- numLinkLocalInterfaces++;
- }
- }
- }
+ ZeroMemory(&row, sizeof(row));
- row.dwForwardDest = 0;
+ err = GetRouteDestination(&ifIndex, &row.dwForwardNextHop);
+ require_noerr( err, exit );
+ row.dwForwardDest = inet_addr(kLLNetworkAddr);
row.dwForwardIfIndex = ifIndex;
- row.dwForwardMask = 0;
+ row.dwForwardMask = inet_addr(kLLNetworkAddrMask);
row.dwForwardType = 3;
row.dwForwardProto = MIB_IPPROTO_NETMGMT;
row.dwForwardAge = 0;
row.dwForwardPolicy = 0;
- row.dwForwardMetric1 = 20;
+ row.dwForwardMetric1 = 20 + GetAdditionalMetric( ifIndex );
row.dwForwardMetric2 = (DWORD) - 1;
row.dwForwardMetric3 = (DWORD) - 1;
row.dwForwardMetric4 = (DWORD) - 1;
row.dwForwardMetric5 = (DWORD) - 1;
-
- if ( numInterfaces == numLinkLocalInterfaces )
+
+ addRoute = true;
+
+ //
+ // check to make sure we don't already have a route
+ //
+ if ( HaveRoute( &rowExtant, inet_addr( kLLNetworkAddr ), 0 ) )
{
- if ( !HaveRoute( &row, 0 ) )
+ //
+ // set the age to 0 so that we can do a memcmp.
+ //
+ rowExtant.dwForwardAge = 0;
+
+ //
+ // check to see if this route is the same as our route
+ //
+ if (memcmp(&row, &rowExtant, sizeof(row)) != 0)
{
- err = CreateIpForwardEntry(&row);
- require_noerr( err, exit );
+ //
+ // if it isn't then delete this entry
+ //
+ DeleteIpForwardEntry(&rowExtant);
+ }
+ else
+ {
+ //
+ // else it is, so we don't want to create another route
+ //
+ addRoute = false;
}
}
- else
+
+ if (addRoute && row.dwForwardNextHop)
{
- DeleteIpForwardEntry( &row );
+ err = CreateIpForwardEntry(&row);
+ check_noerr( err );
}
}
err = kUnknownErr;
// <rdar://problem/3718122>
+ // <rdar://problem/5652098>
//
- // Look for the Nortel VPN virtual interface. This interface
- // is identified by it's unique MAC address: 44-45-53-54-42-00
+ // Look for the Nortel VPN virtual interface, along with Juniper virtual interface.
//
- // If the interface is active (i.e., has a non-zero IP Address),
+ // If these interfaces are active (i.e., has a non-zero IP Address),
// then we want to disable routing table modifications.
while (pAdapter)
{
- if ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
- (pAdapter->AddressLength == 6) &&
- (pAdapter->Address[0] == 0x44) &&
- (pAdapter->Address[1] == 0x45) &&
- (pAdapter->Address[2] == 0x53) &&
- (pAdapter->Address[3] == 0x54) &&
- (pAdapter->Address[4] == 0x42) &&
- (pAdapter->Address[5] == 0x00) &&
- (inet_addr( pAdapter->IpAddressList.IpAddress.String ) != 0))
+ if ( ( IsNortelVPN( pAdapter ) || IsJuniperVPN( pAdapter ) || IsCiscoVPN( pAdapter ) ) &&
+ ( inet_addr( pAdapter->IpAddressList.IpAddress.String ) != 0 ) )
{
+ dlog( kDebugLevelTrace, DEBUG_NAME "disabling routing table management due to VPN incompatibility" );
goto exit;
}
return( err );
}
+
+
+static bool
+IsNortelVPN( IP_ADAPTER_INFO * pAdapter )
+{
+ return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
+ (pAdapter->AddressLength == 6) &&
+ (pAdapter->Address[0] == 0x44) &&
+ (pAdapter->Address[1] == 0x45) &&
+ (pAdapter->Address[2] == 0x53) &&
+ (pAdapter->Address[3] == 0x54) &&
+ (pAdapter->Address[4] == 0x42) &&
+ (pAdapter->Address[5] == 0x00)) ? true : false;
+}
+
+
+static bool
+IsJuniperVPN( IP_ADAPTER_INFO * pAdapter )
+{
+ return ( strnistr( pAdapter->Description, "Juniper", sizeof( pAdapter->Description ) ) != NULL ) ? true : false;
+}
+
+
+static bool
+IsCiscoVPN( IP_ADAPTER_INFO * pAdapter )
+{
+ return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
+ (pAdapter->AddressLength == 6) &&
+ (pAdapter->Address[0] == 0x00) &&
+ (pAdapter->Address[1] == 0x05) &&
+ (pAdapter->Address[2] == 0x9a) &&
+ (pAdapter->Address[3] == 0x3c) &&
+ (pAdapter->Address[4] == 0x7a) &&
+ (pAdapter->Address[5] == 0x00)) ? true : false;
+}
+
+
+static const char *
+strnistr( const char * string, const char * subString, size_t max )
+{
+ size_t subStringLen;
+ size_t offset;
+ size_t maxOffset;
+ size_t stringLen;
+ const char * pPos;
+
+ if ( ( string == NULL ) || ( subString == NULL ) )
+ {
+ return string;
+ }
+
+ stringLen = ( max > strlen( string ) ) ? strlen( string ) : max;
+
+ if ( stringLen == 0 )
+ {
+ return NULL;
+ }
+
+ subStringLen = strlen( subString );
+
+ if ( subStringLen == 0 )
+ {
+ return string;
+ }
+
+ if ( subStringLen > stringLen )
+ {
+ return NULL;
+ }
+
+ maxOffset = stringLen - subStringLen;
+ pPos = string;
+
+ for ( offset = 0; offset <= maxOffset; offset++ )
+ {
+ if ( _strnicmp( pPos, subString, subStringLen ) == 0 )
+ {
+ return pPos;
+ }
+
+ pPos++;
+ }
+
+ return NULL;
+}
+
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="mDNSResponder"\r
ProjectGUID="{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}"\r
- Keyword="Win32Proj">\r
+ Keyword="Win32Proj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;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"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
- ExceptionHandling="FALSE"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;"C:/Program Files/Microsoft SDKs/Windows/v6.1/Include""\r
+ 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_"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
BasicRuntimeChecks="3"\r
- SmallerTypeCheck="TRUE"\r
+ SmallerTypeCheck="true"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
+ BufferSecurityCheck="true"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"\r
- CallingConvention="2"/>\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ DisableSpecificWarnings="4127"\r
+ ShowIncludes="false"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib netapi32.lib"\r
OutputFile="$(OutDir)/mDNSResponder.exe"\r
LinkIncremental="2"\r
- IgnoreAllDefaultLibraries="FALSE"\r
- GenerateDebugInformation="TRUE"\r
+ IgnoreAllDefaultLibraries="false"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/mDNSResponder.pdb"\r
SubSystem="1"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\mDNSResponder.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCPreBuildEventTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCCustomBuildTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;"C:/Program Files/Microsoft SDKs/Windows/v6.1/Include""\r
+ 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_"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
+ BasicRuntimeChecks="3"\r
+ SmallerTypeCheck="true"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ DisableSpecificWarnings="4127"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib netapi32.lib"\r
+ OutputFile="$(OutDir)/mDNSResponder.exe"\r
+ LinkIncremental="2"\r
+ IgnoreAllDefaultLibraries="false"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/mDNSResponder.pdb"\r
+ SubSystem="1"\r
+ TargetMachine="17"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\mDNSResponder64.manifest"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="1"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0500;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE="""";UNICODE;_UNICODE"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;"C:/Program Files/Microsoft SDKs/Windows/v6.1/Include""\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;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_"\r
RuntimeLibrary="0"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="3"/>\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4127"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="ws2_32.lib iphlpapi.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib netapi32.lib"\r
OutputFile="$(OutDir)/mDNSResponder.exe"\r
LinkIncremental="1"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="1"\r
OptimizeReferences="2"\r
EnableCOMDATFolding="2"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\mDNSResponder.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="1"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;"C:/Program Files/Microsoft SDKs/Windows/v6.1/Include""\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;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_"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ DisableSpecificWarnings="4127"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="ws2_32.lib iphlpapi.lib netapi32.lib"\r
+ OutputFile="$(OutDir)/mDNSResponder.exe"\r
+ LinkIncremental="1"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="1"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ AdditionalManifestFiles="res\mDNSResponder64.manifest"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Filter\r
Name="Source Files"\r
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.c">\r
+ RelativePath="..\..\mDNSCore\DNSCommon.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\DNSCommon.c">\r
+ RelativePath="..\..\mDNSCore\DNSDigest.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\DNSDigest.c">\r
+ RelativePath="..\..\mDNSShared\dnssd_ipc.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_ipc.c">\r
+ RelativePath="Firewall.cpp"\r
+ >\r
</File>\r
<File\r
- RelativePath="Firewall.cpp">\r
+ RelativePath="..\..\mDNSShared\GenLinkedList.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\GenLinkedList.c">\r
+ RelativePath="..\..\mDNSMacOSX\LegacyNATTraversal.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\mDNS.c">\r
+ RelativePath="..\..\mDNSCore\mDNS.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\mDNSDebug.c">\r
+ RelativePath="..\..\mDNSShared\mDNSDebug.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\mDNSWin32.c">\r
+ RelativePath="..\mDNSWin32.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\VPCDetect.cpp">\r
+ RelativePath="..\Secret.c"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\Service.c">\r
+ RelativePath=".\Service.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\uDNS.c">\r
+ RelativePath="..\..\mDNSCore\uDNS.c"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\uds_daemon.c">\r
+ RelativePath="..\..\mDNSShared\uds_daemon.c"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
<File\r
- RelativePath="..\..\mDNSShared\CommonServices.h">\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.h">\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\DNSCommon.h">\r
+ RelativePath="..\..\mDNSCore\DNSCommon.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\dnssd_ipc.h">\r
+ RelativePath="..\..\mDNSShared\dnssd_ipc.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\GenLinkedList.h">\r
+ RelativePath="..\..\mDNSShared\GenLinkedList.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\mDNSDebug.h">\r
+ RelativePath="..\..\mDNSCore\mDNSDebug.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\mDNSEmbeddedAPI.h">\r
+ RelativePath="..\..\mDNSCore\mDNSEmbeddedAPI.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\mDNSWin32.h">\r
+ RelativePath="..\mDNSWin32.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\VPCDetect.h">\r
+ RelativePath=".\Resource.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\Resource.h">\r
+ RelativePath="..\Secret.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSCore\uDNS.h">\r
+ RelativePath="..\..\mDNSCore\uDNS.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\uds_daemon.h">\r
+ RelativePath="..\..\mDNSShared\uds_daemon.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
<File\r
- RelativePath=".\Service.rc">\r
+ RelativePath=".\Service.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.mDNSResponder" type="win32"/>
+ <description>Enables hardware devices and software services to automatically configure themselves and advertise their presence on the network.</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+ <description>Enables hardware devices and software services to automatically configure themselves and advertise their presence on the network.</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
Change History (most recent first):
$Log: WinServices.cpp,v $
+Revision 1.3 2009/06/22 23:25:04 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
Revision 1.2 2006/08/14 23:25:20 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
*/
#include "WinServices.h"
+#include <DebugServices.h>
//===========================================================================================================================
}
return( err );
}
+
+
+//===========================================================================================================================
+// UTF8StringToStringObject
+//===========================================================================================================================
+
+OSStatus
+StringObjectToUTF8String( CString &inObject, char* outUTF8, size_t outUTF8Len )
+{
+ OSStatus err = kNoErr;
+
+ memset( outUTF8, 0, outUTF8Len );
+
+ if ( inObject.GetLength() > 0 )
+ {
+ size_t size;
+
+ size = (size_t) WideCharToMultiByte( CP_UTF8, 0, inObject.GetBuffer(), inObject.GetLength(), outUTF8, (int) outUTF8Len, NULL, NULL);
+ err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+ }
+
+exit:
+
+ return err;
+}
Change History (most recent first):
$Log: WinServices.h,v $
+Revision 1.3 2009/06/22 23:25:05 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
Revision 1.2 2006/08/14 23:25:21 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#include "CommonServices.h"
-OSStatus UTF8StringToStringObject( const char *inUTF8, CString &inObject );
+OSStatus UTF8StringToStringObject( const char *inUTF8, CString &outObject );
+OSStatus StringObjectToUTF8String( CString &inObject, char* outUTF8, size_t outUTF8Len );
Change History (most recent first):
$Log: WinVersRes.h,v $
+Revision 1.61 2009/06/30 17:37:32 herscher
+Bump to 2.0.0.5
+
+Revision 1.60 2009/06/15 18:03:41 herscher
+Bump to version 2.0.0.4
+
+Revision 1.59 2009/05/27 20:14:35 herscher
+Bump version to 2.0.0.3
+
+Revision 1.58 2009/05/26 21:13:35 herscher
+Bump to version 2.0.0.2
+
+Revision 1.57 2009/04/28 20:12:15 herscher
+Bump version to 2.0.0.1
+
+Revision 1.56 2009/04/02 22:04:43 herscher
+Bump to version 2.0.0.0
+
Revision 1.55 2007/04/27 20:34:31 herscher
<rdar://problem/5159673> mDNS: Company name needs to be changed to Apple Inc.
#define MASTER_COMPANY_NAME "Apple Inc."
// Define the product version for mDNSResponder on Windows
-#define MASTER_PROD_VERS 1,0,3,1
-#define MASTER_PROD_VERS_STR "1,0,3,1"
-#define MASTER_PROD_VERS_STR2 "1.0.3.1"
-#define MASTER_PROD_VERS_STR3 "Explorer Plugin 1.0.3.1"
+#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 the legal copyright
-#define MASTER_LEGAL_COPYRIGHT "Copyright (C) 2003-2007 Apple Inc."
+#define MASTER_LEGAL_COPYRIGHT "Copyright (C) 2003-2009 Apple Inc."
#endif // WINRESVERS_H
4, 6, 'd','a', 0 , 0 , 0 , 0 ,
4, 11, 'f','i', 0 , 0 , 0 , 0 ,
4, 18, 'k','o', 0 , 0 , 0 , 0 ,
-4, 20, 'n','o', 0 , 0 , 0 , 0 ,
-8, 20, 'n','o', 0 , 0 , 0 , 0 ,
+4, 20, 'n','b', 0 , 0 , 0 , 0 ,
+8, 20, 'n','b', 0 , 0 , 0 , 0 ,
4, 22, 'p','t', 0 , 0 , 0 , 0 ,
4, 29, 's','v', 0 , 0 , 0 , 0 ,
8, 29, 's','v', 0 , 0 , 0 , 0 ,
Change History (most recent first):
$Log: mDNSWin32.c,v $
+Revision 1.142 2009/06/25 21:11:02 herscher
+<rdar://problem/7003607> Platform layer doesn't correctly initialize the port field of TCP and UDP socket structures.
+
+Revision 1.141 2009/06/22 23:25:05 herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box. Refactor Lsa calls into Secret.h and Secret.c, which is used by both the ControlPanel and mDNSResponder system service.
+
+Revision 1.140 2009/04/24 04:55:26 herscher
+<rdar://problem/3496833> Advertise SMB file sharing via Bonjour
+
+Revision 1.139 2009/04/01 20:06:31 herscher
+<rdar://problem/5629676> Corrupt computer name string used
+
+Revision 1.138 2009/04/01 19:31:54 herscher
+Remove extraneous printf
+
+Revision 1.137 2009/04/01 17:50:15 mcguire
+cleanup mDNSRandom
+
+Revision 1.136 2009/03/30 20:53:10 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8.
+<rdar://problem/6145992> Reduce sleep from 3 seconds to 2 seconds
+<rdar://problem/6145992> Bonjour Service sometimes only gets a IPv6 link-local address after a network changed event
+<rdar://problem/6145913> Bonjour For Windows doesn't show IPv4 loopback intermittently when no network interfaces are active
+<rdar://problem/6143633> Bonjour service does not publish ANY IPv6 address on Windows Vista
+<rdar://problem/6136296> Bonjour 105A6: mDNSResponder is crashing on startup
+<rdar://problem/6127927> B4Windows: uDNS: Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+<rdar://problem/5270738> Remove Virtual PC check from mDNSResponder code
+
+Revision 1.135 2009/01/13 05:31:35 mkrochma
+<rdar://problem/6491367> Replace bzero, bcopy with mDNSPlatformMemZero, mDNSPlatformMemCopy, memset, memcpy
+
+Revision 1.134 2008/10/23 22:33:25 cheshire
+Changed "NOTE:" to "Note:" so that BBEdit 9 stops putting those comment lines into the funtion popup menu
+
+Revision 1.133 2008/10/22 17:19:57 cheshire
+Don't need to define BPF_fd any more (it's now per-interface, not global)
+
+Revision 1.132 2008/10/03 23:34:08 cheshire
+Added skeleton definition of mDNSPlatformSendRawPacket
+
+Revision 1.131 2008/10/03 18:25:18 cheshire
+Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);"
+
Revision 1.130 2007/11/16 18:53:56 cheshire
TCPSocketFlags needs to be first field of TCPSocket_struct
#include "CommonServices.h"
#include "DebugServices.h"
-#include "VPCDetect.h"
+#include "Firewall.h"
#include "RegNames.h"
+#include "Secret.h"
#include <dns_sd.h>
#include <Iphlpapi.h>
#include <mswsock.h>
#include <process.h>
#include <ntsecapi.h>
+ #include <lm.h>
#endif
#include "mDNSEmbeddedAPI.h"
-
+#include "DNSCommon.h"
#include "mDNSWin32.h"
#if 0
#define kWaitListComputerDescriptionEvent ( WAIT_OBJECT_0 + 3 )
#define kWaitListTCPIPEvent ( WAIT_OBJECT_0 + 4 )
#define kWaitListDynDNSEvent ( WAIT_OBJECT_0 + 5 )
-#define kWaitListFixedItemCount 6 + MDNS_WINDOWS_ENABLE_IPV4 + MDNS_WINDOWS_ENABLE_IPV6
+#define kWaitListFileShareEvent ( WAIT_OBJECT_0 + 6 )
+#define kWaitListFirewallEvent ( WAIT_OBJECT_0 + 7 )
+#define kWaitListFixedItemCount 8 + MDNS_WINDOWS_ENABLE_IPV4 + MDNS_WINDOWS_ENABLE_IPV6
#define kRegistryMaxKeyLength 255
+#define kRegistryMaxValueName 16383
#if( !TARGET_OS_WINDOWS_CE )
static GUID kWSARecvMsgGUID = WSAID_WSARECVMSG;
#endif
#define kIPv6IfIndexBase (10000000L)
-
-#define kRetryVPCRate (-100000000)
-#define kRetryVPCMax (10)
+#define SMBPortAsNumber 445
#if 0
mDNSlocal mStatus SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort );
mDNSlocal mStatus SetupNotifications( mDNS * const inMDNS );
mDNSlocal mStatus TearDownNotifications( mDNS * const inMDNS );
-mDNSlocal mStatus SetupRetryVPCCheck( mDNS * const inMDNS );
-mDNSlocal mStatus TearDownRetryVPCCheck( mDNS * const inMDNS );
mDNSlocal mStatus SetupThread( mDNS * const inMDNS );
mDNSlocal mStatus TearDownThread( const mDNS * const inMDNS );
mDNSlocal unsigned WINAPI ProcessingThread( LPVOID inParam );
mDNSlocal mStatus ProcessingThreadInitialize( mDNS * const inMDNS );
mDNSlocal mStatus ProcessingThreadSetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount );
-mDNSlocal void ProcessingThreadProcessPacket( mDNS *inMDNS, mDNSInterfaceData *inIFD, SocketRef inSock );
+mDNSlocal void ProcessingThreadProcessPacket( mDNS *inMDNS, mDNSInterfaceData *inIFD, UDPSocket * inUDPSocket, SocketRef inSock );
mDNSlocal void ProcessingThreadInterfaceListChanged( mDNS *inMDNS );
mDNSlocal void ProcessingThreadComputerDescriptionChanged( mDNS * inMDNS );
mDNSlocal void ProcessingThreadTCPIPConfigChanged( mDNS * inMDNS );
mDNSlocal void ProcessingThreadDynDNSConfigChanged( mDNS * inMDNS );
-mDNSlocal void ProcessingThreadRetryVPCCheck( mDNS * inMDNS );
+mDNSlocal void ProcessingThreadFileShareChanged( mDNS * inMDNS );
+mDNSlocal void ProcessingThreadFirewallChanged( mDNS * inMDNS );
+mDNSlocal OSStatus GetWindowsVersionString( char *inBuffer, size_t inBufferSize );
+
+mDNSlocal int getifaddrs( struct ifaddrs **outAddrs );
+mDNSlocal void freeifaddrs( struct ifaddrs *inAddrs );
+
// Platform Accessors
TCPSocket * next;
};
+struct UDPSocket_struct
+{
+ mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
+ SocketRef sock;
+ HANDLE readEvent;
+ mDNSAddr dstAddr;
+ LPFN_WSARECVMSG recvMsgPtr;
+ struct UDPSocket_struct * next;
+};
-mDNSexport mStatus mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID );
-mDNSexport mStatus mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo );
-// Utilities
-typedef struct PolyString PolyString;
-struct PolyString
-{
- domainname m_dname;
- char m_utf8[256];
- PLSA_UNICODE_STRING m_lsa;
-};
+mDNSexport mStatus mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID );
+mDNSexport mStatus mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo );
+
+// Utilities
#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
mDNSlocal int getifaddrs_ipv6( struct ifaddrs **outAddrs );
mDNSlocal struct ifaddrs* myGetIfAddrs(int refresh);
mDNSlocal OSStatus TCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize );
mDNSlocal OSStatus WindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize );
-mDNSlocal OSStatus MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input );
-mDNSlocal OSStatus MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input );
mDNSlocal void FreeTCPSocket( TCPSocket *sock );
+mDNSlocal void FreeUDPSocket( UDPSocket * sock );
mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa);
+mDNSlocal void GetDDNSFQDN( domainname *const fqdn );
+#ifdef UNICODE
+mDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey );
+#else
+mDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCSTR lpSubKey );
+#endif
+mDNSlocal void SetDomainSecrets( mDNS * const m );
+mDNSlocal void SetDomainSecret( mDNS * const m, const domainname * inDomain );
+mDNSlocal void CheckFileShares( mDNS * const m );
#ifdef __cplusplus
}
mDNSs32 mDNSPlatformOneSecond = 0;
mDNSlocal TCPSocket * gTCPConnectionList = NULL;
mDNSlocal int gTCPConnections = 0;
+mDNSlocal UDPSocket * gUDPSocketList = NULL;
+mDNSlocal int gUDPSockets = 0;
mDNSlocal BOOL gWaitListChanged = FALSE;
#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
#endif
+
+#ifndef HCRYPTPROV
+ typedef ULONG_PTR HCRYPTPROV; // WinCrypt.h, line 249
+#endif
+
+
+#ifndef CRYPT_MACHINE_KEYSET
+# define CRYPT_MACHINE_KEYSET 0x00000020
+#endif
+
+#ifndef CRYPT_NEWKEYSET
+# define CRYPT_NEWKEYSET 0x00000008
+#endif
+
+#ifndef PROV_RSA_FULL
+# define PROV_RSA_FULL 1
+#endif
+
+typedef BOOL (__stdcall *fnCryptGenRandom)( HCRYPTPROV, DWORD, BYTE* );
+typedef BOOL (__stdcall *fnCryptAcquireContext)( HCRYPTPROV*, LPCTSTR, LPCTSTR, DWORD, DWORD);
+typedef BOOL (__stdcall *fnCryptReleaseContext)(HCRYPTPROV, DWORD);
+
+static fnCryptAcquireContext g_lpCryptAcquireContext = NULL;
+static fnCryptReleaseContext g_lpCryptReleaseContext = NULL;
+static fnCryptGenRandom g_lpCryptGenRandom = NULL;
+static HINSTANCE g_hAAPI32 = NULL;
+static HCRYPTPROV g_hProvider = ( ULONG_PTR ) NULL;
+
+
#if 0
#pragma mark -
#pragma mark == Platform Support ==
// Initialize variables. If the PlatformSupport pointer is not null then just assume that a non-Apple client is
// calling mDNS_Init and wants to provide its own storage for the platform-specific data so do not overwrite it.
- memset( &gMDNSPlatformSupport, 0, sizeof( gMDNSPlatformSupport ) );
+ mDNSPlatformMemZero( &gMDNSPlatformSupport, sizeof( gMDNSPlatformSupport ) );
if( !inMDNS->p ) inMDNS->p = &gMDNSPlatformSupport;
inMDNS->p->interfaceListChangedSocket = kInvalidSocketRef;
mDNSPlatformOneSecond = 1000; // Use milliseconds as the quantum of time
inMDNS->HISoftware.c[ 0 ] = (mDNSu8) mDNSPlatformStrLen( &inMDNS->HISoftware.c[ 1 ] );
dlog( kDebugLevelInfo, DEBUG_NAME "HISoftware: %#s\n", inMDNS->HISoftware.c );
#endif
-
- // Bookkeeping
-
- inMDNS->p->vpcCheckCount = 0;
- inMDNS->p->vpcCheckEvent = NULL;
- inMDNS->p->timersCount = 0;
// Set up the IPv4 unicast socket
err = SetupThread( inMDNS );
require_noerr( err, exit );
+
+ // Notify core of domain secret keys
+
+ SetDomainSecrets( inMDNS );
// Success!
-
+
mDNSCoreInitComplete( inMDNS, err );
+
+ // See if we need to advertise file sharing
+
+ inMDNS->p->smbRegistered = mDNSfalse;
+ CheckFileShares( inMDNS );
exit:
if( err )
err = TearDownInterfaceList( inMDNS );
check_noerr( err );
check( !inMDNS->p->inactiveInterfaceList );
-
- err = TearDownRetryVPCCheck( inMDNS );
- check_noerr( err );
err = TearDownSynchronizationObjects( inMDNS );
check_noerr( err );
}
#endif
- WSACleanup();
-
- dlog( kDebugLevelTrace, DEBUG_NAME "platform close done\n" );
-}
-
-//===========================================================================================================================
-// mDNSPlatformSendUDP
-//===========================================================================================================================
-
-mDNSexport mStatus
- mDNSPlatformSendUDP(
- const mDNS * const inMDNS,
- const void * const inMsg,
- const mDNSu8 * const inMsgEnd,
- mDNSInterfaceID inInterfaceID,
- const mDNSAddr * inDstIP,
- mDNSIPPort inDstPort )
-{
- SOCKET sendingsocket = INVALID_SOCKET;
- mStatus err = mStatus_NoError;
- mDNSInterfaceData * ifd = (mDNSInterfaceData*) inInterfaceID;
- struct sockaddr_storage addr;
- int n;
-
- DEBUG_USE_ONLY( inMDNS );
-
- n = (int)( inMsgEnd - ( (const mDNSu8 * const) inMsg ) );
- check( inMDNS );
- check( inMsg );
- check( inMsgEnd );
- check( inDstIP );
-
- dlog( kDebugLevelChatty, DEBUG_NAME "platform send %d bytes to %#a:%u\n", n, inDstIP, ntohs( inDstPort.NotAnInteger ) );
-
- if( inDstIP->type == mDNSAddrType_IPv4 )
- {
- struct sockaddr_in * sa4;
-
- sa4 = (struct sockaddr_in *) &addr;
- sa4->sin_family = AF_INET;
- sa4->sin_port = inDstPort.NotAnInteger;
- sa4->sin_addr.s_addr = inDstIP->ip.v4.NotAnInteger;
- sendingsocket = ifd ? ifd->sock : inMDNS->p->unicastSock4;
- }
- else if( inDstIP->type == mDNSAddrType_IPv6 )
- {
- struct sockaddr_in6 * sa6;
-
- sa6 = (struct sockaddr_in6 *) &addr;
- sa6->sin6_family = AF_INET6;
- sa6->sin6_port = inDstPort.NotAnInteger;
- sa6->sin6_flowinfo = 0;
- sa6->sin6_addr = *( (struct in6_addr *) &inDstIP->ip.v6 );
- sa6->sin6_scope_id = 0; // Windows requires the scope ID to be zero. IPV6_MULTICAST_IF specifies interface.
- sendingsocket = ifd ? ifd->sock : inMDNS->p->unicastSock6;
- }
- else
- {
- dlog( kDebugLevelError, DEBUG_NAME "%s: dst is not an IPv4 or IPv6 address (type=%d)\n", __ROUTINE__, inDstIP->type );
- err = mStatus_BadParamErr;
- goto exit;
- }
-
- if (IsValidSocket(sendingsocket))
+ if ( g_hAAPI32 )
{
- n = sendto( sendingsocket, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
- err = translate_errno( n > 0, errno_compat(), kWriteErr );
+ // Release any resources
- if ( err )
+ if ( g_hProvider && g_lpCryptReleaseContext )
{
- // Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
-
- if ( !mDNSAddressIsAllDNSLinkGroup( inDstIP ) && ( WSAGetLastError() == WSAEHOSTDOWN || WSAGetLastError() == WSAENETDOWN || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAENETUNREACH ) )
- {
- err = mStatus_TransientErr;
- }
- else
- {
- require_noerr( err, exit );
- }
+ ( g_lpCryptReleaseContext )( g_hProvider, 0 );
}
+
+ // Free the AdvApi32.dll
+
+ FreeLibrary( g_hAAPI32 );
+
+ // And reset all the data
+
+ g_lpCryptAcquireContext = NULL;
+ g_lpCryptReleaseContext = NULL;
+ g_lpCryptGenRandom = NULL;
+ g_hProvider = ( ULONG_PTR ) NULL;
+ g_hAAPI32 = NULL;
}
+
+ WSACleanup();
-exit:
- return( err );
+ dlog( kDebugLevelTrace, DEBUG_NAME "platform close done\n" );
}
+
//===========================================================================================================================
// mDNSPlatformLock
//===========================================================================================================================
}
//===========================================================================================================================
-// mDNSPlatformRandomSeed
+// mDNSPlatformRandomNumber
//===========================================================================================================================
-mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
+mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
{
- return( GetTickCount() );
+ mDNSu32 randomNumber = 0;
+ BOOL bResult;
+ OSStatus err = 0;
+
+ if ( !g_hAAPI32 )
+ {
+ g_hAAPI32 = LoadLibrary( TEXT("AdvAPI32.dll") );
+ err = translate_errno( g_hAAPI32 != NULL, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+ }
+
+ // Function Pointer: CryptAcquireContext
+
+ if ( !g_lpCryptAcquireContext )
+ {
+ g_lpCryptAcquireContext = ( fnCryptAcquireContext )
+#ifdef UNICODE
+ ( GetProcAddress( g_hAAPI32, "CryptAcquireContextW" ) );
+#else
+ ( GetProcAddress( g_hAAPI32, "CryptAcquireContextA" ) );
+#endif
+ err = translate_errno( g_lpCryptAcquireContext != NULL, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+ }
+
+ // Function Pointer: CryptReleaseContext
+
+ if ( !g_lpCryptReleaseContext )
+ {
+ g_lpCryptReleaseContext = ( fnCryptReleaseContext )
+ ( GetProcAddress( g_hAAPI32, "CryptReleaseContext" ) );
+ err = translate_errno( g_lpCryptReleaseContext != NULL, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+ }
+
+ // Function Pointer: CryptGenRandom
+
+ if ( !g_lpCryptGenRandom )
+ {
+ g_lpCryptGenRandom = ( fnCryptGenRandom )
+ ( GetProcAddress( g_hAAPI32, "CryptGenRandom" ) );
+ err = translate_errno( g_lpCryptGenRandom != NULL, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+ }
+
+ // Setup
+
+ if ( !g_hProvider )
+ {
+ bResult = (*g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET );
+
+ if ( !bResult )
+ {
+ bResult = ( *g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET );
+ err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+ }
+ }
+
+ bResult = (*g_lpCryptGenRandom)( g_hProvider, sizeof( randomNumber ), ( BYTE* ) &randomNumber );
+ err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+
+exit:
+
+ if ( err )
+ {
+ randomNumber = rand();
+ }
+
+ return randomNumber;
}
//===========================================================================================================================
sock = (TCPSocket *) malloc( sizeof( TCPSocket ) );
require_action( sock, exit, err = mStatus_NoMemoryErr );
- memset( sock, 0, sizeof( TCPSocket ) );
+ mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
sock->fd = INVALID_SOCKET;
sock->flags = flags;
- bzero(&saddr, sizeof(saddr));
+ mDNSPlatformMemZero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl( INADDR_ANY );
saddr.sin_port = port->NotAnInteger;
err = translate_errno( sock->fd != INVALID_SOCKET, WSAGetLastError(), mStatus_UnknownErr );
require_noerr( err, exit );
+ // bind
+
+ err = bind( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr ) );
+ err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+
// Set it to be non-blocking
err = ioctlsocket( sock->fd, FIONBIO, &on );
// Get port number
- memset( &saddr, 0, sizeof( saddr ) );
+ mDNSPlatformMemZero( &saddr, sizeof( saddr ) );
len = sizeof( saddr );
err = getsockname( sock->fd, ( struct sockaddr* ) &saddr, &len );
sock->callback = inCallback;
sock->context = inContext;
- bzero(&saddr, sizeof(saddr));
+ mDNSPlatformMemZero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = inDstPort.NotAnInteger;
memcpy(&saddr.sin_addr, &inDstIP->ip.v4.NotAnInteger, sizeof(saddr.sin_addr));
sock = malloc( sizeof( TCPSocket ) );
require_action( sock, exit, err = mStatus_NoMemoryErr );
- memset( sock, 0, sizeof( *sock ) );
+ mDNSPlatformMemZero( sock, sizeof( *sock ) );
sock->fd = fd;
sock->flags = flags;
return ( int ) sock->fd;
}
+
//===========================================================================================================================
// mDNSPlatformUDPSocket
//===========================================================================================================================
-mDNSexport UDPSocket *mDNSPlatformUDPSocket
- (
- mDNS * const m,
- mDNSIPPort port
- )
+mDNSexport UDPSocket* mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport)
+{
+ UDPSocket* sock = NULL;
+ mDNSIPPort port = requestedport;
+ mStatus err = mStatus_NoError;
+ unsigned i;
+
+ // Setup connection data object
+
+ sock = (struct UDPSocket_struct*) malloc( sizeof( struct UDPSocket_struct ) );
+ require_action( sock, exit, err = mStatus_NoMemoryErr );
+ memset( sock, 0, sizeof( struct UDPSocket_struct ) );
+
+ // Create the socket
+
+ sock->recvMsgPtr = m->p->unicastSock4RecvMsgPtr;
+ sock->dstAddr = m->p->unicastSock4DestAddr;
+ sock->sock = INVALID_SOCKET;
+
+ // Try at most 10000 times to get a unique random port
+
+ for (i=0; i<10000; i++)
{
- DEBUG_UNUSED( m );
- DEBUG_UNUSED( port );
+ struct sockaddr_in saddr;
+
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr.s_addr = 0;
+
+ // The kernel doesn't do cryptographically strong random port
+ // allocation, so we do it ourselves here
+
+ if (mDNSIPPortIsZero(requestedport))
+ {
+ port = mDNSOpaque16fromIntVal(0xC000 + mDNSRandom(0x3FFF));
+ }
+
+ saddr.sin_port = port.NotAnInteger;
+
+ err = SetupSocket(m, ( struct sockaddr* ) &saddr, port, &sock->sock );
+ if (!err) break;
+ }
+
+ require_noerr( err, exit );
+
+ // Set the port
+
+ sock->port = port;
+
+ // Set it up with Windows Eventing
+
+ sock->readEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+ err = translate_errno( sock->readEvent, GetLastError(), mStatus_UnknownErr );
+ require_noerr( err, exit );
+ err = WSAEventSelect( sock->sock, sock->readEvent, FD_READ );
+ require_noerr( err, exit );
+
+ // Bookkeeping
+
+ sock->next = gUDPSocketList;
+ gUDPSocketList = sock;
+ gUDPSockets++;
+ gWaitListChanged = TRUE;
+
+exit:
- return NULL;
+ if ( err )
+ {
+ if ( sock )
+ {
+ FreeUDPSocket( sock );
+ sock = NULL;
+ }
}
+
+ return sock;
+}
//===========================================================================================================================
// mDNSPlatformUDPClose
//===========================================================================================================================
mDNSexport void mDNSPlatformUDPClose( UDPSocket *sock )
+{
+ UDPSocket * current = gUDPSocketList;
+ UDPSocket * last = NULL;
+
+ while ( current )
{
- DEBUG_UNUSED( sock );
- }
-
+ if ( current == sock )
+ {
+ if ( last == NULL )
+ {
+ gUDPSocketList = sock->next;
+ }
+ else
+ {
+ last->next = sock->next;
+ }
-//===========================================================================================================================
-// mDNSPlatformTLSSetupCerts
-//===========================================================================================================================
+ FreeUDPSocket( sock );
-mDNSexport mStatus
-mDNSPlatformTLSSetupCerts(void)
-{
- return mStatus_UnsupportedErr;
+ gUDPSockets--;
+ gWaitListChanged = TRUE;
+
+ break;
+ }
+
+ last = current;
+ current = current->next;
+ }
}
+
//===========================================================================================================================
-// mDNSPlatformTLSTearDownCerts
+// mDNSPlatformSendUDP
//===========================================================================================================================
-mDNSexport void
-mDNSPlatformTLSTearDownCerts(void)
+mDNSexport mStatus
+ mDNSPlatformSendUDP(
+ const mDNS * const inMDNS,
+ const void * const inMsg,
+ const mDNSu8 * const inMsgEnd,
+ mDNSInterfaceID inInterfaceID,
+ UDPSocket * inSrcSocket,
+ const mDNSAddr * inDstIP,
+ mDNSIPPort inDstPort )
{
-}
-
-//===========================================================================================================================
-// mDNSPlatformSetDNSConfig
-//===========================================================================================================================
+ SOCKET sendingsocket = INVALID_SOCKET;
+ mStatus err = mStatus_NoError;
+ mDNSInterfaceData * ifd = (mDNSInterfaceData*) inInterfaceID;
+ struct sockaddr_storage addr;
+ int n;
+
+ DEBUG_USE_ONLY( inMDNS );
+
+ n = (int)( inMsgEnd - ( (const mDNSu8 * const) inMsg ) );
+ check( inMDNS );
+ check( inMsg );
+ check( inMsgEnd );
+ check( inDstIP );
+
+ dlog( kDebugLevelChatty, DEBUG_NAME "platform send %d bytes to %#a:%u\n", n, inDstIP, ntohs( inDstPort.NotAnInteger ) );
+
+ if( inDstIP->type == mDNSAddrType_IPv4 )
+ {
+ struct sockaddr_in * sa4;
+
+ sa4 = (struct sockaddr_in *) &addr;
+ sa4->sin_family = AF_INET;
+ sa4->sin_port = inDstPort.NotAnInteger;
+ sa4->sin_addr.s_addr = inDstIP->ip.v4.NotAnInteger;
+ sendingsocket = ifd ? ifd->sock : inMDNS->p->unicastSock4;
-mDNSlocal void SetDNSServers( mDNS *const m );
-mDNSlocal void SetSearchDomainList( void );
+ if (inSrcSocket) { sendingsocket = inSrcSocket->sock; debugf("mDNSPlatformSendUDP using port %d, static port %d, sock %d", mDNSVal16(inSrcSocket->port), inMDNS->p->unicastSock4, sendingsocket); }
+ }
+ else if( inDstIP->type == mDNSAddrType_IPv6 )
+ {
+ struct sockaddr_in6 * sa6;
+
+ sa6 = (struct sockaddr_in6 *) &addr;
+ sa6->sin6_family = AF_INET6;
+ sa6->sin6_port = inDstPort.NotAnInteger;
+ sa6->sin6_flowinfo = 0;
+ sa6->sin6_addr = *( (struct in6_addr *) &inDstIP->ip.v6 );
+ sa6->sin6_scope_id = 0; // Windows requires the scope ID to be zero. IPV6_MULTICAST_IF specifies interface.
+ sendingsocket = ifd ? ifd->sock : inMDNS->p->unicastSock6;
+ }
+ else
+ {
+ dlog( kDebugLevelError, DEBUG_NAME "%s: dst is not an IPv4 or IPv6 address (type=%d)\n", __ROUTINE__, inDstIP->type );
+ err = mStatus_BadParamErr;
+ goto exit;
+ }
+
+ if (IsValidSocket(sendingsocket))
+ {
+ n = sendto( sendingsocket, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
+ err = translate_errno( n > 0, errno_compat(), kWriteErr );
-void
-mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains, DNameListElem **browseDomains)
-{
- LPSTR name = NULL;
- char subKeyName[kRegistryMaxKeyLength + 1];
- DWORD cSubKeys = 0;
- DWORD cbMaxSubKey;
- DWORD cchMaxClass;
- DWORD dwSize;
- DWORD enabled;
- HKEY key;
- HKEY subKey = NULL;
- domainname dname;
- DWORD i;
- OSStatus err;
+ if ( err )
+ {
+ // Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
- if (setservers) SetDNSServers(m);
- if (setsearch) SetSearchDomainList();
+ if ( !mDNSAddressIsAllDNSLinkGroup( inDstIP ) && ( WSAGetLastError() == WSAEHOSTDOWN || WSAGetLastError() == WSAENETDOWN || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAENETUNREACH ) )
+ {
+ err = mStatus_TransientErr;
+ }
+ else
+ {
+ require_noerr( err, exit );
+ }
+ }
+ }
+
+exit:
+ return( err );
+}
- // Initialize
- fqdn->c[0] = '\0';
+mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
+ {
+ DEBUG_UNUSED( m );
+ DEBUG_UNUSED( InterfaceID );
+ }
- *browseDomains = NULL;
+//===========================================================================================================================
+// mDNSPlatformSendRawPacket
+//===========================================================================================================================
- err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
- require_noerr( err, exit );
-
- err = RegQueryString( key, "", &name, &dwSize, &enabled );
- if ( !err && ( name[0] != '\0' ) && enabled )
+mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
{
- if ( !MakeDomainNameFromDNSNameString( fqdn, name ) || !fqdn->c[0] )
- {
- dlog( kDebugLevelError, "bad DDNS host name in registry: %s", name[0] ? name : "(unknown)");
- }
+ DEBUG_UNUSED( msg );
+ DEBUG_UNUSED( end );
+ DEBUG_UNUSED( InterfaceID );
}
- if ( key )
+mDNSexport void mDNSPlatformReceiveRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
{
- RegCloseKey( key );
- key = NULL;
+ DEBUG_UNUSED( msg );
+ DEBUG_UNUSED( end );
+ DEBUG_UNUSED( InterfaceID );
}
- if ( name )
+mDNSexport void mDNSPlatformSetLocalARP( const mDNSv4Addr * const tpa, const mDNSEthAddr * const tha, mDNSInterfaceID InterfaceID )
{
- free( name );
- name = NULL;
+ DEBUG_UNUSED( tpa );
+ DEBUG_UNUSED( tha );
+ DEBUG_UNUSED( InterfaceID );
}
- err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSBrowseDomains, &key );
- require_noerr( err, exit );
-
- // Get information about this node
-
- err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
- require_noerr( err, exit );
+mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
+ {
+ fprintf( stderr, msg );
+ }
- for ( i = 0; i < cSubKeys; i++)
+mDNSexport void mDNSPlatformWriteLogMsg( const char * ident, const char * msg, int flags )
{
- DWORD enabled;
+ DEBUG_UNUSED( ident );
+ DEBUG_UNUSED( msg );
+ DEBUG_UNUSED( flags );
+ }
- dwSize = kRegistryMaxKeyLength;
-
- err = RegEnumKeyExA( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+mDNSexport void mDNSPlatformSourceAddrForDest( mDNSAddr * const src, const mDNSAddr * const dst )
+ {
+ DEBUG_UNUSED( src );
+ DEBUG_UNUSED( dst );
+ }
- if ( !err )
- {
- err = RegOpenKeyExA( key, subKeyName, 0, KEY_READ, &subKey );
- require_noerr( err, exit );
+//===========================================================================================================================
+// mDNSPlatformTLSSetupCerts
+//===========================================================================================================================
- dwSize = sizeof( DWORD );
- err = RegQueryValueExA( subKey, "Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+mDNSexport mStatus
+mDNSPlatformTLSSetupCerts(void)
+{
+ return mStatus_UnsupportedErr;
+}
- if ( !err && ( subKeyName[0] != '\0' ) && enabled )
- {
- if ( !MakeDomainNameFromDNSNameString( &dname, subKeyName ) || !dname.c[0] )
- {
- dlog( kDebugLevelError, "bad DDNS browse domain in registry: %s", subKeyName[0] ? subKeyName : "(unknown)");
- }
- else
- {
- DNameListElem * browseDomain = (DNameListElem*) malloc( sizeof( DNameListElem ) );
- require_action( browseDomain, exit, err = mStatus_NoMemoryErr );
-
- AssignDomainName(&browseDomain->name, &dname);
- browseDomain->next = *browseDomains;
+//===========================================================================================================================
+// mDNSPlatformTLSTearDownCerts
+//===========================================================================================================================
- *browseDomains = browseDomain;
- }
- }
+mDNSexport void
+mDNSPlatformTLSTearDownCerts(void)
+{
+}
- RegCloseKey( subKey );
- subKey = NULL;
- }
- }
+//===========================================================================================================================
+// mDNSPlatformSetDNSConfig
+//===========================================================================================================================
- if ( key )
- {
- RegCloseKey( key );
- key = NULL;
- }
+mDNSlocal void SetDNSServers( mDNS *const m );
+mDNSlocal void SetSearchDomainList( void );
- err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains, &key );
- require_noerr( err, exit );
+mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **regDomains, DNameListElem **browseDomains)
+{
+ if (setservers) SetDNSServers(m);
+ if (setsearch) SetSearchDomainList();
- err = RegQueryString( key, "", &name, &dwSize, &enabled );
- if ( !err && ( name[0] != '\0' ) && enabled )
- {
- *RegDomains = (DNameListElem*) malloc( sizeof( DNameListElem ) );
- if (!*RegDomains) dlog( kDebugLevelError, "No memory");
- else
- {
- (*RegDomains)->next = mDNSNULL;
- if ( !MakeDomainNameFromDNSNameString( &(*RegDomains)->name, name ) || (*RegDomains)->name.c[0] )
- {
- dlog( kDebugLevelError, "bad DDNS registration domain in registry: %s", name[0] ? name : "(unknown)");
- }
- }
- }
-
-exit:
-
- if ( subKey )
+ if ( fqdn )
{
- RegCloseKey( subKey );
+ GetDDNSFQDN( fqdn );
}
- if ( key )
+ if ( browseDomains )
{
- RegCloseKey( key );
+ GetDDNSDomains( browseDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSBrowseDomains );
}
- if ( name )
+ if ( regDomains )
{
- free( name );
+ GetDDNSDomains( regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
}
}
//===========================================================================================================================
mDNSexport void
-mDNSPlatformDynDNSHostNameStatusChanged(domainname *const dname, mStatus status)
+mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
{
char uname[MAX_ESCAPED_DOMAIN_NAME];
+ BYTE bStatus;
LPCTSTR name;
HKEY key = NULL;
mStatus err;
err = RegCreateKey( HKEY_LOCAL_MACHINE, name, &key );
require_noerr( err, exit );
- status = ( status ) ? 0 : 1;
- err = RegSetValueEx( key, kServiceDynDNSStatus, 0, REG_DWORD, (const LPBYTE) &status, sizeof(DWORD) );
+ bStatus = ( status ) ? 0 : 1;
+ err = RegSetValueEx( key, kServiceDynDNSStatus, 0, REG_DWORD, (const LPBYTE) &bStatus, sizeof(DWORD) );
require_noerr( err, exit );
exit:
//===========================================================================================================================
// This routine needs to be called whenever the system secrets database changes.
-// Right now I call it from ProcessingThreadDynDNSConfigChanged, which may or may not be sufficient.
-// Also, it needs to call mDNS_SetSecretForDomain() for *every* configured DNS domain/secret pair
-// in the database, not just inDomain (the inDomain parameter should be deleted).
+// We call it from ProcessingThreadDynDNSConfigChanged and mDNSPlatformInit
mDNSlocal void
-SetDomainSecrets( mDNS * const m, const domainname * inDomain )
+SetDomainSecrets( mDNS * const m )
{
- PolyString domain;
- PolyString key;
- PolyString secret;
- size_t i;
- size_t dlen;
- LSA_OBJECT_ATTRIBUTES attrs;
- LSA_HANDLE handle = NULL;
- NTSTATUS res;
- OSStatus err;
-
- // Initialize PolyStrings
-
- domain.m_lsa = NULL;
- key.m_lsa = NULL;
- secret.m_lsa = NULL;
-
- // canonicalize name by converting to lower case (keychain and some name servers are case sensitive)
-
- ConvertDomainNameToCString( inDomain, domain.m_utf8 );
- dlen = strlen( domain.m_utf8 );
- for ( i = 0; i < dlen; i++ )
- {
- domain.m_utf8[i] = (char) tolower( domain.m_utf8[i] ); // canonicalize -> lower case
- }
-
- MakeDomainNameFromDNSNameString( &domain.m_dname, domain.m_utf8 );
-
- // attrs are reserved, so initialize to zeroes.
-
- ZeroMemory( &attrs, sizeof( attrs ) );
+ DomainAuthInfo *ptr;
+ domainname fqdn;
+ DNameListElem * regDomains = NULL;
- // Get a handle to the Policy object on the local system
-
- res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle );
- err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
- require_noerr( err, exit );
-
- // Get the encrypted data
-
- domain.m_lsa = ( PLSA_UNICODE_STRING) malloc( sizeof( LSA_UNICODE_STRING ) );
- require_action( domain.m_lsa != NULL, exit, err = mStatus_NoMemoryErr );
- err = MakeLsaStringFromUTF8String( domain.m_lsa, domain.m_utf8 );
- require_noerr( err, exit );
-
- // Retrieve the key
-
- res = LsaRetrievePrivateData( handle, domain.m_lsa, &key.m_lsa );
- err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
- require_noerr_quiet( err, exit );
-
- // <rdar://problem/4192119> 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.
-
- // Convert the key to a domainname. Strip off the "$" prefix.
-
- err = MakeUTF8StringFromLsaString( key.m_utf8, sizeof( key.m_utf8 ), key.m_lsa );
- require_noerr( err, exit );
- require_action( key.m_utf8[0] == '$', exit, err = kUnknownErr );
- MakeDomainNameFromDNSNameString( &key.m_dname, key.m_utf8 + 1 );
-
- // Retrieve the secret
-
- res = LsaRetrievePrivateData( handle, key.m_lsa, &secret.m_lsa );
- err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
- require_noerr_quiet( err, exit );
+ // Rather than immediately deleting all keys now, we mark them for deletion in ten seconds.
+ // In the case where the user simultaneously removes their DDNS host name and the key
+ // for it, this gives mDNSResponder ten seconds to gracefully delete the name from the
+ // server before it loses access to the necessary key. Otherwise, we'd leave orphaned
+ // address records behind that we no longer have permission to delete.
- // Convert the secret to UTF8 string
-
- err = MakeUTF8StringFromLsaString( secret.m_utf8, sizeof( secret.m_utf8 ), secret.m_lsa );
- require_noerr( err, exit );
-
- // And finally, tell the core about this secret
-
- debugf("Setting shared secret for zone %s with key %##s", domain.m_utf8, key.m_dname.c);
- mDNS_SetSecretForDomain( m, &domain.m_dname, &key.m_dname, secret.m_utf8, mDNSfalse );
-
-exit:
-
- if ( domain.m_lsa != NULL )
- {
- if ( domain.m_lsa->Buffer != NULL )
- {
- free( domain.m_lsa->Buffer );
- }
+ for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
+ ptr->deltime = NonZeroTime(m->timenow + mDNSPlatformOneSecond*10);
- free( domain.m_lsa );
- }
+ GetDDNSFQDN( &fqdn );
- if ( key.m_lsa != NULL )
+ if ( fqdn.c[ 0 ] )
{
- LsaFreeMemory( key.m_lsa );
+ SetDomainSecret( m, &fqdn );
}
- if ( secret.m_lsa != NULL )
- {
- LsaFreeMemory( secret.m_lsa );
- }
+ GetDDNSDomains( ®Domains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
- if ( handle )
+ while ( regDomains )
{
- LsaClose( handle );
- handle = NULL;
+ DNameListElem * current = regDomains;
+ SetDomainSecret( m, ¤t->name );
+ regDomains = regDomains->next;
+ free( current );
}
}
{
char * searchList = NULL;
DWORD searchListLen;
- DNameListElem * head = NULL;
- DNameListElem * current = NULL;
+ //DNameListElem * head = NULL;
+ //DNameListElem * current = NULL;
char * tok;
HKEY key;
mStatus err;
ifa = ifa->ifa_next;
}
-exit:
+ return;
}
{
mDNSAddr addr;
err = StringToAddress( &addr, ipAddr->IpAddress.String );
- if ( !err ) mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, addr, UnicastDNSPort);
+ if ( !err ) mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, &addr, UnicastDNSPort);
}
exit:
mDNSlocal void
SetDomainFromDHCP( void )
{
- DNameListElem * head = NULL;
int i = 0;
IP_ADAPTER_INFO * pAdapterInfo;
IP_ADAPTER_INFO * pAdapter;
DWORD index;
HKEY key = NULL;
LPSTR domain = NULL;
- domainname dname;
DWORD dwSize;
mStatus err = mStatus_NoError;
mDNSlocal mStatus SetupNiceName( mDNS * const inMDNS )
{
mStatus err = 0;
- char tempString[ 256 ];
char utf8[ 256 ];
check( inMDNS );
// Set up the nice name.
- tempString[ 0 ] = '\0';
- utf8[0] = '\0';
+ utf8[0] = '\0';
// First try and open the registry key that contains the computer description value
if (inMDNS->p->descKey == NULL)
// if we can't find it in the registry, then use the hostname of the machine
if ( err || ( utf8[ 0 ] == '\0' ) )
{
- DWORD tempStringLen = sizeof( tempString );
+ TCHAR hostname[256];
+ DWORD hostnameLen = sizeof( hostname ) / sizeof( TCHAR );
BOOL ok;
- ok = GetComputerNameExA( ComputerNamePhysicalDnsHostname, tempString, &tempStringLen );
+ ok = GetComputerNameExW( ComputerNamePhysicalDnsHostname, hostname, &hostnameLen );
err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
check_noerr( err );
if( !err )
{
- err = WindowsLatin1toUTF8( tempString, utf8, sizeof( utf8 ) );
+ err = TCHARtoUTF8( hostname, utf8, sizeof( utf8 ) );
}
if ( err )
return( err );
}
-
//===========================================================================================================================
// SetupHostName
//===========================================================================================================================
#if( !TARGET_OS_WINDOWS_CE )
{
DWORD size;
-
- // If we are running inside VPC, then we won't use WSARecvMsg because it will give us bogus information due to
- // a bug in VPC itself.
- err = inMDNS->p->inVirtualPC;
-
- if ( !err )
- {
- err = WSAIoctl( sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ),
+ err = WSAIoctl( sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ),
&ifd->wsaRecvMsgFunctionPtr, sizeof( ifd->wsaRecvMsgFunctionPtr ), &size, NULL, NULL );
- }
if ( err )
{
err = SockAddrToMDNSAddr( inIFA->ifa_netmask, &ifd->interfaceInfo.mask, NULL );
require_noerr( err, exit );
- ifd->interfaceInfo.Advertise = inMDNS->AdvertiseLocalAddresses;
+ ifd->interfaceInfo.Advertise = ( mDNSu8 ) inMDNS->AdvertiseLocalAddresses;
err = mDNS_RegisterInterface( inMDNS, &ifd->interfaceInfo, mDNSfalse );
require_noerr( err, exit );
// Bind the socket to the desired port
ipv4.NotAnInteger = ( (const struct sockaddr_in *) inAddr )->sin_addr.s_addr;
- memset( &sa4, 0, sizeof( sa4 ) );
+ mDNSPlatformMemZero( &sa4, sizeof( sa4 ) );
sa4.sin_family = AF_INET;
sa4.sin_port = port.NotAnInteger;
sa4.sin_addr.s_addr = ipv4.NotAnInteger;
// Bind the socket to the desired port
- memset( &sa6, 0, sizeof( sa6 ) );
+ mDNSPlatformMemZero( &sa6, sizeof( sa6 ) );
sa6.sin6_family = AF_INET6;
sa6.sin6_port = port.NotAnInteger;
sa6.sin6_flowinfo = 0;
err = RegNotifyChangeKeyValue(inMDNS->p->ddnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, inMDNS->p->ddnsChangedEvent, TRUE);
require_noerr( err, exit );
-exit:
- if( err )
- {
- TearDownNotifications( inMDNS );
- }
- return( err );
-}
+ // This will catch all changes to file sharing
-//===========================================================================================================================
-// TearDownNotifications
-//===========================================================================================================================
+ inMDNS->p->fileShareEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+ err = translate_errno( inMDNS->p->fileShareEvent, (mStatus) GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\Shares"), &inMDNS->p->fileShareKey );
+ require_noerr( err, exit );
+
+ err = RegNotifyChangeKeyValue(inMDNS->p->fileShareKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, inMDNS->p->fileShareEvent, TRUE);
+ require_noerr( err, exit );
+
+ // This will catch changes to the Windows firewall
+
+ inMDNS->p->firewallEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+ err = translate_errno( inMDNS->p->firewallEvent, (mStatus) GetLastError(), kUnknownErr );
+ require_noerr( err, exit );
+
+ // Just to make sure that initialization doesn't fail on some old OS
+ // that doesn't have this key, we'll only add the notification if
+ // the key exists.
+
+ err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules"), &inMDNS->p->firewallKey );
+
+ if ( !err )
+ {
+ err = RegNotifyChangeKeyValue(inMDNS->p->firewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, inMDNS->p->firewallEvent, TRUE);
+ require_noerr( err, exit );
+ }
+ else
+ {
+ err = mStatus_NoError;
+ }
+
+exit:
+ if( err )
+ {
+ TearDownNotifications( inMDNS );
+ }
+ return( err );
+}
+
+//===========================================================================================================================
+// TearDownNotifications
+//===========================================================================================================================
mDNSlocal mStatus TearDownNotifications( mDNS * const inMDNS )
{
inMDNS->p->ddnsKey = NULL;
}
- return( mStatus_NoError );
-}
-
-
-//===========================================================================================================================
-// SetupRetryVPCCheck
-//===========================================================================================================================
-
-mDNSlocal mStatus
-SetupRetryVPCCheck( mDNS * const inMDNS )
-{
- LARGE_INTEGER liDueTime;
- BOOL ok;
- mStatus err;
-
- dlog( kDebugLevelTrace, DEBUG_NAME "setting up retry VirtualPC check\n" );
-
- liDueTime.QuadPart = kRetryVPCRate;
-
- // Create a waitable timer.
-
- inMDNS->p->vpcCheckEvent = CreateWaitableTimer( NULL, TRUE, TEXT( "VPCCheckTimer" ) );
- err = translate_errno( inMDNS->p->vpcCheckEvent, (mStatus) GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- // Set a timer to wait for 10 seconds.
-
- ok = SetWaitableTimer( inMDNS->p->vpcCheckEvent, &liDueTime, 0, NULL, NULL, 0 );
- err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- inMDNS->p->timersCount++;
-
-exit:
-
- return err;
-}
-
-
-//===========================================================================================================================
-// TearDownRetryVPCCheck
-//===========================================================================================================================
+ if ( inMDNS->p->fileShareEvent != NULL )
+ {
+ CloseHandle( inMDNS->p->fileShareEvent );
+ inMDNS->p->fileShareEvent = NULL;
+ }
-mDNSlocal mStatus
-TearDownRetryVPCCheck( mDNS * const inMDNS )
-{
- dlog( kDebugLevelTrace, DEBUG_NAME "tearing down retry VirtualPC check\n" );
+ if ( inMDNS->p->fileShareKey != NULL )
+ {
+ RegCloseKey( inMDNS->p->fileShareKey );
+ inMDNS->p->fileShareKey = NULL;
+ }
- if ( inMDNS->p->vpcCheckEvent )
+ if ( inMDNS->p->firewallEvent != NULL )
{
- CancelWaitableTimer( inMDNS->p->vpcCheckEvent );
- CloseHandle( inMDNS->p->vpcCheckEvent );
+ CloseHandle( inMDNS->p->firewallEvent );
+ inMDNS->p->firewallEvent = NULL;
+ }
- inMDNS->p->vpcCheckEvent = NULL;
- inMDNS->p->timersCount--;
+ if ( inMDNS->p->firewallKey != NULL )
+ {
+ RegCloseKey( inMDNS->p->firewallKey );
+ inMDNS->p->firewallKey = NULL;
}
- return ( mStatus_NoError );
+ return( mStatus_NoError );
}
}
else if( result == kWaitListInterfaceListChangedEvent )
{
+ // It would be nice to come up with a more elegant solution to this, but it seems that
+ // GetAdaptersAddresses doesn't always stay in sync after network changed events. So as
+ // as a simple workaround, we'll pause for a couple of seconds before processing the change.
+
+ // We arrived at 2 secs by trial and error. We could reproduce the problem after sleeping
+ // for 500 msec and 750 msec, but couldn't after sleeping for 1 sec. We added another
+ // second on top of that to account for machine load or some other exigency.
+
+ Sleep( 2000 );
+
// Interface list changed event. Break out of the inner loop to re-setup the wait list.
ProcessingThreadInterfaceListChanged( m );
ProcessingThreadDynDNSConfigChanged( m );
break;
}
+ else if ( result == kWaitListFileShareEvent )
+ {
+ //
+ // File sharing changed
+ //
+ ProcessingThreadFileShareChanged( m );
+ break;
+ }
+ else if ( result == kWaitListFirewallEvent )
+ {
+ //
+ // Firewall configuration changed
+ //
+ ProcessingThreadFirewallChanged( m );
+ }
else
{
int waitItemIndex;
waitItemIndex = (int)( ( (int) result ) - WAIT_OBJECT_0 );
dlog( kDebugLevelChatty, DEBUG_NAME "socket data available on socket index %d\n", waitItemIndex );
check( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) );
+
if( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) )
{
HANDLE signaledObject;
int n = 0;
mDNSInterfaceData * ifd;
TCPSocket * tcd;
+ UDPSocket * sock;
signaledObject = waitList[ waitItemIndex ];
- if ( m->p->vpcCheckEvent == signaledObject )
- {
- ProcessingThreadRetryVPCCheck( m );
- ++n;
-
- break;
- }
#if ( MDNS_WINDOWS_ENABLE_IPV4 )
if ( m->p->unicastSock4ReadEvent == signaledObject )
{
- ProcessingThreadProcessPacket( m, NULL, m->p->unicastSock4 );
+ ProcessingThreadProcessPacket( m, NULL, NULL, m->p->unicastSock4 );
++n;
}
#endif
#if ( MDNS_WINDOWS_ENABLE_IPV6 )
if ( m->p->unicastSock6ReadEvent == signaledObject )
{
- ProcessingThreadProcessPacket( m, NULL, m->p->unicastSock6 );
+ ProcessingThreadProcessPacket( m, NULL, NULL, m->p->unicastSock6 );
++n;
}
#endif
{
if( ifd->readPendingEvent == signaledObject )
{
- ProcessingThreadProcessPacket( m, ifd, ifd->sock );
+ ProcessingThreadProcessPacket( m, ifd, NULL, ifd->sock );
++n;
}
}
}
}
+ for ( sock = gUDPSocketList; sock; sock = sock->next )
+ {
+ if ( sock->readEvent == signaledObject )
+ {
+ ProcessingThreadProcessPacket( m, NULL, sock, sock->sock );
+
+ ++n;
+
+ break;
+ }
+ }
+
check( n > 0 );
}
else
inMDNS->p->threadID = GetCurrentThreadId();
- err = IsVPCRunning( &inMDNS->p->inVirtualPC );
-
- if ( err )
- {
- TearDownRetryVPCCheck( inMDNS );
- SetupRetryVPCCheck( inMDNS );
- }
-
err = SetupInterfaceList( inMDNS );
require_noerr( err, exit );
if( err )
{
TearDownInterfaceList( inMDNS );
- TearDownRetryVPCCheck( inMDNS );
}
inMDNS->p->initStatus = err;
HANDLE * waitItemPtr;
mDNSInterfaceData * ifd;
TCPSocket * tcd;
+ UDPSocket * sock;
dlog( kDebugLevelTrace, DEBUG_NAME "thread setting up wait list\n" );
check( inMDNS );
// Allocate an array to hold all the objects to wait on.
- waitListCount = kWaitListFixedItemCount + inMDNS->p->timersCount + inMDNS->p->interfaceCount + gTCPConnections;
+ waitListCount = kWaitListFixedItemCount + inMDNS->p->interfaceCount + gTCPConnections + gUDPSockets;
waitList = (HANDLE *) malloc( waitListCount * sizeof( *waitList ) );
require_action( waitList, exit, err = mStatus_NoMemoryErr );
waitItemPtr = waitList;
*waitItemPtr++ = inMDNS->p->descChangedEvent;
*waitItemPtr++ = inMDNS->p->tcpipChangedEvent;
*waitItemPtr++ = inMDNS->p->ddnsChangedEvent;
-
- // Add timers
-
- if ( inMDNS->p->vpcCheckEvent )
- {
- *waitItemPtr++ = inMDNS->p->vpcCheckEvent;
- }
+ *waitItemPtr++ = inMDNS->p->fileShareEvent;
+ *waitItemPtr++ = inMDNS->p->firewallEvent;
// Append all the dynamic wait items to the list.
#if ( MDNS_WINDOWS_ENABLE_IPV4 )
*waitItemPtr++ = tcd->pendingEvent;
}
+ for ( sock = gUDPSocketList; sock; sock = sock->next )
+ {
+ *waitItemPtr++ = sock->readEvent;
+ }
+
check( (int)( waitItemPtr - waitList ) == waitListCount );
*outWaitList = waitList;
// ProcessingThreadProcessPacket
//===========================================================================================================================
-mDNSlocal void ProcessingThreadProcessPacket( mDNS *inMDNS, mDNSInterfaceData *inIFD, SocketRef inSock )
+mDNSlocal void ProcessingThreadProcessPacket( mDNS *inMDNS, mDNSInterfaceData *inIFD, UDPSocket * inUDPSocket, SocketRef inSock )
{
OSStatus err;
const mDNSInterfaceID iid = inIFD ? inIFD->interfaceInfo.InterfaceID : NULL;
dstPort = MulticastDNSPort;
ttl = 255;
}
+ else if ( inUDPSocket )
+ {
+ recvMsgPtr = inUDPSocket->recvMsgPtr;
+ dstAddr = inUDPSocket->dstAddr;
+ dstPort = inUDPSocket->port;
+ ttl = 255;
+ }
else if ( inSock == inMDNS->p->unicastSock4 )
{
recvMsgPtr = inMDNS->p->unicastSock4RecvMsgPtr;
dstAddr = inMDNS->p->unicastSock4DestAddr;
- dstPort = zeroIPPort;
+ dstPort = inMDNS->UnicastPort4;
ttl = 255;
}
else if ( inSock == inMDNS->p->unicastSock6 )
{
recvMsgPtr = inMDNS->p->unicastSock6RecvMsgPtr;
dstAddr = inMDNS->p->unicastSock6DestAddr;
- dstPort = zeroIPPort;
+ dstPort = inMDNS->UnicastPort6;
ttl = 255;
}
else
msg.dwFlags = 0;
err = recvMsgPtr( inSock, &msg, &size, NULL, NULL );
- err = translate_errno( err == 0, (OSStatus) GetLastError(), kUnknownErr );
+ err = translate_errno( err == 0, (OSStatus) WSAGetLastError(), kUnknownErr );
require_noerr( err, exit );
n = (int) size;
// Inform clients of the change.
- if( inMDNS->MainCallback )
- {
- inMDNS->MainCallback( inMDNS, mStatus_ConfigChanged );
- }
+ mDNS_ConfigChanged(inMDNS);
// Force mDNS to update.
- mDNSCoreMachineSleep( inMDNS, mDNSfalse );
+ mDNSCoreMachineSleep( inMDNS, mDNSfalse ); // What is this for? Mac OS X does not do this
}
//===========================================================================================================================
-// ProcessingThreadRetryVPCCheck
+// ProcessingThreadFileShareChanged
//===========================================================================================================================
-
-mDNSlocal void
-ProcessingThreadRetryVPCCheck( mDNS * inMDNS )
+mDNSlocal void ProcessingThreadFileShareChanged( mDNS *inMDNS )
{
- mStatus err = mStatus_NoError;
-
- dlog( kDebugLevelTrace, DEBUG_NAME "in ProcessingThreadRetryVPCCheck\n" );
+ mStatus err;
- TearDownRetryVPCCheck( inMDNS );
+ dlog( kDebugLevelInfo, DEBUG_NAME "File shares has changed\n" );
+ check( inMDNS );
+
+ CheckFileShares( inMDNS );
+
+ // and reset the event handler
- if ( inMDNS->p->vpcCheckCount < kRetryVPCMax )
+ if ((inMDNS->p->fileShareKey != NULL) && (inMDNS->p->fileShareEvent))
{
- inMDNS->p->vpcCheckCount++;
+ err = RegNotifyChangeKeyValue(inMDNS->p->fileShareKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, inMDNS->p->fileShareEvent, TRUE);
+ check_noerr( err );
+ }
+}
- err = IsVPCRunning( &inMDNS->p->inVirtualPC );
- require_noerr( err, exit );
+
+//===========================================================================================================================
+// ProcessingThreadFileShareChanged
+//===========================================================================================================================
+mDNSlocal void ProcessingThreadFirewallChanged( mDNS *inMDNS )
+{
+ mStatus err;
- if ( inMDNS->p->inVirtualPC )
- {
- ProcessingThreadInterfaceListChanged( inMDNS );
- }
- }
+ dlog( kDebugLevelInfo, DEBUG_NAME "Firewall has changed\n" );
+ check( inMDNS );
-exit:
+ CheckFileShares( inMDNS );
- if ( err )
+ // and reset the event handler
+
+ if ((inMDNS->p->firewallKey != NULL) && (inMDNS->p->firewallEvent))
{
- SetupRetryVPCCheck( inMDNS );
+ err = RegNotifyChangeKeyValue(inMDNS->p->firewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, inMDNS->p->firewallEvent, TRUE);
+ check_noerr( err );
}
-
- return;
}
// Use the new IPv6-capable routine if supported. Otherwise, fall back to the old and compatible IPv4-only code.
// <rdar://problem/4278934> Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 fails
-
- if( !gGetAdaptersAddressesFunctionPtr || ( ( err = getifaddrs_ipv6( outAddrs ) ) != mStatus_NoError ) )
+ // <rdar://problem/6145913> Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 returns no addrs
+
+ if( !gGetAdaptersAddressesFunctionPtr || ( ( ( err = getifaddrs_ipv6( outAddrs ) ) != mStatus_NoError ) || ( ( outAddrs != NULL ) && ( *outAddrs == NULL ) ) ) )
{
err = getifaddrs_ipv4( outAddrs );
require_noerr( err, exit );
int prefixIndex;
IP_ADAPTER_PREFIX * prefix;
ULONG prefixLength;
+ uint32_t ipv4Index;
+ struct sockaddr_in ipv4Netmask;
family = addr->Address.lpSockaddr->sa_family;
if( ( family != AF_INET ) && ( family != AF_INET6 ) ) continue;
+ // <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
+ // Seems as if the problem here is a buggy implementation of some network interface
+ // driver. It is reporting that is has a link-local address when it is actually
+ // disconnected. This was causing a problem in AddressToIndexAndMask.
+ // The solution is to call AddressToIndexAndMask first, and if unable to lookup
+ // the address, to ignore that address.
+
+ ipv4Index = 0;
+ memset( &ipv4Netmask, 0, sizeof( ipv4Netmask ) );
+
+ if ( family == AF_INET )
+ {
+ err = AddressToIndexAndMask( addr->Address.lpSockaddr, &ipv4Index, ( struct sockaddr* ) &ipv4Netmask );
+
+ if ( err )
+ {
+ err = 0;
+ continue;
+ }
+ }
+
ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
require_action( ifa, exit, err = WSAENOBUFS );
prefixLength = 0;
for( prefixIndex = 0, prefix = firstPrefix; prefix; ++prefixIndex, prefix = prefix->Next )
{
- if( prefixIndex == addrIndex )
+ if( ( prefix->Address.lpSockaddr->sa_family == family ) && ( prefixIndex == addrIndex ) )
{
check_string( prefix->Address.lpSockaddr->sa_family == family, "addr family != netmask family" );
prefixLength = prefix->PrefixLength;
{
struct sockaddr_in * sa4;
- require_action( prefixLength <= 32, exit, err = ERROR_INVALID_DATA );
-
sa4 = (struct sockaddr_in *) calloc( 1, sizeof( *sa4 ) );
require_action( sa4, exit, err = WSAENOBUFS );
-
sa4->sin_family = AF_INET;
-
- if ( prefixLength != 0 )
- {
- sa4->sin_addr.s_addr = htonl( 0xFFFFFFFFU << ( 32 - prefixLength ) );
- }
- else
- {
- uint32_t index;
-
- dlog( kDebugLevelWarning, DEBUG_NAME "%s: IPv4 prefixLength is 0\n", __ROUTINE__ );
- err = AddressToIndexAndMask( ifa->ifa_addr, &index, (struct sockaddr*) sa4 );
- require_noerr( err, exit );
- }
+ sa4->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr;
dlog( kDebugLevelInfo, DEBUG_NAME "%s: IPv4 mask = %s\n", __ROUTINE__, inet_ntoa( sa4->sin_addr ) );
ifa->ifa_netmask = (struct sockaddr *) sa4;
for( i = 0; i < n; ++i )
{
+ uint32_t ifIndex;
+ struct sockaddr_in netmask;
+
ifInfo = &buffer[ i ];
if( ifInfo->iiAddress.Address.sa_family != AF_INET )
{
continue;
}
+ // <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
+ // See comment in getifaddrs_ipv6
+
+ ifIndex = 0;
+ memset( &netmask, 0, sizeof( netmask ) );
+ err = AddressToIndexAndMask( ( struct sockaddr* ) &ifInfo->iiAddress.AddressIn, &ifIndex, ( struct sockaddr* ) &netmask );
+
+ if ( err )
+ {
+ continue;
+ }
+
ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
require_action( ifa, exit, err = WSAENOBUFS );
memcpy( ifa->ifa_addr, sa4, sizeof( *sa4 ) );
ifa->ifa_netmask = (struct sockaddr*) calloc(1, sizeof( *sa4 ) );
+ require_action( ifa->ifa_netmask, exit, err = WSAENOBUFS );
// <rdar://problem/4076478> Service won't start on Win2K. The address
// family field was not being initialized.
ifa->ifa_netmask->sa_family = AF_INET;
- require_action( ifa->ifa_netmask, exit, err = WSAENOBUFS );
- err = AddressToIndexAndMask( ifa->ifa_addr, &ifa->ifa_extra.index, ifa->ifa_netmask );
- require_noerr( err, exit );
+ ( ( struct sockaddr_in* ) ifa->ifa_netmask )->sin_addr = netmask.sin_addr;
+ ifa->ifa_extra.index = ifIndex;
}
else
{
// Call WSAIoctl with SIO_ADDRESS_LIST_QUERY and pass a null buffer. This call will fail, but the size needed to
// for the request will be filled in. Once we know the size, allocate a buffer to hold the entire list.
//
- // NOTE: Due to a bug in Windows CE, the size returned by WSAIoctl is not enough so double it as a workaround.
+ // Note: Due to a bug in Windows CE, the size returned by WSAIoctl is not enough so double it as a workaround.
size = 0;
WSAIoctl( sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &size, NULL, NULL );
// Process the raw interface list and build a linked list of interfaces.
//
- // NOTE: Due to a bug in Windows CE, the iAddressCount field is always 0 so use 1 in that case.
+ // Note: Due to a bug in Windows CE, the iAddressCount field is always 0 so use 1 in that case.
n = addressList->iAddressCount;
if( n == 0 )
}
require_noerr( err, exit );
+ err = mStatus_UnknownErr;
for ( i = 0; i < pIPAddrTable->dwNumEntries; i++ )
{
ok = IsValidSocket( sock );
if( ok )
{
- memset( &addr, 0, sizeof( addr ) );
+ mDNSPlatformMemZero( &addr, sizeof( addr ) );
addr.sin_family = AF_INET;
addr.sin_port = MulticastDNSPort.NotAnInteger;
addr.sin_addr.s_addr = htonl( INADDR_ANY );
//===========================================================================================================================
-// ConvertUTF8ToLsaString
+// FreeTCPConnectionData
//===========================================================================================================================
-mDNSlocal OSStatus
-MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input )
+mDNSlocal void
+FreeTCPSocket( TCPSocket *sock )
+{
+ check( sock );
+
+ if ( sock->pendingEvent )
+ {
+ CloseHandle( sock->pendingEvent );
+ }
+
+ if ( sock->fd != INVALID_SOCKET )
+ {
+ closesocket( sock->fd );
+ }
+
+ free( sock );
+}
+
+
+//===========================================================================================================================
+// FreeUDPSocket
+//===========================================================================================================================
+
+mDNSlocal void
+FreeUDPSocket( UDPSocket * sock )
{
- int size;
+ check( sock );
+
+ if ( sock->readEvent )
+ {
+ CloseHandle( sock->readEvent );
+ }
+
+ if ( sock->sock != INVALID_SOCKET )
+ {
+ closesocket( sock->sock );
+ }
+
+ free( sock );
+}
+
+//===========================================================================================================================
+// SetupAddr
+//===========================================================================================================================
+
+mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
+ {
+ if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
+
+ if (sa->sa_family == AF_INET)
+ {
+ struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
+ ip->type = mDNSAddrType_IPv4;
+ ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
+ return(mStatus_NoError);
+ }
+
+ if (sa->sa_family == AF_INET6)
+ {
+ struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
+ ip->type = mDNSAddrType_IPv6;
+ if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.u.Word[1] = 0;
+ ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
+ return(mStatus_NoError);
+ }
+
+ LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
+ return(mStatus_Invalid);
+ }
+
+
+mDNSlocal void GetDDNSFQDN( domainname *const fqdn )
+{
+ LPSTR name = NULL;
+ DWORD dwSize;
+ DWORD enabled;
+ HKEY key = NULL;
OSStatus err;
-
- check( input );
- check( output );
- output->Buffer = NULL;
+ check( fqdn );
- size = MultiByteToWideChar( CP_UTF8, 0, input, -1, NULL, 0 );
- err = translate_errno( size > 0, GetLastError(), kUnknownErr );
- require_noerr( err, exit );
+ // Initialize
+
+ fqdn->c[0] = '\0';
- output->Length = (USHORT)( size * sizeof( wchar_t ) );
- output->Buffer = (PWCHAR) malloc( output->Length );
- require_action( output->Buffer, exit, err = mStatus_NoMemoryErr );
- size = MultiByteToWideChar( CP_UTF8, 0, input, -1, output->Buffer, size );
- err = translate_errno( size > 0, GetLastError(), kUnknownErr );
+ // Get info from Bonjour registry key
+
+ err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
require_noerr( err, exit );
- // We're going to subtrace one wchar_t from the size, because we didn't
- // include it when we encoded the string
+ err = RegQueryString( key, "", &name, &dwSize, &enabled );
+ if ( !err && ( name[0] != '\0' ) && enabled )
+ {
+ if ( !MakeDomainNameFromDNSNameString( fqdn, name ) || !fqdn->c[0] )
+ {
+ dlog( kDebugLevelError, "bad DDNS host name in registry: %s", name[0] ? name : "(unknown)");
+ }
+ }
- output->MaximumLength = output->Length;
- output->Length -= sizeof( wchar_t );
-
exit:
- if ( err && output->Buffer )
+ if ( key )
{
- free( output->Buffer );
- output->Buffer = NULL;
+ RegCloseKey( key );
+ key = NULL;
}
- return( err );
+ if ( name )
+ {
+ free( name );
+ name = NULL;
+ }
}
-//===========================================================================================================================
-// ConvertLsaStringToUTF8
-//===========================================================================================================================
-
-mDNSlocal OSStatus
-MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input )
+#ifdef UNICODE
+mDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey )
+#else
+mDNSlocal void GetDDNSConfig( DNameListElem ** domains, LPCSTR lpSubKey )
+#endif
{
- size_t size;
- OSStatus err = kNoErr;
+ char subKeyName[kRegistryMaxKeyLength + 1];
+ DWORD cSubKeys = 0;
+ DWORD cbMaxSubKey;
+ DWORD cchMaxClass;
+ DWORD dwSize;
+ HKEY key = NULL;
+ HKEY subKey = NULL;
+ domainname dname;
+ DWORD i;
+ OSStatus err;
- // The Length field of this structure holds the number of bytes,
- // but WideCharToMultiByte expects the number of wchar_t's. So
- // we divide by sizeof(wchar_t) to get the correct number.
+ check( domains );
- size = (size_t) WideCharToMultiByte(CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), NULL, 0, NULL, NULL);
- err = translate_errno( size != 0, GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- // Ensure that we have enough space (Add one for trailing '\0')
+ // Initialize
- require_action( ( size + 1 ) <= len, exit, err = mStatus_NoMemoryErr );
+ *domains = NULL;
- // Convert the string
+ err = RegCreateKey( HKEY_LOCAL_MACHINE, lpSubKey, &key );
+ require_noerr( err, exit );
- size = (size_t) WideCharToMultiByte( CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), output, (int) size, NULL, NULL);
- err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+ // Get information about this node
+
+ err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
require_noerr( err, exit );
- // have to add the trailing 0 because WideCharToMultiByte doesn't do it,
- // although it does return the correct size
+ for ( i = 0; i < cSubKeys; i++)
+ {
+ DWORD enabled;
- output[size] = '\0';
+ dwSize = kRegistryMaxKeyLength;
+
+ err = RegEnumKeyExA( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
-exit:
+ if ( !err )
+ {
+ err = RegOpenKeyExA( key, subKeyName, 0, KEY_READ, &subKey );
+ require_noerr( err, exit );
- return err;
-}
+ dwSize = sizeof( DWORD );
+ err = RegQueryValueExA( subKey, "Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+
+ if ( !err && ( subKeyName[0] != '\0' ) && enabled )
+ {
+ if ( !MakeDomainNameFromDNSNameString( &dname, subKeyName ) || !dname.c[0] )
+ {
+ dlog( kDebugLevelError, "bad DDNS domain in registry: %s", subKeyName[0] ? subKeyName : "(unknown)");
+ }
+ else
+ {
+ DNameListElem * domain = (DNameListElem*) malloc( sizeof( DNameListElem ) );
+ require_action( domain, exit, err = mStatus_NoMemoryErr );
+
+ AssignDomainName(&domain->name, &dname);
+ domain->next = *domains;
+ *domains = domain;
+ }
+ }
-//===========================================================================================================================
-// FreeTCPConnectionData
-//===========================================================================================================================
+ RegCloseKey( subKey );
+ subKey = NULL;
+ }
+ }
-mDNSlocal void
-FreeTCPSocket( TCPSocket *sock )
-{
- check( sock );
+exit:
- if ( sock->pendingEvent )
+ if ( subKey )
{
- CloseHandle( sock->pendingEvent );
+ RegCloseKey( subKey );
}
- if ( sock->fd != INVALID_SOCKET )
+ if ( key )
{
- closesocket( sock->fd );
+ RegCloseKey( key );
}
-
- free( sock );
}
-//===========================================================================================================================
-// SetupAddr
-//===========================================================================================================================
-mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
+mDNSlocal void SetDomainSecret( mDNS * const m, const domainname * inDomain )
+{
+ char domainUTF8[ 256 ];
+ DomainAuthInfo *foundInList;
+ DomainAuthInfo *ptr;
+ char outDomain[ 256 ];
+ char outKey[ 256 ];
+ char outSecret[ 256 ];
+ OSStatus err;
+
+ ConvertDomainNameToCString( inDomain, domainUTF8 );
+
+ // If we're able to find a secret for this domain
+
+ if ( LsaGetSecret( domainUTF8, outDomain, sizeof( outDomain ), outKey, sizeof( outKey ), outSecret, sizeof( outSecret ) ) )
{
- if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
+ domainname domain;
+ domainname key;
- if (sa->sa_family == AF_INET)
+ // Tell the core about this secret
+
+ MakeDomainNameFromDNSNameString( &domain, outDomain );
+ MakeDomainNameFromDNSNameString( &key, outKey );
+
+ for (foundInList = m->AuthInfoList; foundInList; foundInList = foundInList->next)
+ if (SameDomainName(&foundInList->domain, &domain ) ) break;
+
+ ptr = foundInList;
+
+ if (!ptr)
{
- struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
- ip->type = mDNSAddrType_IPv4;
- ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
- return(mStatus_NoError);
+ ptr = (DomainAuthInfo*)malloc(sizeof(DomainAuthInfo));
+ require_action( ptr, exit, err = mStatus_NoMemoryErr );
}
- if (sa->sa_family == AF_INET6)
+ err = mDNS_SetSecretForDomain(m, ptr, &domain, &key, outSecret, mDNSfalse );
+ require_action( err != mStatus_BadParamErr, exit, if (!foundInList ) mDNSPlatformMemFree( ptr ) );
+
+ debugf("Setting shared secret for zone %s with key %##s", outDomain, key.c);
+ }
+
+exit:
+
+ return;
+}
+
+
+mDNSlocal void
+CheckFileShares( mDNS * const m )
+{
+ PSHARE_INFO_1 bufPtr = ( PSHARE_INFO_1 ) NULL;
+ DWORD entriesRead = 0;
+ DWORD totalEntries = 0;
+ DWORD resume = 0;
+ mDNSBool enabled = mDNSfalse;
+ NET_API_STATUS res;
+ mStatus err;
+
+ check( m );
+
+ if ( mDNSIsFileAndPrintSharingEnabled() )
+ {
+ dlog( kDebugLevelTrace, DEBUG_NAME "file and print sharing is enabled\n" );
+
+ res = NetShareEnum( NULL, 1, ( LPBYTE* )&bufPtr, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resume );
+
+ if ( ( res == ERROR_SUCCESS ) || ( res == ERROR_MORE_DATA ) )
{
- struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
- ip->type = mDNSAddrType_IPv6;
- if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.u.Word[1] = 0;
- ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
- return(mStatus_NoError);
+ PSHARE_INFO_1 p = bufPtr;
+ DWORD i;
+
+ for( i = 0; i <= totalEntries; i++ )
+ {
+ // We are only interested if the user is sharing anything other
+ // than the built-in "print$" source
+
+ if ( ( p->shi1_type == STYPE_DISKTREE ) && ( wcscmp( p->shi1_netname, TEXT( "print$" ) ) != 0 ) )
+ {
+ enabled = mDNStrue;
+ break;
+ }
+
+ p++;
+ }
+
+ NetApiBufferFree( bufPtr );
+ bufPtr = NULL;
}
+ }
- LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
- return(mStatus_Invalid);
+ if ( enabled && !m->p->smbRegistered )
+ {
+ domainname type;
+ domainname domain;
+ mDNSIPPort port = { { SMBPortAsNumber >> 8, SMBPortAsNumber & 0xFF } };
+ mDNSInterfaceID iid = mDNSPlatformInterfaceIDfromInterfaceIndex( m, 0 );
+
+ dlog( kDebugLevelTrace, DEBUG_NAME "registering smb type\n" );
+
+ MakeDomainNameFromDNSNameString(&type, "_smb._tcp" );
+ MakeDomainNameFromDNSNameString(&domain, "local.");
+
+ err = mDNS_RegisterService( m, &m->p->smbSRS, &m->nicelabel, &type, &domain, NULL, port, NULL, 0, NULL, 0, iid, /* callback */ NULL, /* context */ NULL);
+ require_noerr( err, exit );
+
+ m->p->smbRegistered = mDNStrue;
+ }
+ else if ( !enabled && m->p->smbRegistered )
+ {
+ dlog( kDebugLevelTrace, DEBUG_NAME "deregistering smb type\n" );
+
+ err = mDNS_DeregisterService( m, &m->p->smbSRS );
+ require_noerr( err, exit );
+
+ m->p->smbRegistered = mDNSfalse;
}
+
+exit:
+
+ return;
+}
Change History (most recent first):
$Log: mDNSWin32.h,v $
+Revision 1.28 2009/04/24 04:55:26 herscher
+<rdar://problem/3496833> Advertise SMB file sharing via Bonjour
+
+Revision 1.27 2009/03/30 20:45:52 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/6127927> B4Windows: uDNS: Should use randomized source ports and transaction IDs to avoid DNS cache poisoning
+Remove VirtualPC workaround
+
Revision 1.26 2006/08/14 23:25:21 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
HANDLE descChangedEvent; // Computer description changed event
HANDLE tcpipChangedEvent; // TCP/IP config changed
HANDLE ddnsChangedEvent; // DynDNS config changed
+ HANDLE fileShareEvent; // File Sharing changed
+ HANDLE firewallEvent; // Firewall changed
HANDLE wakeupEvent;
HANDLE initEvent;
- HANDLE vpcCheckEvent; // Timer handle to check if we're running in Virtual PC
- int vpcCheckCount;
HKEY descKey;
HKEY tcpipKey;
HKEY ddnsKey;
+ HKEY fileShareKey;
+ HKEY firewallKey;
+ mDNSBool smbRegistered;
+ ServiceRecordSet smbSRS;
mStatus initStatus;
- mDNSBool inVirtualPC;
- int timersCount;
mDNSBool registeredLoopback4;
SocketRef interfaceListChangedSocket;
int interfaceCount;
};
-//---------------------------------------------------------------------------------------------------------------------------
-/*! @function GetWindowsVersionString
-
- @abstract Stores Windows version information in the string passed in (inBuffer)
-*/
-
-OSStatus GetWindowsVersionString( char *inBuffer, size_t inBufferSize );
-
-
-//---------------------------------------------------------------------------------------------------------------------------
-/*! @function getifaddrs
-
- @abstract Builds a linked list of interfaces. Caller must free using freeifaddrs if successful.
-*/
-
-int getifaddrs( struct ifaddrs **outAddrs );
-
-//---------------------------------------------------------------------------------------------------------------------------
-/*! @function freeifaddrs
-
- @abstract Frees a linked list of interfaces built with getifaddrs.
-*/
-
-void freeifaddrs( struct ifaddrs *inAddrs );
-
-
#ifdef __cplusplus
}
#endif
Change History (most recent first):
$Log: mdnsNSP.c,v $
+Revision 1.22 2009/03/30 20:34:51 herscher
+<rdar://problem/5925472> Current Bonjour code does not compile on Windows
+<rdar://problem/5914160> Eliminate use of GetNextLabel in mdnsNSP
+
+Revision 1.21 2008/07/16 01:25:10 cheshire
+<rdar://problem/5914160> Eliminate use of GetNextLabel in mdnsNSP
+
Revision 1.20 2006/08/14 23:26:10 cheshire
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
#include <stdlib.h>
#include <string.h>
+#include "ClientCommon.h"
#include "CommonServices.h"
#include "DebugServices.h"
#define snprintf _snprintf
#endif
+#define MAX_LABELS 128
+
#if 0
#pragma mark == Structures ==
#endif
DEBUG_LOCAL OSStatus HostsFileClose( HostsFile * self );
DEBUG_LOCAL void HostsFileInfoFree( HostsFileInfo * info );
DEBUG_LOCAL OSStatus HostsFileNext( HostsFile * self, HostsFileInfo ** hInfo );
-DEBUG_LOCAL const char * GetNextLabel( const char *cstr, char label[64] );
DEBUG_LOCAL DWORD GetScopeId( DWORD ifIndex );
#ifdef ENABLE_REVERSE_LOOKUP
WSCUnInstallNameSpace( &gNSPGUID );
- err = GetModuleFileNameW( gInstance, path, sizeof( path ) );
+ err = GetModuleFileNameW( gInstance, path, MAX_PATH );
err = translate_errno( err != 0, errno_compat(), kUnknownErr );
require_noerr( err, exit );
char translated[ kDNSServiceMaxDomainName ];
int n;
int labels = 0;
- const char * label[128];
+ const char * label[MAX_LABELS];
char text[64];
n = WideCharToMultiByte( CP_UTF8, 0, name, -1, translated, sizeof( translated ), NULL, NULL );
// Don't resolve multi-label name
+ // <rdar://problem/5914160> Eliminate use of GetNextLabel in mdnsNSP
+ // Add checks for GetNextLabel returning NULL, individual labels being greater than
+ // 64 bytes, and the number of labels being greater than MAX_LABELS
replyDomain = translated;
- while ( *replyDomain )
+ while (replyDomain && *replyDomain && labels < MAX_LABELS)
{
label[labels++] = replyDomain;
replyDomain = GetNextLabel(replyDomain, text);
require_action( InHostsTable( translated ) == FALSE, exit, err = WSASERVICE_NOT_FOUND );
}
- // The name ends in .local ( and isn't in the hosts table ), {8,9,A,B}.E.F.ip6.arpa, or .254.169.in-addr.arpa so start the resolve operation. Lazy initialize DNS-SD if needed.
+ // The name ends in .local ( and isn't in the hosts table ), .0.8.e.f.ip6.arpa, or .254.169.in-addr.arpa so start the resolve operation. Lazy initialize DNS-SD if needed.
NSPLock();
}
-//===========================================================================================================================
-// GetNextLabel
-//===========================================================================================================================
-DEBUG_LOCAL const char*
-GetNextLabel(const char *cstr, char label[64])
-{
- char *ptr = label;
- while (*cstr && *cstr != '.') // While we have characters in the label...
- {
- char c = *cstr++;
- if (c == '\\')
- {
- c = *cstr++;
- if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
- {
- int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
- int v1 = cstr[ 0] - '0';
- int v2 = cstr[ 1] - '0';
- int val = v0 * 100 + v1 * 10 + v2;
- if (val <= 255) { c = (char)val; cstr += 2; } // If valid three-digit decimal value, use it
- }
- }
- *ptr++ = c;
- if (ptr >= label+64) return(NULL);
- }
- if (*cstr) cstr++; // Skip over the trailing dot (if present)
- *ptr++ = 0;
- return(cstr);
-}
-
-
#ifdef ENABLE_REVERSE_LOOKUP
//===========================================================================================================================
// IsReverseLookup
LPCWSTR p;
OSStatus err = kNoErr;
+ // IPv6LL Reverse-mapping domains are {8,9,A,B}.E.F.ip6.arpa
require_action_quiet( size > sizeof_string( ".0.8.e.f.ip6.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
p = name + ( size - 1 );
<?xml version="1.0" encoding="Windows-1252"?>\r
<VisualStudioProject\r
ProjectType="Visual C++"\r
- Version="7.10"\r
+ Version="8.00"\r
Name="mdnsNSP"\r
ProjectGUID="{F4F15529-F0EB-402F-8662-73C5797EE557}"\r
- Keyword="Win32Proj">\r
+ Keyword="Win32Proj"\r
+ >\r
<Platforms>\r
<Platform\r
- Name="Win32"/>\r
+ Name="Win32"\r
+ />\r
+ <Platform\r
+ Name="x64"\r
+ />\r
</Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
<Configurations>\r
<Configuration\r
Name="Debug|Win32"\r
- OutputDirectory=".\Debug"\r
- IntermediateDirectory=".\Debug"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- AdditionalIncludeDirectories=".;../;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NSP_EXPORTS;DEBUG;WIN32_LEAN_AND_MEAN"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
- ExceptionHandling="FALSE"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NSP_EXPORTS;DEBUG;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
BasicRuntimeChecks="3"\r
- SmallerTypeCheck="TRUE"\r
+ SmallerTypeCheck="true"\r
RuntimeLibrary="1"\r
- BufferSecurityCheck="TRUE"\r
+ BufferSecurityCheck="true"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
- DebugInformationFormat="4"\r
- CallingConvention="2"/>\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../DLL/Debug/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"\r
OutputFile="$(OutDir)/mdnsNSP.dll"\r
LinkIncremental="2"\r
ModuleDefinitionFile="mdnsNSP.def"\r
DelayLoadDLLs="dnssd.dll"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(OutDir)/mdnsNSP.pdb"\r
SubSystem="2"\r
- BaseAddress="0x16080000"\r
+ BaseAddress="0x64000000"\r
ImportLibrary="$(OutDir)/mdnsNSP.lib"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Debug|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NSP_EXPORTS;DEBUG;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
+ BasicRuntimeChecks="3"\r
+ SmallerTypeCheck="true"\r
+ RuntimeLibrary="1"\r
+ BufferSecurityCheck="true"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"\r
+ OutputFile="$(OutDir)/mdnsNSP.dll"\r
+ LinkIncremental="2"\r
+ ModuleDefinitionFile="mdnsNSP.def"\r
+ DelayLoadDLLs="dnssd.dll"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(OutDir)/mdnsNSP.pdb"\r
+ SubSystem="2"\r
+ BaseAddress="0x64000000"\r
+ ImportLibrary="$(OutDir)/mdnsNSP.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
</Configuration>\r
<Configuration\r
Name="Release|Win32"\r
- OutputDirectory=".\Release"\r
- IntermediateDirectory=".\Release"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
ConfigurationType="2"\r
- CharacterSet="2">\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
<Tool\r
Name="VCCLCompilerTool"\r
- AdditionalIncludeDirectories=".;../;../../mDNSShared"\r
- PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NSP_EXPORTS;WIN32_LEAN_AND_MEAN"\r
- StringPooling="TRUE"\r
- MinimalRebuild="TRUE"\r
- ExceptionHandling="FALSE"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NSP_EXPORTS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
BasicRuntimeChecks="0"\r
- SmallerTypeCheck="FALSE"\r
+ SmallerTypeCheck="false"\r
RuntimeLibrary="0"\r
UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
WarningLevel="4"\r
- Detect64BitPortabilityProblems="TRUE"\r
+ Detect64BitPortabilityProblems="true"\r
DebugInformationFormat="3"\r
- CallingConvention="2"/>\r
+ CallingConvention="2"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
<Tool\r
- Name="VCCustomBuildTool"/>\r
+ Name="VCPreLinkEventTool"\r
+ />\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="../DLL/Release/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"\r
OutputFile="$(OutDir)/mdnsNSP.dll"\r
LinkIncremental="1"\r
ModuleDefinitionFile="mdnsNSP.def"\r
DelayLoadDLLs="dnssd.dll"\r
- GenerateDebugInformation="TRUE"\r
+ GenerateDebugInformation="true"\r
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
SubSystem="2"\r
OptimizeReferences="0"\r
EnableCOMDATFolding="0"\r
- BaseAddress="0x16080000"\r
+ BaseAddress="0x64000000"\r
ImportLibrary="$(IntDir)/mdnsNSP.lib"\r
- TargetMachine="1"/>\r
+ TargetMachine="1"\r
+ />\r
<Tool\r
- Name="VCMIDLTool"/>\r
+ Name="VCALinkTool"\r
+ />\r
<Tool\r
- Name="VCPostBuildEventTool"/>\r
+ Name="VCManifestTool"\r
+ />\r
<Tool\r
- Name="VCPreBuildEventTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCPreLinkEventTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|x64"\r
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ TargetEnvironment="3"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"\r
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NSP_EXPORTS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"\r
+ StringPooling="true"\r
+ MinimalRebuild="true"\r
+ ExceptionHandling="0"\r
+ BasicRuntimeChecks="0"\r
+ SmallerTypeCheck="false"\r
+ RuntimeLibrary="0"\r
+ UsePrecompiledHeader="0"\r
+ AssemblerListingLocation="$(IntDir)\"\r
+ WarningLevel="4"\r
+ Detect64BitPortabilityProblems="true"\r
+ DebugInformationFormat="3"\r
+ CallingConvention="2"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
<Tool\r
Name="VCResourceCompilerTool"\r
- AdditionalIncludeDirectories="../"/>\r
+ AdditionalIncludeDirectories="../"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ AdditionalOptions="/NXCOMPAT /DYNAMICBASE"\r
+ AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"\r
+ OutputFile="$(OutDir)/mdnsNSP.dll"\r
+ LinkIncremental="1"\r
+ ModuleDefinitionFile="mdnsNSP.def"\r
+ DelayLoadDLLs="dnssd.dll"\r
+ GenerateDebugInformation="true"\r
+ ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"\r
+ SubSystem="2"\r
+ OptimizeReferences="0"\r
+ EnableCOMDATFolding="0"\r
+ BaseAddress="0x64000000"\r
+ ImportLibrary="$(IntDir)/mdnsNSP.lib"\r
+ TargetMachine="17"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
<Tool\r
- Name="VCWebServiceProxyGeneratorTool"/>\r
+ Name="VCXDCMakeTool"\r
+ />\r
<Tool\r
- Name="VCXMLDataGeneratorTool"/>\r
+ Name="VCBscMakeTool"\r
+ />\r
<Tool\r
- Name="VCWebDeploymentTool"/>\r
+ Name="VCFxCopTool"\r
+ />\r
<Tool\r
- Name="VCManagedWrapperGeneratorTool"/>\r
+ Name="VCAppVerifierTool"\r
+ />\r
<Tool\r
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="if not "%RC_XBS%" == "YES" goto END
if not exist "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)" mkdir "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
xcopy /I/Y "$(TargetPath)" "$(DSTROOT)\Program Files\Bonjour\$(PlatformName)"
:END
"\r
+ />\r
</Configuration>\r
</Configurations>\r
<References>\r
<Filter\r
Name="Source Files"\r
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\Clients\ClientCommon.c"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.c">\r
+ RelativePath="..\..\mDNSShared\DebugServices.c"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\mdnsNSP.c">\r
+ RelativePath=".\mdnsNSP.c"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\mdnsNSP.def">\r
+ RelativePath=".\mdnsNSP.def"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath="..\..\Clients\ClientCommon.h"\r
+ >\r
+ </File>\r
<File\r
- RelativePath="..\..\mDNSShared\CommonServices.h">\r
+ RelativePath="..\..\mDNSShared\CommonServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\mDNSShared\DebugServices.h">\r
+ RelativePath="..\..\mDNSShared\DebugServices.h"\r
+ >\r
</File>\r
<File\r
- RelativePath="..\..\..\mDNSShared\dns_sd.h">\r
+ RelativePath="..\..\..\mDNSShared\dns_sd.h"\r
+ >\r
</File>\r
<File\r
- RelativePath=".\resource.h">\r
+ RelativePath=".\resource.h"\r
+ >\r
</File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
<File\r
- RelativePath=".\mdnsNSP.rc">\r
+ RelativePath=".\mdnsNSP.rc"\r
+ >\r
</File>\r
</Filter>\r
</Files>\r