]> git.saurik.com Git - apple/mdnsresponder.git/commitdiff
mDNSResponder-107.3.tar.gz mac-os-x-1043 v107.3
authorApple <opensource@apple.com>
Sat, 6 Aug 2005 00:38:37 +0000 (00:38 +0000)
committerApple <opensource@apple.com>
Sat, 6 Aug 2005 00:38:37 +0000 (00:38 +0000)
73 files changed:
Clients/ExplorerPlugin/ExplorerBarWindow.cpp
Clients/ExplorerPlugin/ExplorerPluginLocRes.rc
Clients/ExplorerPlugin/ExplorerPluginLocRes.vcproj
Clients/ExplorerPlugin/ExplorerPluginRes.rc
Clients/ExplorerPlugin/ExplorerPluginRes.vcproj
Clients/ExplorerPlugin/res/globe.bmp [new file with mode: 0755]
Clients/ExplorerPlugin/resource_res.h
Clients/PrinterSetupWizard/FirstPage.cpp
Clients/PrinterSetupWizard/PrinterSetupWizardApp.cpp
Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc
Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.vcproj
Clients/PrinterSetupWizard/PrinterSetupWizardRes.vcproj
Clients/PrinterSetupWizard/PrinterSetupWizardSheet.cpp
Clients/PrinterSetupWizard/PrinterSetupWizardSheet.h
Clients/PrinterSetupWizard/SecondPage.cpp
Clients/PrinterSetupWizard/SecondPage.h
Clients/PrinterSetupWizard/ThirdPage.cpp
Clients/PrinterSetupWizard/UtilTypes.h
Clients/PrinterSetupWizard/res/NetworkPrinter.ico
Clients/PrinterSetupWizard/res/Print.ico
Clients/dns-sd.c
Makefile
mDNSCore/mDNS.c
mDNSCore/mDNSEmbeddedAPI.h
mDNSCore/uDNS.c
mDNSCore/uDNS.h
mDNSMacOS9/mDNSLibraryResources.r
mDNSMacOSX/LegacyNATTraversal.c
mDNSMacOSX/PreferencePane/BonjourPref.icns [deleted file]
mDNSMacOSX/PreferencePane/BonjourPref.tiff [deleted file]
mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.icns [new file with mode: 0644]
mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.tiff [new file with mode: 0644]
mDNSMacOSX/daemon.c
mDNSMacOSX/mDNSMacOSX.c
mDNSMacOSX/mDNSResponder.pbproj/project.pbxproj
mDNSPosix/Makefile
mDNSPosix/dnsextd.c
mDNSPosix/mDNSUNP.c
mDNSPosix/mDNSUNP.h
mDNSResponder.sln
mDNSShared/Java/DNSSD.java
mDNSShared/Java/JNISupport.c
mDNSShared/PlatformCommon.c
mDNSShared/dns_sd.h
mDNSShared/dnssd_clientlib.c
mDNSShared/dnssd_clientstub.c
mDNSShared/uds_daemon.c
mDNSVxWorks/mDNSVxWorksIPv4Only.c [new file with mode: 0644]
mDNSVxWorks/mDNSVxWorksIPv4Only.h [new file with mode: 0644]
mDNSWindows/ControlPanel/ConfigDialog.h [changed mode: 0755->0644]
mDNSWindows/ControlPanel/ControlPanel.def [changed mode: 0755->0644]
mDNSWindows/ControlPanel/ControlPanel.h [changed mode: 0755->0644]
mDNSWindows/ControlPanel/ControlPanel.rc [changed mode: 0755->0644]
mDNSWindows/ControlPanel/FirstPage.cpp
mDNSWindows/ControlPanel/SecondPage.cpp
mDNSWindows/ControlPanel/SecondPage.h
mDNSWindows/ControlPanel/SharedSecret.cpp [changed mode: 0755->0644]
mDNSWindows/ControlPanel/SharedSecret.h [changed mode: 0755->0644]
mDNSWindows/ControlPanel/resource.h [changed mode: 0755->0644]
mDNSWindows/DLL/dnssd.vcproj
mDNSWindows/Installer/Main.ism [new file with mode: 0644]
mDNSWindows/Installer/SDK.ism [new file with mode: 0644]
mDNSWindows/SystemService/Service.c
mDNSWindows/SystemServiceTest/Prefix.h [new file with mode: 0644]
mDNSWindows/SystemServiceTest/Tool.c [new file with mode: 0644]
mDNSWindows/SystemServiceTest/Tool.mcp [new file with mode: 0644]
mDNSWindows/SystemServiceTest/Tool2002.vcproj [new file with mode: 0644]
mDNSWindows/WinVersRes.h
mDNSWindows/dDNS.c
mDNSWindows/dDNS.h
mDNSWindows/loclibrary.c
mDNSWindows/mDNSWin32.c
mDNSWindows/mdnsNSP/mdnsNSP.c

index d4ea5c1d6849c8b6a3465f7d7f2b74ca7e151170..a68880b2a643aae03584be98f22dd215f1973832 100644 (file)
     Change History (most recent first):
     
 $Log: ExplorerBarWindow.cpp,v $
-Revision 1.21  2005/04/06 01:13:07  shersche
-<rdar://problem/4066195> Use the product icon instead of globe icon for 'About' link.
-
-Revision 1.20  2005/03/18 02:43:02  shersche
-<rdar://problem/4046443> Use standard IE website icon for 'About Bonjour', only using globe icon if standard icon cannot be loaded
-
-Revision 1.19  2005/03/16 03:46:27  shersche
-<rdar://problem/4045657> Use Bonjour icon for all discovered sites
-
 Revision 1.18  2005/02/26 01:24:05  shersche
 Remove display lines in tree control
 
@@ -152,10 +143,6 @@ static char THIS_FILE[] = __FILE__;
 
 #define        kTXTRecordKeyPath                               "path"
 
-// IE Icon resource
-
-#define kIEIconResource                                        32529
-
 
 #if 0
 #pragma mark == Prototypes ==
@@ -218,7 +205,6 @@ int ExplorerBarWindow::OnCreate( LPCREATESTRUCT inCreateStruct )
 {
        AFX_MANAGE_STATE( AfxGetStaticModuleState() );
        
-       HINSTANCE               module = NULL;
        OSStatus                err;
        CRect                   rect;
        CBitmap                 bitmap;
@@ -245,7 +231,7 @@ int ExplorerBarWindow::OnCreate( LPCREATESTRUCT inCreateStruct )
        mServiceHandlers.Add( e );
 
        s.LoadString( IDS_ABOUT );
-       m_about = mTree.InsertItem( s, 0, 0 );
+       m_about = mTree.InsertItem( s, 1, 1 );
 
        err = DNSServiceBrowse( &e->ref, 0, 0, e->type, NULL, BrowseCallBack, e );
        require_noerr( err, exit );
@@ -255,22 +241,17 @@ int       ExplorerBarWindow::OnCreate( LPCREATESTRUCT inCreateStruct )
 
        m_serviceRefs.push_back(e->ref);
 
-       m_imageList.Create( 16, 16, ILC_MASK | ILC_COLOR16, 2, 0);
-
-       bitmap.Attach( ::LoadBitmap( GetNonLocalizedResources(), MAKEINTRESOURCE( IDB_LOGO ) ) );
+       m_imageList.Create( 16, 16, ILC_COLORDDB, 2, 0);
+       bitmap.Attach( ::LoadBitmap( GetNonLocalizedResources(), MAKEINTRESOURCE( IDB_GLOBE ) ) );
        m_imageList.Add( &bitmap, (CBitmap*) NULL );
        bitmap.Detach();
+       bitmap.Attach( ::LoadBitmap( GetNonLocalizedResources(), MAKEINTRESOURCE( IDB_LOGO ) ) );
+       m_imageList.Add( &bitmap, (CBitmap*) NULL );
 
        mTree.SetImageList(&m_imageList, TVSIL_NORMAL);
        
 exit:
 
-       if ( module )
-       {
-               FreeLibrary( module );
-               module = NULL;
-       }
-
        // Cannot talk to the mDNSResponder service. Show the error message and exit (with kNoErr so they can see it).
        if ( err )
        {
index 34cf048a51f320cba9408d144ece006524978f1d..7e025f271d645f34e9eb079174bfdb696d7fd697 100755 (executable)
@@ -177,7 +177,7 @@ END
 STRINGTABLE \r
 BEGIN\r
     IDS_ABOUT               "About Bonjour"\r
-    IDS_ABOUT_URL           "http://www.apple.com/macosx/features/bonjour"\r
+    IDS_ABOUT_URL           "http://www.apple.com/macosx/features/rendezvous"\r
     IDS_NAME                "Bonjour"\r
     IDS_WEB_SITES           "Web Sites"\r
     IDS_PRINTERS            "Printers"\r
index 35f32be4f2cfc85bdde0ab9c377c33c3e779d364..bcb02693eae341813f5c3694b103db93aaed4517 100755 (executable)
@@ -13,7 +13,7 @@
        <Configurations>\r
                <Configuration\r
                        Name="Debug|Win32"\r
-                       OutputDirectory=".\Debug\ExplorerPlugin.Resources\en.lproj"\r
+                       OutputDirectory=".\Debug\Resources\ExplorerPlugin.dll.Resources\en.lproj"\r
                        IntermediateDirectory=".\Debug"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -71,8 +71,9 @@
                        <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
+                               CommandLine="if not exist Debug\Resources mkdir Debug\Resources\r
+if not exist Debug\Resources\ExplorerPlugin.dll.Resources mkdir Debug\Resources\ExplorerPlugin.dll.Resources\r
+if not exist Debug\Resources\ExplorerPlugin.dll.Resources\en.lproj mkdir Debug\Resources\ExplorerPlugin.dll.Resources\en.lproj"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="_DEBUG"\r
@@ -85,7 +86,7 @@ if not exist Debug\ExplorerPlugin.Resources\en.lproj mkdir Debug\ExplorerPlugin.
                </Configuration>\r
                <Configuration\r
                        Name="Release|Win32"\r
-                       OutputDirectory=".\Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources\en.lproj"\r
+                       OutputDirectory=".\Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources\en.lproj"\r
                        IntermediateDirectory=".\Release"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -150,8 +151,9 @@ if not exist Debug\ExplorerPlugin.Resources\en.lproj mkdir Debug\ExplorerPlugin.
                                CommandLine="if not exist Release\Root mkdir Release\Root\r
 if not exist &quot;Release\Root\Program Files&quot; mkdir &quot;Release\Root\Program Files&quot;\r
 if not exist &quot;Release\Root\Program Files\Bonjour&quot; mkdir &quot;Release\Root\Program Files\Bonjour&quot;\r
-if not exist &quot;Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources&quot;\r
-if not exist &quot;Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources\en.lproj&quot; mkdir &quot;Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources\en.lproj&quot;"/>\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources&quot;\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources&quot;\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources\en.lproj&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources\en.lproj&quot;"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="NDEBUG"\r
index 5ed5f4e20e270d8993c2baf32a981f566579010b..d97ab2039ff502ffe359068f2609a788a9b85dae 100755 (executable)
@@ -104,6 +104,7 @@ END
 \r
 IDB_LOGO                BITMAP                  "res\\logo.bmp"\r
 IDB_ABOUT               BITMAP                  "res\\about.bmp"\r
+IDB_GLOBE                                      BITMAP                                          "res\\globe.bmp"\r
 \r
 /////////////////////////////////////////////////////////////////////////////\r
 //\r
index 1429c246e8a62bf646e481e5c39d1b7c80891460..0949120516428fcb676bdf3cb5a8b23635dd8f28 100755 (executable)
@@ -13,7 +13,7 @@
        <Configurations>\r
                <Configuration\r
                        Name="Debug|Win32"\r
-                       OutputDirectory=".\Debug\ExplorerPlugin.Resources"\r
+                       OutputDirectory=".\Debug\Resources\ExplorerPlugin.dll.Resources"\r
                        IntermediateDirectory=".\Debug"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -70,7 +70,8 @@
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
                                Description="Building Output Directories"\r
-                               CommandLine="if not exist Debug\ExplorerPlugin.Resources mkdir Debug\ExplorerPlugin.Resources"/>\r
+                               CommandLine="if not exist Debug\Resources mkdir Debug\Resources\r
+if not exist Debug\Resources\ExplorerPlugin.dll.Resources mkdir Debug\Resources\ExplorerPlugin.dll.Resources"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="_DEBUG"\r
@@ -83,7 +84,7 @@
                </Configuration>\r
                <Configuration\r
                        Name="Release|Win32"\r
-                       OutputDirectory=".\Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources"\r
+                       OutputDirectory=".\Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources"\r
                        IntermediateDirectory=".\Release"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
                                CommandLine="if not exist Release\Root mkdir Release\Root\r
 if not exist &quot;Release\Root\Program Files&quot; mkdir &quot;Release\Root\Program Files&quot;\r
 if not exist &quot;Release\Root\Program Files\Bonjour&quot; mkdir &quot;Release\Root\Program Files\Bonjour&quot;\r
-if not exist &quot;Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources&quot;"/>\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources&quot;\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources&quot;"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="NDEBUG"\r
diff --git a/Clients/ExplorerPlugin/res/globe.bmp b/Clients/ExplorerPlugin/res/globe.bmp
new file mode 100755 (executable)
index 0000000..af43b4e
Binary files /dev/null and b/Clients/ExplorerPlugin/res/globe.bmp differ
index c4aae0a10a7a0d598f9b94b4cc724b44fb209d40..4f66a0cc966d16f34ef7f3bcbb18a6ed4743e831 100755 (executable)
@@ -11,6 +11,7 @@
 #define IDI_BUTTON_2K                   115\r
 #define IDI_BUTTON_XP                   118\r
 #define IDB_ABOUT                       119\r
+#define IDB_GLOBE                       149\r
 #define IDC_COMPONENT                   1001\r
 #define IDC_LEGAL                       1002\r
 #define IDC_LOGIN_USERNAME_TEXT         1182\r
index f8c4adae333533d7a2067b3559b2dae8c06285d5..530b26cf8520670fda0a3d7863f136f8c2e9adbf 100644 (file)
@@ -23,9 +23,6 @@
     Change History (most recent first):
     
 $Log: FirstPage.cpp,v $
-Revision 1.4  2005/03/16 01:41:29  shersche
-<rdar://problem/3989644> Remove info icon from first page
-
 Revision 1.3  2005/01/25 08:58:08  shersche
 <rdar://problem/3911084> Load icons at run-time from resource DLLs
 Bug #: 3911084
@@ -80,6 +77,18 @@ void CFirstPage::DoDataExchange(CDataExchange* pDX)
 BOOL
 CFirstPage::OnSetActive()
 {
+       static bool firstTime = true;
+
+       if ( firstTime )
+       {
+               CStatic * image = (CStatic*) GetDlgItem( IDC_INFO );
+               check( image );
+
+               image->SetIcon( LoadIcon( GetNonLocalizedResources(), MAKEINTRESOURCE( IDI_INFO ) ) );
+
+               firstTime = false;
+       }
+
        CPropertySheet* psheet = (CPropertySheet*) GetParent();   
    
        psheet->SetWizardButtons(PSWIZB_NEXT);
index 7b6544313604e74af47fcd109d2d7de20ca8349a..08a0505ae4e6a05bf549a2c4af044bd975ff36fb 100644 (file)
@@ -23,9 +23,6 @@
     Change History (most recent first):
     
 $Log: PrinterSetupWizardApp.cpp,v $
-Revision 1.8  2005/04/13 17:43:39  shersche
-<rdar://problem/4081448> Change "PrinterWizard.dll" to "PrinterWizardResources.dll"
-
 Revision 1.7  2005/02/15 07:50:09  shersche
 <rdar://problem/4007151> Update name
 
@@ -126,7 +123,7 @@ BOOL CPrinterSetupWizardApp::InitInstance()
 
        // Load Resources
 
-       res = PathForResource( NULL, L"PrinterWizardResources.dll", resource, MAX_PATH );
+       res = PathForResource( NULL, L"PrinterWizard.dll", resource, MAX_PATH );
        err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
        require_noerr( err, exit );
 
index 56319c3b24a768e0ca6869bd5d89c1e5f7d92e23..7a2842fc498dd6c7626756245c29afb2fdc9e36b 100755 (executable)
@@ -79,11 +79,11 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55\r
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | \r
     WS_SYSMENU\r
-CAPTION "About Printer Wizard"\r
+CAPTION "About Printer Setup Wizard"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x1\r
 BEGIN\r
     ICON            128,IDC_STATIC,11,17,20,20\r
-    LTEXT           "Printer Wizard Version 1.0",IDC_STATIC,40,10,119,\r
+    LTEXT           "Printer Setup Wizard Version 1.0",IDC_STATIC,40,10,119,\r
                     8,SS_NOPREFIX\r
     LTEXT           "Copyright (C) 2002",IDC_STATIC,40,25,119,8\r
     DEFPUSHBUTTON   "OK",IDOK,178,7,50,16,WS_GROUP\r
@@ -93,7 +93,7 @@ IDD_PRINTERSETUPWIZARD_DIALOG DIALOGEX 0, 0, 320, 200
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | \r
     WS_CAPTION | WS_SYSMENU\r
 EXSTYLE WS_EX_APPWINDOW\r
-CAPTION "Bonjour Printer Wizard"\r
+CAPTION "Printer Setup Wizard"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x1\r
 BEGIN\r
     DEFPUSHBUTTON   "OK",IDOK,263,7,50,16\r
@@ -123,11 +123,12 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Bonjour Printer Wizard"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
 BEGIN\r
-    LTEXT           "Welcome to the Bonjour Printer Wizard",\r
+    LTEXT           "Welcome to the Bonjour Printer Setup Wizard",\r
                     IDC_GREETING,114,7,171,46\r
-    LTEXT           "To continue, click Next.",IDC_STATIC,115,188,143,8\r
+    LTEXT           "Click next to continue.",IDC_STATIC,115,188,143,8\r
     LTEXT           "This wizard helps you connect to a shared printer using Bonjour.  Make sure your printer is turned on and connected to your network.",\r
-                    IDC_STATIC,114,60,171,62\r
+                    IDC_STATIC,146,60,139,62\r
+    ICON            "",IDC_INFO,118,60,20,20,SS_REALSIZEIMAGE\r
 END\r
 \r
 IDD_THIRD_PAGE DIALOGEX 0, 0, 290, 154\r
@@ -142,9 +143,9 @@ BEGIN
     CONTROL         "",IDC_PRINTER_MANUFACTURER,"SysListView32",LVS_REPORT | \r
                     LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | \r
                     LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,2,58,105,76\r
-    ICON            1017,1,3,5,20,27\r
+    ICON            1017,1,0,0,20,27\r
     LTEXT           "",IDC_PRINTER_NAME,40,5,173,8\r
-    LTEXT           "The Bonjour Printer Wizard has auto-selected the following printer settings.  To continue installing this printer, click Next.",\r
+    LTEXT           "The Bonjour Printer Wizard has auto-selected the following printer settings.  Click 'Next' to continue installing this printer.",\r
                     IDC_PRINTER_SELECTION_TEXT,40,18,243,33\r
     CONTROL         "Use this printer as the default printer",\r
                     IDC_DEFAULT_PRINTER,"Button",BS_AUTOCHECKBOX | \r
@@ -159,20 +160,20 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
 BEGIN\r
     LTEXT           "Completing the Bonjour Printer Wizard",IDC_GOODBYE,\r
                     116,7,171,27\r
-    LTEXT           "You are ready to complete the Bonjour Printer Wizard.  The printer has the following settings:",\r
-                    IDC_STATIC,116,42,171,31\r
+    LTEXT           "You have successfully completed the Bonjour Printer Wizard.  The printer has the following settings:",\r
+                    IDC_STATIC,116,42,158,31\r
     LTEXT           "Name:",IDC_STATIC,116,78,22,8\r
     LTEXT           "Manufacturer:",IDC_STATIC,116,91,47,8\r
     LTEXT           "Model:",IDC_STATIC,116,104,22,8\r
     LTEXT           "Protocol:",IDC_STATIC,116,117,38,8\r
     LTEXT           "Default:",IDC_STATIC,116,130,27,8\r
-    LTEXT           "",IDC_PRINTER_NAME,172,78,113,8,SS_ENDELLIPSIS\r
+    LTEXT           "",IDC_PRINTER_NAME,172,78,113,8\r
     LTEXT           "",IDC_PRINTER_MANUFACTURER,172,91,113,8\r
     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 close this wizard, click Finish.",IDC_STATIC,116,187,\r
+                    103,8\r
 END\r
 \r
 IDD_DIALOG1 DIALOGEX 0, 0, 265, 130\r
@@ -235,15 +236,15 @@ END
 \r
 STRINGTABLE \r
 BEGIN\r
-    IDS_ABOUTBOX            "&About Bonjour Printer Wizard..."\r
-    IDS_GOODBYE             "Completing the Bonjour Printer Wizard."\r
-    IDS_GREETING            "Welcome to the Bonjour Printer Wizard"\r
+    IDS_ABOUTBOX            "&About Printer Setup Wizard..."\r
+    IDS_GOODBYE             "Completing the Bonjour Printer Setup Wizard."\r
+    IDS_GREETING            "Welcome to the Bonjour Printer Setup Wizard"\r
     IDS_BROWSE_TITLE        "Browse for Bonjour Printers"\r
     IDS_BROWSE_SUBTITLE     "Select the printer you want to use from the list below."\r
     IDS_CAPTION             "Bonjour Printer Wizard"\r
-    IDS_GOODBYE_GOOD1       "You are ready to complete the Bonjour Printer Wizard.  The printer has the following settings:"\r
+    IDS_GOODBYE_GOOD1       "You have successfully completed the Bonjour Printer Wizard.  The printer has the following settings:"\r
     IDS_SEARCHING           "Searching for printers..."\r
-    IDS_GOODBYTE_GOOD2      "To complete the installation, click Finish."\r
+    IDS_GOODBYTE_GOOD2      "To close this wizard, click Finish."\r
     IDS_INSTALL_TITLE       "Install Bonjour Printer"\r
     IDS_INSTALL_SUBTITLE    "The manufacturer and model determine which printer software to use."\r
 END\r
index c8ea960e58161de109e899c00fe9500e587ee4d2..c97e842287839ddad98870a7c1a412a758168118 100755 (executable)
@@ -12,7 +12,7 @@
        <Configurations>\r
                <Configuration\r
                        Name="Debug|Win32"\r
-                       OutputDirectory=".\Debug\PrinterWizard.Resources\en.lproj"\r
+                       OutputDirectory=".\Debug\Resources\PrinterWizard.exe.Resources\en.lproj"\r
                        IntermediateDirectory=".\Debug"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -57,8 +57,9 @@
                        <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
+                               CommandLine="if not exist Debug\Resources mkdir Debug\Resources\r
+if not exist Debug\Resources\PrinterWizard.exe.Resources mkdir Debug\Resources\PrinterWizard.exe.Resources\r
+if not exist Debug\Resources\PrinterWizard.exe.Resources\en.lproj mkdir Debug\Resources\PrinterWizard.exe.Resources\en.lproj\r
 "/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
@@ -72,7 +73,7 @@ if not exist Debug\PrinterWizard.Resources\en.lproj mkdir Debug\PrinterWizard.Re
                </Configuration>\r
                <Configuration\r
                        Name="Release|Win32"\r
-                       OutputDirectory=".\Release\Root\Program Files\Bonjour\PrinterWizard.Resources\en.lproj"\r
+                       OutputDirectory=".\Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources\en.lproj"\r
                        IntermediateDirectory=".\Release"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -122,8 +123,9 @@ if not exist Debug\PrinterWizard.Resources\en.lproj mkdir Debug\PrinterWizard.Re
                                CommandLine="if not exist Release\Root mkdir Release\Root\r
 if not exist &quot;Release\Root\Program Files&quot; mkdir &quot;Release\Root\Program Files&quot;\r
 if not exist &quot;Release\Root\Program Files\Bonjour&quot; mkdir &quot;Release\Root\Program Files\Bonjour&quot;\r
-if not exist &quot;Release\Root\Program Files\Bonjour\PrinterWizard.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\PrinterWizard.Resources&quot;\r
-if not exist &quot;Release\Root\Program Files\Bonjour\PrinterWizard.Resources\en.lproj&quot; mkdir &quot;Release\Root\Program Files\Bonjour\PrinterWizard.Resources\en.lproj&quot;"/>\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources&quot;\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources&quot;\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources\en.lproj&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources\en.lproj&quot;"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="NDEBUG"\r
index 33b9fe8ed30945f63404a8fb6bdaa4b666484463..79424ffad9c085e18a4775c576f1e4f615209d28 100755 (executable)
@@ -12,7 +12,7 @@
        <Configurations>\r
                <Configuration\r
                        Name="Debug|Win32"\r
-                       OutputDirectory=".\Debug\PrinterWizard.Resources"\r
+                       OutputDirectory=".\Debug\Resources\PrinterWizard.exe.Resources"\r
                        IntermediateDirectory=".\Debug"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -38,7 +38,7 @@
                                Name="VCCustomBuildTool"/>\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               OutputFile="$(OutDir)/PrinterWizardResources.dll"\r
+                               OutputFile="$(OutDir)/PrinterWizard.dll"\r
                                LinkIncremental="2"\r
                                GenerateDebugInformation="TRUE"\r
                                SubSystem="2"\r
@@ -57,7 +57,8 @@
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
                                Description="Building Output Directories"\r
-                               CommandLine="if not exist Debug\PrinterWizard.Resources mkdir Debug\PrinterWizard.Resources"/>\r
+                               CommandLine="if not exist Debug\Resources mkdir Debug\Resources\r
+if not exist Debug\Resources\PrinterWizard.exe.Resources mkdir Debug\Resources\PrinterWizard.exe.Resources"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="_DEBUG"\r
@@ -70,7 +71,7 @@
                </Configuration>\r
                <Configuration\r
                        Name="Release|Win32"\r
-                       OutputDirectory=".\Release\Root\Program Files\Bonjour\PrinterWizard.Resources"\r
+                       OutputDirectory=".\Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources"\r
                        IntermediateDirectory=".\Release"\r
                        ConfigurationType="2"\r
                        UseOfMFC="1"\r
@@ -96,7 +97,7 @@
                                Name="VCCustomBuildTool"/>\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               OutputFile="$(OutDir)/PrinterWizardResources.dll"\r
+                               OutputFile="$(OutDir)/PrinterWizard.dll"\r
                                LinkIncremental="1"\r
                                GenerateDebugInformation="FALSE"\r
                                SubSystem="2"\r
                                CommandLine="if not exist Release\Root mkdir Release\Root\r
 if not exist &quot;Release\Root\Program Files&quot; mkdir &quot;Release\Root\Program Files&quot;\r
 if not exist &quot;Release\Root\Program Files\Bonjour&quot; mkdir &quot;Release\Root\Program Files\Bonjour&quot;\r
-if not exist &quot;Release\Root\Program Files\Bonjour\PrinterWizard.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\PrinterWizard.Resources&quot;"/>\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources&quot;\r
+if not exist &quot;Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources&quot; mkdir &quot;Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources&quot;"/>\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="NDEBUG"\r
index 378e56ce06071ee487f8049e20551c54ac1d0e24..75cda89d51ec2a8a856a6023b0fbcb7aece14b1b 100644 (file)
@@ -23,9 +23,6 @@
     Change History (most recent first):
     
 $Log: PrinterSetupWizardSheet.cpp,v $
-Revision 1.30  2005/04/13 17:46:22  shersche
-<rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
-
 Revision 1.29  2005/02/14 20:48:37  shersche
 <rdar://problem/4003710> Default pdl key to "application/postscript"
 
@@ -448,7 +445,7 @@ CPrinterSetupWizardSheet::InstallPrinterPDLAndLPR(Printer * printer, Service * s
        pInfo.pPortName                         =       printer->portName.GetBuffer();
        pInfo.pDriverName                       =       printer->modelName.GetBuffer();
        pInfo.pComment                          =       printer->displayModelName.GetBuffer();
-       pInfo.pLocation                         =       q->location.GetBuffer();
+       pInfo.pLocation                         =       service->location.GetBuffer();
        pInfo.pDevMode                          =       NULL;
        pInfo.pDevMode                          =       NULL;
        pInfo.pSepFile                          =       L"";
@@ -492,12 +489,9 @@ CPrinterSetupWizardSheet::InstallPrinterIPP(Printer * printer, Service * service
 {
        DEBUG_UNUSED( service );
 
-       Queue           *       q                = service->SelectedQueue();
        HANDLE                  hPrinter = NULL;
        PRINTER_INFO_2  pInfo;
        OSStatus                err;
-
-       check( q );
        
        //
        // add the printer
@@ -508,7 +502,7 @@ CPrinterSetupWizardSheet::InstallPrinterIPP(Printer * printer, Service * service
        pInfo.pPortName                 = printer->portName.GetBuffer();
        pInfo.pDriverName               = printer->modelName.GetBuffer();
        pInfo.pPrintProcessor   = L"winprint";
-       pInfo.pLocation                 = q->location.GetBuffer();
+       pInfo.pLocation                 = service->location.GetBuffer();
        pInfo.pComment                  = printer->displayModelName.GetBuffer();
        pInfo.Attributes                = PRINTER_ATTRIBUTE_NETWORK | PRINTER_ATTRIBUTE_LOCAL;
        
@@ -892,6 +886,8 @@ CPrinterSetupWizardSheet::OnResolve(
        CPrinterSetupWizardSheet        *       self;
        Service                                         *       service;
        Queue                                           *       q;
+       uint32_t                                                qpriority = kDefaultPriority;
+       CString                                                 qname;
        int                                                             idx;
        OSStatus                                                err;
 
@@ -929,6 +925,13 @@ CPrinterSetupWizardSheet::OnResolve(
        //
        service->portNumber = ntohs(inPort);
 
+       //
+       // parse the text record.
+       //
+
+       err = self->ParseTextRecord( service, inTXTSize, inTXT, qname, qpriority );
+       require_noerr( err, exit );
+
        if ( service->qtotal == 1 )
        {       
                //
@@ -945,13 +948,10 @@ CPrinterSetupWizardSheet::OnResolve(
 
                require_action( q, exit, err = E_OUTOFMEMORY );
 
-               //
-               // parse the text record.
-               //
-
-               err = self->ParseTextRecord( service, q, inTXTSize, inTXT );
-               require_noerr( err, exit );
 
+               q->name         = qname;
+               q->priority = qpriority;
+               
                service->queues.push_back( q );
 
                //
@@ -1033,7 +1033,7 @@ CPrinterSetupWizardSheet::OnQuery(
 
                require_action( q, exit, err = E_OUTOFMEMORY );
 
-               err = service->printer->window->ParseTextRecord( service, q, inRDLen, inTXT );
+               err = service->printer->window->ParseTextRecord( service, inRDLen, inTXT, q->name, q->priority );
                require_noerr( err, exit );
 
                //
@@ -1512,11 +1512,8 @@ exit:
 
 
 OSStatus
-CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_t inTXTSize, const char * inTXT )
+CPrinterSetupWizardSheet::ParseTextRecord( Service * service, uint16_t inTXTSize, const char * inTXT, CString & qname, uint32_t & qpriority )
 {
-       check( service );
-       check( q );
-
        // <rdar://problem/3946587> Use TXTRecord APIs declared in dns_sd.h
        
        bool                    qtotalDefined   = false;
@@ -1527,11 +1524,11 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
 
        // <rdar://problem/3987680> Default to queue "lp"
 
-       q->name = L"lp";
+       qname = L"lp";
 
        // <rdar://problem/4003710> Default pdl key to be "application/postscript"
 
-       q->pdl = L"application/postscript";
+       service->pdl = L"application/postscript";
 
        if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "rp", &len ) ) != NULL )
        {
@@ -1540,7 +1537,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->name );
+               err = UTF8StringToStringObject( buf, qname );
                require_noerr( err, exit );
        }
        
@@ -1551,7 +1548,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->pdl );
+               err = UTF8StringToStringObject( buf, service->pdl );
                require_noerr( err, exit );
        }
        
@@ -1563,7 +1560,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->usb_MFG );
+               err = UTF8StringToStringObject( buf, service->usb_MFG );
                require_noerr( err, exit );
        }
        
@@ -1575,7 +1572,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->usb_MDL );
+               err = UTF8StringToStringObject( buf, service->usb_MDL );
                require_noerr( err, exit );
        }
 
@@ -1586,7 +1583,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->description );
+               err = UTF8StringToStringObject( buf, service->description );
                require_noerr( err, exit );
        }
                
@@ -1597,7 +1594,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->product );
+               err = UTF8StringToStringObject( buf, service->product );
                require_noerr( err, exit );
        }
 
@@ -1608,7 +1605,7 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               err = UTF8StringToStringObject( buf, q->location );
+               err = UTF8StringToStringObject( buf, service->location );
                require_noerr( err, exit );
        }
 
@@ -1630,20 +1627,20 @@ CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_
                memcpy( buf, val, len );
                buf[len] = '\0';
 
-               q->priority = atoi( buf );
+               qpriority = atoi( buf );
        }
 
 exit:
 
        // The following code is to fix a problem with older HP 
        // printers that don't include "qtotal" in their text
-       // record.  We'll check to see if the q->name is "TEXT"
+       // record.  We'll check to see if the qname is "TEXT"
        // and if so, we're going to modify it to be "lp" so
        // that we don't use the wrong queue
 
-       if ( !err && !qtotalDefined && ( q->name == L"TEXT" ) )
+       if ( !err && !qtotalDefined && ( qname == L"TEXT" ) )
        {
-               q->name = "lp";
+               qname = "lp";
        }
 
        return err;
index 3bf77a61462608fa66c137e8a88ea1acd5c7fbf5..cf7f096f76b84b8b628efdcb3ddddc34d67d3746 100644 (file)
@@ -23,9 +23,6 @@
     Change History (most recent first):
     
 $Log: PrinterSetupWizardSheet.h,v $
-Revision 1.9  2005/04/13 17:46:22  shersche
-<rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
-
 Revision 1.8  2005/02/08 18:53:33  shersche
 Remove qtotalDefined parameter from ParseTextRecord()
 
@@ -244,7 +241,7 @@ private:
        StopResolve( Service * service );
 
        OSStatus
-       ParseTextRecord( Service * service, Queue * q, uint16_t inTXTSize, const char * inTXT );
+       ParseTextRecord( Service * service, uint16_t inTXTSize, const char * inTXT, CString & qname, uint32_t & qpriority );
 
        OSStatus
        LoadPrinterNames();
index f5647a61a19073898e873f06ee7263a3a26869f3..63665ee8f1f9e6bf05b10d4127b5711b32b18cc9 100644 (file)
     Change History (most recent first):
     
 $Log: SecondPage.cpp,v $
-Revision 1.15  2005/04/13 17:46:22  shersche
-<rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
-
-Revision 1.14  2005/03/20 20:08:37  shersche
-<rdar://problem/4055670> Second screen should not select a printer by default
-
 Revision 1.13  2005/02/15 07:50:10  shersche
 <rdar://problem/4007151> Update name
 
@@ -137,13 +131,6 @@ CSecondPage::InitBrowseList()
        // disable the printer information box
        //
        SetPrinterInformationState( FALSE );
-       m_descriptionField.SetWindowText( L"" );
-       m_locationField.SetWindowText( L"" );
-
-       //
-       // and wait for the user to either hit the mouse or keyboard before selecting an item
-       //
-       m_gotChoice = false;
 
 exit:
 
@@ -195,9 +182,6 @@ CSecondPage::OnSetActive()
        Printer                                         *       printer;
        Printers::iterator                              it;
        OSStatus                                                err = kNoErr;
-       BOOL                                                    b;
-
-       b = CPropertyPage::OnSetActive();
 
        psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
        require_action( psheet, exit, err = kUnknownErr );
@@ -223,7 +207,7 @@ CSecondPage::OnSetActive()
 
 exit:
 
-       return b;
+       return CPropertyPage::OnSetActive();
 }
 
 
@@ -236,8 +220,6 @@ CSecondPage::OnKillActive()
 
 BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
        ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSE_LIST, OnTvnSelchangedBrowseList)
-       ON_NOTIFY(NM_CLICK, IDC_BROWSE_LIST, OnNmClickBrowseList)
-       ON_NOTIFY(TVN_KEYDOWN, IDC_BROWSE_LIST, OnTvnKeyDownBrowseList)
        ON_WM_SETCURSOR()
 END_MESSAGE_MAP()
 
@@ -263,6 +245,11 @@ CSecondPage::OnAddPrinter(
        m_browseList.SetItemData( printer->item, (DWORD_PTR) printer );
 
        m_browseList.SortChildren(TVI_ROOT);
+               
+       if ( printer->name == m_selectedName )
+       {
+               m_browseList.SelectItem( printer->item );
+       }
 
        //
        // if the searching item is still in the list
@@ -346,13 +333,8 @@ CSecondPage::OnResolveService( Service * service )
 {
        CPrinterSetupWizardSheet * psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
        require_quiet( psheet, exit );
-
-       check( service );
-
-       Queue * q = service->SelectedQueue();
-
-       check( q );
        
+       check( service );
 
        //
        // and set it to selected
@@ -365,8 +347,8 @@ CSecondPage::OnResolveService( Service * service )
        //
        SetPrinterInformationState( TRUE );
 
-       m_descriptionField.SetWindowText( q->description );
-       m_locationField.SetWindowText( q->location );
+       m_descriptionField.SetWindowText( service->description );
+       m_locationField.SetWindowText( service->location );
 
        //
        // reset the cursor
@@ -384,44 +366,16 @@ void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
 {
        LPNMTREEVIEW                                    pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
        CPrinterSetupWizardSheet        *       psheet;
-       Printer                                         *       printer;
        int                                                             err = 0;
 
-       psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
-       require_action( psheet, exit, err = kUnknownErr );
-
-       // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
-       // we selected isn't passed through correctly to this callback routine.
-
-       if ( !m_gotChoice )
-       {
-               printer = psheet->GetSelectedPrinter();
-
-               // If we really haven't selected a printer, then re-select NULL and exit
-
-               if ( !printer )
-               {
-                       m_browseList.SelectItem( NULL );
-
-                       goto exit;
-               }
-
-               // If we already have selected a printer, fake like we've clicked on it, but only
-               // if the CTreeCtrl hasn't already selected it
-               
-               else if ( printer->item != m_browseList.GetSelectedItem() )
-               {
-                       m_gotChoice = true;
-
-                       m_browseList.SelectItem( printer->item );
-
-                       goto exit;
-               }
-       }
-
        HTREEITEM item = m_browseList.GetSelectedItem();
        require_quiet( item, exit );
 
+       psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
+       require_action( psheet, exit, err = kUnknownErr );      
+
+       Printer * printer;
+
        printer = reinterpret_cast<Printer*>(m_browseList.GetItemData( item ) );
        require_quiet( printer, exit );
 
@@ -456,26 +410,6 @@ exit:
 }
 
 
-void CSecondPage::OnNmClickBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
-{
-       DEBUG_UNUSED( pNMHDR );
-
-       m_gotChoice = true;
-
-       *pResult = 0;
-}
-
-
-void CSecondPage::OnTvnKeyDownBrowseList( NMHDR * pNMHDR, LRESULT * pResult)
-{
-       DEBUG_UNUSED( pNMHDR );
-
-       m_gotChoice = true;
-
-       *pResult = 0;
-}
-
-
 void
 CSecondPage::LoadTextAndDisableWindow( CString & text )
 {
index 5cf1852aa8093a5b0c5b0a75bd20fe31bf7405f7..aa0826083f910da34319936e6f2bf1ca53639569 100644 (file)
@@ -23,9 +23,6 @@
     Change History (most recent first):
     
 $Log: SecondPage.h,v $
-Revision 1.8  2005/03/20 20:08:37  shersche
-<rdar://problem/4055670> Second screen should not select a printer by default
-
 Revision 1.7  2005/01/31 23:54:30  shersche
 <rdar://problem/3947508> Start browsing when printer wizard starts. Move browsing logic from CSecondPage object to CPrinterSetupWizardSheet object.
 
@@ -98,8 +95,6 @@ public:
        bool                    m_waiting;
 
        afx_msg void    OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult);
-       afx_msg void    OnNmClickBrowseList(NMHDR * pNMHDR, LRESULT * pResult);
-       afx_msg void    OnTvnKeyDownBrowseList(NMHDR * pNMHDR, LRESULT * pResult );
 
        OSStatus
        OnAddPrinter(
@@ -131,6 +126,4 @@ private:
        CStatic m_descriptionField;\r
        CStatic m_locationLabel;\r
        CStatic m_locationField;\r
-
-       bool    m_gotChoice;
 };
index 8da4d40e8a7edd7d172a8cb1a49f6fa7815c92dc..acd8d3c5374d4ece89560516cf26577f7ac8b033 100644 (file)
     Change History (most recent first):
     
 $Log: ThirdPage.cpp,v $
-Revision 1.23  2005/04/18 02:33:47  shersche
-<rdar://problem/4091216> Default printer option cannot be deselected
-
-Revision 1.22  2005/04/13 17:46:22  shersche
-<rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
-
-Revision 1.21  2005/03/30 02:09:55  shersche
-Auto-resize the column width to account for differing fonts and font sizes
-
 Revision 1.20  2005/03/05 02:27:45  shersche
 <rdar://problem/4030388> Generic drivers don't do color
 
@@ -1048,27 +1039,20 @@ OSStatus CThirdPage::MatchPrinter(Manufacturers & manufacturers, Printer * print
        CString                                 text;
        OSStatus                                err                                     =       kNoErr;
 
-       check( printer );
-       check( service );
-
-       Queue * q = service->SelectedQueue();
-
-       check( q );
-
        //
        // first look to see if we have a usb_MFG descriptor
        //
-       if ( q->usb_MFG.GetLength() > 0)
+       if (service->usb_MFG.GetLength() > 0)
        {
-               manufacturer = MatchManufacturer( manufacturers, ConvertToManufacturerName ( q->usb_MFG ) );
+               manufacturer = MatchManufacturer( manufacturers, ConvertToManufacturerName ( service->usb_MFG ) );
        }
 
        if ( manufacturer == NULL )
        {
-               q->product.Remove('(');
-               q->product.Remove(')');
+               service->product.Remove('(');
+               service->product.Remove(')');
 
-               manufacturer = MatchManufacturer( manufacturers, ConvertToManufacturerName ( q->product ) );
+               manufacturer = MatchManufacturer( manufacturers, ConvertToManufacturerName ( service->product ) );
        }
        
        //
@@ -1076,17 +1060,17 @@ OSStatus CThirdPage::MatchPrinter(Manufacturers & manufacturers, Printer * print
        //
        if ( manufacturer != NULL )
        {
-               if ( q->usb_MDL.GetLength() > 0 )
+               if (service->usb_MDL.GetLength() > 0)
                {
-                       model = MatchModel ( manufacturer, ConvertToModelName ( q->usb_MDL ) );
+                       model = MatchModel ( manufacturer, ConvertToModelName ( service->usb_MDL ) );
                }
 
-               if ( ( model == NULL ) && ( q->product.GetLength() > 0 ) )
+               if ( ( model == NULL ) && ( service->product.GetLength() > 0 ) )
                {
-                       q->product.Remove('(');
-                       q->product.Remove(')');
+                       service->product.Remove('(');
+                       service->product.Remove(')');
 
-                       model = MatchModel ( manufacturer, ConvertToModelName ( q->product ) );
+                       model = MatchModel ( manufacturer, ConvertToModelName ( service->product ) );
                }
 
                if ( model != NULL )
@@ -1270,18 +1254,12 @@ CThirdPage::MatchGeneric( Printer * printer, Service * service, Manufacturer **
 
        DEBUG_UNUSED( printer );
 
-       check( service );
-
-       Queue * q = service->SelectedQueue();
-
-       check( q );
-
        Manufacturers::iterator iter = m_manufacturers.find( kGenericManufacturer );
        require_action_quiet( iter != m_manufacturers.end(), exit, ok = FALSE );
 
        *manufacturer = iter->second;
 
-       pdl = q->pdl;
+       pdl = service->pdl;
        pdl.MakeLower();
 
        if ( pdl.Find( kPDLPCLKey ) != -1 )
@@ -1345,11 +1323,11 @@ OSStatus CThirdPage::OnInitPage()
        // selection notice
        //
        header.LoadString(IDS_MANUFACTURER_HEADING);
-       m_manufacturerListCtrl.InsertColumn(0, header, LVCFMT_LEFT, -1 );
+       m_manufacturerListCtrl.InsertColumn(0, header, LVCFMT_LEFT, 138);
        m_manufacturerSelected = NULL;
 
        header.LoadString(IDS_MODEL_HEADING);
-       m_modelListCtrl.InsertColumn(0, header, LVCFMT_LEFT, -1 );
+       m_modelListCtrl.InsertColumn(0, header, LVCFMT_LEFT, 247);
        m_modelSelected = NULL;
 
        return (err);
@@ -1453,8 +1431,6 @@ CThirdPage::PopulateUI(Manufacturers & manufacturers)
                nIndex = m_manufacturerListCtrl.InsertItem(0, manufacturer->name);
 
                m_manufacturerListCtrl.SetItemData(nIndex, (DWORD_PTR) manufacturer);
-
-               m_manufacturerListCtrl.SetColumnWidth( 0, LVSCW_AUTOSIZE_USEHEADER );
        }
 
        return 0;
@@ -1495,8 +1471,6 @@ void CThirdPage::OnLvnItemchangedManufacturer(NMHDR *pNMHDR, LRESULT *pResult)
                        int nItem = m_modelListCtrl.InsertItem( 0, model->displayName );
 
                        m_modelListCtrl.SetItemData(nItem, (DWORD_PTR) model);
-
-                       m_modelListCtrl.SetColumnWidth( 0, LVSCW_AUTOSIZE_USEHEADER );
                }
 
                m_modelListCtrl.SetRedraw(TRUE);
@@ -1557,7 +1531,7 @@ void CThirdPage::OnBnClickedDefaultPrinter()
        printer = psheet->GetSelectedPrinter();
        require_quiet( printer, exit );
 
-       printer->deflt = ( m_defaultPrinterCtrl.GetCheck() == BST_CHECKED ) ? true : false;
+       printer->deflt = m_defaultPrinterCtrl.GetState() ? true : false;
 
 exit:
 
index 4496e0cc8acc98d6aa1a3c4a0ef4a9ec19c6c9de..5e2fe196ef91357c12bc4e211281a1b83ce7ac21 100644 (file)
     Change History (most recent first):
     
 $Log: UtilTypes.h,v $
-Revision 1.13  2005/04/13 17:46:22  shersche
-<rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
-
-Revision 1.12  2005/03/16 03:12:28  shersche
-<rdar://problem/4050504> Generic PCL driver isn't selected correctly on Win2K
-
 Revision 1.11  2005/03/05 02:27:46  shersche
 <rdar://problem/4030388> Generic drivers don't do color
 
@@ -155,9 +149,6 @@ namespace PrinterSetupWizard
 
                ~Service();
 
-               Queue*
-               SelectedQueue();
-
                void
                EmptyQueues();
 
@@ -172,6 +163,12 @@ namespace PrinterSetupWizard
                DNSServiceRef   serviceRef;
                CString                 hostname;
                unsigned short  portNumber;
+               CString                 pdl;
+               CString                 usb_MFG;
+               CString                 usb_MDL;
+               CString                 description;
+               CString                 location;
+               CString                 product;
                CString                 protocol;
                unsigned short  qtotal;
 
@@ -197,12 +194,6 @@ namespace PrinterSetupWizard
 
                CString         name;
                uint32_t        priority;
-               CString         pdl;
-               CString         usb_MFG;
-               CString         usb_MDL;
-               CString         description;
-               CString         location;
-               CString         product;
        };
 
 
@@ -278,12 +269,6 @@ namespace PrinterSetupWizard
                EmptyQueues();
        }
 
-       inline Queue*
-       Service::SelectedQueue()
-       {
-               return queues.front();
-       }
-
        inline void
        Service::EmptyQueues()
        {
@@ -316,7 +301,7 @@ namespace PrinterSetupWizard
                {
                        Model * model = *it;
 
-                       if ( model->name == name )
+                       if ( model->name = name )
                        {
                                return model;
                        }
index b737f473253cde006f562cdca30f025db8646439..22130b3de3ee242e78b347bc07d177cf3cd44a10 100644 (file)
Binary files a/Clients/PrinterSetupWizard/res/NetworkPrinter.ico and b/Clients/PrinterSetupWizard/res/NetworkPrinter.ico differ
index b737f473253cde006f562cdca30f025db8646439..22130b3de3ee242e78b347bc07d177cf3cd44a10 100644 (file)
Binary files a/Clients/PrinterSetupWizard/res/Print.ico and b/Clients/PrinterSetupWizard/res/Print.ico differ
index 2fdc66f8b77e8627960938266212893d6e5621bf..699a93286da4ad51aa85c27cf8f944ddc1a808cc 100644 (file)
@@ -550,7 +550,7 @@ static DNSServiceErrorType RegisterService(DNSServiceRef *sdRef,
        for (i = 0; i < argc; i++)
                {
                unsigned char *len = ptr++;
-               *len = (unsigned char) strlen(argv[i]);
+               *len = strlen(argv[i]);
                strcpy((char*)ptr, argv[i]);
                ptr += *len;
                }
@@ -558,7 +558,7 @@ static DNSServiceErrorType RegisterService(DNSServiceRef *sdRef,
        printf("Registering Service %s.%s%s", nam, typ, dom);
        if (host && *host) printf(" host %s", host);
        printf(" port %s %s\n", port, txt);
-       return(DNSServiceRegister(sdRef, /* kDNSServiceFlagsAllowRemoteQuery */ 0, opinterface, nam, typ, dom, host, registerPort.NotAnInteger, (uint16_t) (ptr-txt), txt, reg_reply, NULL));
+       return(DNSServiceRegister(sdRef, /* kDNSServiceFlagsAllowRemoteQuery */ 0, opinterface, nam, typ, dom, host, registerPort.NotAnInteger, ptr-txt, txt, reg_reply, NULL));
        }
 
 int main(int argc, char **argv)
@@ -584,14 +584,6 @@ int main(int argc, char **argv)
                printf("Using LocalOnly\n");
                }
 
-       if (argc > 2 && !strcmp(argv[1], "-i") && atoi(argv[2]))
-               {
-               opinterface = atoi(argv[2]);
-               argc -= 2;
-               argv += 2;
-               printf("Using interface %d\n", opinterface);
-               }
-
        if (argc < 2) goto Fail;        // Minimum command line is the command name and one argument
        operation = getfirstoption( argc, argv, "EFBLQRPAUNTMI", &optind);
        if (operation == -1) goto Fail;
index 924853bfc4c4302208834b80edb9a7d95565fec2..e4be589b3a6463337c3e9d345e65caa043f0fb7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 
 include /Developer/Makefiles/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-107.1"
+MVERS = "mDNSResponder-107.3"
 
 install:
        cd "$(SRCROOT)/mDNSMacOSX"; xcodebuild install     OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) DSTROOT=$(DSTROOT) MVERS=$(MVERS)
index e68c865ab07a6abe99fcdc92224a7cd0324f015d..d89a42bce2ab23fb9f50f5dc44f45aec1b2a9aa8 100755 (executable)
@@ -45,9 +45,6 @@
     Change History (most recent first):
 
 $Log: mDNS.c,v $
-Revision 1.523  2005/03/21 00:33:51  shersche
-<rdar://problem/4021486> Fix build warnings on Win32 platform
-
 Revision 1.522  2005/03/04 21:48:12  cheshire
 <rdar://problem/4037283> Fractional time rounded down instead of up on platforms with coarse clock granularity
 
@@ -3139,7 +3136,7 @@ mDNSlocal void SendResponses(mDNS *const m)
                                        newptr = PutResourceRecordTTL(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec, m->SleepState ? 0 : rr->resrec.rroriginalttl);
                                        rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;                   // Make sure to clear cache flush bit back to normal state
                                        if (!newptr && m->omsg.h.numAnswers) break;
-                                       rr->RequireGoodbye = (mDNSu8) (!m->SleepState);
+                                       rr->RequireGoodbye = !m->SleepState;
                                        if (rr->LastAPTime == m->timenow) numAnnounce++; else numAnswer++;
                                        responseptr = newptr;
                                        }
index 70439f312d64f8b26cabaa288770d739016d9901..1029e21bea0c586151aceeb71415bcce96aed6d9 100755 (executable)
     Change History (most recent first):
 
 $Log: mDNSEmbeddedAPI.h,v $
+Revision 1.284  2005/07/29 18:04:22  ksekar
+<rdar://problem/4137930> Hostname registration should register IPv6 AAAA record with DNS Update
+
+Revision 1.283  2005/05/13 20:45:09  ksekar
+<rdar://problem/4074400> Rapid wide-area txt record updates don't work
+
 Revision 1.282  2005/03/16 00:42:32  ksekar
 <rdar://problem/4012279> Long-lived queries not working on Windows
 
@@ -1509,10 +1515,11 @@ typedef struct
     mDNSBool     SRVChanged;              // temporarily deregistered service because its SRV target or port changed
 
     // uDNS_UpdateRecord support fields
-       mDNSBool     UpdateQueued; // Update the rdata once the current pending operation completes
-       RData       *UpdateRData;  // Pointer to new RData while a record update is in flight
-       mDNSu16      UpdateRDLen;  // length of above field
-       mDNSRecordUpdateCallback *UpdateRDCallback; // client callback to free old rdata
+    RData *OrigRData;      mDNSu16 OrigRDLen;     // previously registered, being deleted
+    RData *InFlightRData;  mDNSu16 InFlightRDLen; // currently being registered
+    RData *QueuedRData;    mDNSu16 QueuedRDLen;   // if the client call Update while an update is in flight, we must finish the
+                                                  // pending operation (re-transmitting if necessary) THEN register the queued update
+       mDNSRecordUpdateCallback *UpdateRDCallback;   // client callback to free old rdata
        } uDNS_RegInfo;
 
 struct AuthRecord_struct
@@ -1630,7 +1637,9 @@ typedef struct
 typedef struct uDNS_HostnameInfo
        {
        struct uDNS_HostnameInfo *next;
-       AuthRecord *ar;                           // registered address record
+    domainname fqdn;
+    AuthRecord *arv4;                         // registered IPv4 address record
+       AuthRecord *arv6;                         // registered IPv6 address record
        mDNSRecordCallback *StatusCallback;       // callback to deliver success or error code to client layer
        const void *StatusContext;                // Client Context
        } uDNS_HostnameInfo;
@@ -2013,8 +2022,9 @@ typedef struct
        mDNSu16          NextMessageID;
     DNSServer        *Servers;           // list of DNS servers
        mDNSAddr         Router;
-       mDNSAddr         PrimaryIP;          // Address of primary interface
-       mDNSAddr         MappedPrimaryIP;    // Cache of public address if PrimaryIP is behind a NAT
+       mDNSAddr         AdvertisedV4;       // IPv4 address pointed to by hostname
+       mDNSAddr         MappedV4;           // Cache of public address if PrimaryIP is behind a NAT
+       mDNSAddr         AdvertisedV6;       // IPv6 address pointed to by hostname
     NATTraversalInfo *LLQNatInfo;        // Nat port mapping to receive LLQ events
        domainname       ServiceRegDomain;   // (going away w/ multi-user support)
        struct uDNS_AuthInfo *AuthInfoList;  // list of domains requiring authentication for updates.
@@ -2514,10 +2524,10 @@ extern mStatus mDNS_SetSecretForZone(mDNS *m, const domainname *zone, const doma
 
 // Hostname/Unicast Interface Configuration
 
-// All hostnames advertised point to a single IP address, set via SetPrimaryInterfaceInfo.  Invoking this routine
+// All hostnames advertised point to one IPv4 address and/or one IPv6 address, set via SetPrimaryInterfaceInfo.  Invoking this routine
 // updates all existing hostnames to point to the new address.
        
-// A hostname is added via AddDynDNSHostName, which points to the primary interface's IP address.
+// A hostname is added via AddDynDNSHostName, which points to the primary interface's v4 and/or v6 addresss
 
 // The status callback is invoked to convey success or failure codes - the callback should not modify the AuthRecord or free memory.
 // Added hostnames may be removed (deregistered) via mDNS_RemoveDynDNSHostName.
@@ -2535,7 +2545,7 @@ extern mStatus mDNS_SetSecretForZone(mDNS *m, const domainname *zone, const doma
        
 extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext);
 extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
-extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *addr, const mDNSAddr *router);
+extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr,  const mDNSAddr *v6addr, const mDNSAddr *router);
 extern void mDNS_UpdateLLQs(mDNS *m);
 extern void mDNS_AddDNSServer(mDNS *const m, const mDNSAddr *dnsAddr, const domainname *domain);
 extern void mDNS_DeleteDNSServers(mDNS *const m);
index f4ca81817c4c882f729adf647f3a85a84791582a..bed5c73d0192eead0153bb18e215b17de7075eca 100755 (executable)
     Change History (most recent first):
 
 $Log: uDNS.c,v $
+Revision 1.217  2005/08/04 18:08:24  cheshire
+Update comments
+
+Revision 1.216  2005/07/29 23:05:22  ksekar
+<rdar://problem/4137930> Hostname registration should register IPv6 AAAA record with DNS Update
+Services should point to IPv6 address if IPv4 NAT mapping fails
+
+Revision 1.215  2005/07/29 21:01:51  ksekar
+<rdar://problem/4137930> Hostname registration should register IPv6 AAAA record with DNS Update
+correction to original checkin - misplaced return in HostnameCallback and logic error determining v6 changes
+
+Revision 1.214  2005/07/29 19:46:10  ksekar
+<rdar://problem/4191860> reduce polling period on failed LLQs to 15 minutes
+
+Revision 1.213  2005/07/29 18:04:22  ksekar
+<rdar://problem/4137930> Hostname registration should register IPv6 AAAA record with DNS Update
+
+Revision 1.212  2005/07/22 19:35:50  ksekar
+<rdar://problem/4188821> SUTiger: LLQ event acknowledgments are not formated correctly
+
+Revision 1.211  2005/07/21 18:51:04  ksekar
+<rdar://problem/4103136> mDNSResponder times out when mapping ports after sleep
+
+Revision 1.210  2005/07/21 18:47:31  ksekar
+<rdar://problem/4137283> NAT-PMP refresh Requested Public Port should contain actual mapped port
+
+Revision 1.209  2005/07/04 21:16:37  cheshire
+Minor code tidying -- initialize variables where they are declared
+
+Revision 1.208  2005/06/28 00:24:28  ksekar
+<rdar://problem/4157823> memory smasher in conQueryCallback
+
+Revision 1.207  2005/05/13 20:45:10  ksekar
+<rdar://problem/4074400> Rapid wide-area txt record updates don't work
+
 Revision 1.206  2005/03/31 02:19:55  cheshire
 <rdar://problem/4021486> Fix build warnings
 Reviewed by: Scott Herscher
@@ -756,7 +791,6 @@ mDNSlocal void sendRecordRegistration(mDNS *const m, AuthRecord *rr);
 mDNSlocal void SendServiceRegistration(mDNS *m, ServiceRecordSet *srs);
 mDNSlocal void SendServiceDeregistration(mDNS *m, ServiceRecordSet *srs);
 mDNSlocal void serviceRegistrationCallback(mStatus err, mDNS *const m, void *srsPtr, const AsyncOpResult *result);
-mDNSlocal void SendRecordUpdate(mDNS *m, AuthRecord *rr, uDNS_RegInfo *info);
 mDNSlocal void SuspendLLQs(mDNS *m, mDNSBool DeregisterActive);
 mDNSlocal void RestartQueries(mDNS *m);
 mDNSlocal void startLLQHandshake(mDNS *m, LLQ_Info *info, mDNSBool defer);
@@ -863,25 +897,6 @@ mDNSlocal void LinkActiveQuestion(uDNS_GlobalInfo *u, DNSQuestion *q)
        u->ActiveQueries = q;
        }
 
-mDNSlocal void SwapRData(mDNS *m, AuthRecord *rr, mDNSBool DeallocOld)
-       {
-       RData *oldrd = rr->resrec.rdata;
-       mDNSu16 oldrdlen = rr->resrec.rdlength;
-
-       if (!rr->uDNS_info.UpdateRData) { LogMsg("SwapRData invoked with NULL UpdateRData field"); return; }
-       SetNewRData(&rr->resrec, rr->uDNS_info.UpdateRData, rr->uDNS_info.UpdateRDLen);
-       if (DeallocOld)
-               {
-               rr->uDNS_info.UpdateRData = mDNSNULL;                                                       // Clear the NewRData pointer ...
-               if (rr->uDNS_info.UpdateRDCallback) rr->uDNS_info.UpdateRDCallback(m, rr, oldrd);                                       // ... and let the client know
-               }
-       else
-               {
-               rr->uDNS_info.UpdateRData = oldrd;
-               rr->uDNS_info.UpdateRDLen = oldrdlen;
-               }
-       }
-
 // set retry timestamp for record with exponential backoff
 // (for service record sets, use RR_SRV as representative for time checks
 mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mStatus SendErr)
@@ -1200,15 +1215,15 @@ mDNSlocal mDNSBool ReceiveNATAddrResponse(NATTraversalInfo *n, mDNS *m, mDNSu8 *
        }
 
 
-mDNSlocal void StartGetPublicAddr(mDNS *m, uDNS_HostnameInfo *hInfo)
+mDNSlocal void StartGetPublicAddr(mDNS *m, AuthRecord *AddressRec)
        {
        NATAddrRequest *req;
        uDNS_GlobalInfo *u = &m->uDNS_info;
        
        NATTraversalInfo *info = AllocNATInfo(m, NATOp_AddrRequest, ReceiveNATAddrResponse);
-       if (!info) { uDNS_RegisterRecord(m, hInfo->ar); return; }
-       hInfo->ar->uDNS_info.NATinfo = info;
-       info->reg.RecordRegistration = hInfo->ar;
+       if (!info) { uDNS_RegisterRecord(m, AddressRec); return; }
+       AddressRec->uDNS_info.NATinfo = info;
+       info->reg.RecordRegistration = AddressRec;
        info->state = NATState_Request;
        
     // format message
@@ -1333,7 +1348,10 @@ mDNSlocal mDNSBool ReceivePortMapReply(NATTraversalInfo *n, mDNS *m, mDNSu8 *pkt
        if (n->state == NATState_Refresh && reply->pub.NotAnInteger != n->PublicPort.NotAnInteger)
                LogMsg("ReceivePortMapReply: NAT refresh changed public port from %d to %d", mDNSVal16(n->PublicPort), mDNSVal16(reply->pub));
         // this should never happen
+           // !!!KRS to be defensive, use SRVChanged flag on service and deregister here
+       
        n->PublicPort = reply->pub;
+       if (reply->pub.NotAnInteger != n->request.PortReq.pub.NotAnInteger) n->request.PortReq.pub = reply->pub; // set message buffer for refreshes
 
        n->retry = mDNSPlatformTimeNow(m) + ((mDNSs32)lease * mDNSPlatformOneSecond / 2);  // retry half way to expiration
 
@@ -1346,17 +1364,35 @@ mDNSlocal mDNSBool ReceivePortMapReply(NATTraversalInfo *n, mDNS *m, mDNSu8 *pkt
                LogMsg("NAT Port Mapping (%##s): timeout", service);
                if (pkt) LogMsg("!!! timeout with non-null packet");
                n->state = NATState_Error;
-               if (srs) srs->uDNS_info.state = regState_NATError;
+               if (srs)
+                       {
+                       uDNS_HostnameInfo *hi = m->uDNS_info.Hostnames;
+                       while (hi)
+                               {
+                               if (hi->arv6 && (hi->arv6->uDNS_info.state == regState_Registered || hi->arv6->uDNS_info.state == regState_Refresh)) break;
+                               else hi = hi->next;
+                               }
+
+                       if (hi)
+                               {
+                               debugf("Port map failed for service %##s - using IPv6 service target", service);
+                               srs->uDNS_info.NATinfo = mDNSNULL;
+                               FreeNATInfo(m, n);
+                               goto register_service;
+                               }
+                       else srs->uDNS_info.state = regState_NATError;
+                       }
                else LLQNatMapComplete(m);
-               return mDNStrue;  // note - unsafe to touch srs here
+               return mDNStrue;
                }
+       else LogOperation("Mapped private port %d to public port %d", mDNSVal16(priv), mDNSVal16(n->PublicPort));
 
-       LogOperation("Mapped private port %d to public port %d", mDNSVal16(priv), mDNSVal16(n->PublicPort));
        if (!srs) { LLQNatMapComplete(m); return mDNStrue; }
 
+       register_service:
        if (srs->uDNS_info.ns.ip.v4.NotAnInteger) SendServiceRegistration(m, srs);  // non-zero server address means we already have necessary zone data to send update
        else
-               {       
+               {
                srs->uDNS_info.state = regState_FetchingZoneData;
                startGetZoneData(srs->RR_SRV.resrec.name, m, mDNStrue, mDNSfalse, serviceRegistrationCallback, srs);
                }
@@ -1480,8 +1516,16 @@ mDNSlocal mDNSBool GetServiceTarget(uDNS_GlobalInfo *u, AuthRecord *srv, domainn
        dst->c[0] = 0;
        while (hi)
                {
-               if (hi->ar->uDNS_info.state == regState_Registered || hi->ar->uDNS_info.state == regState_Refresh)
-                       { AssignDomainName(dst, hi->ar->resrec.name); return mDNStrue; }
+               if (hi->arv4 && (hi->arv4->uDNS_info.state == regState_Registered || hi->arv4->uDNS_info.state == regState_Refresh))
+                       {
+                       AssignDomainName(dst, hi->arv4->resrec.name);
+                       return mDNStrue;
+                       }
+               if (hi->arv6 && (hi->arv6->uDNS_info.state == regState_Registered || hi->arv6->uDNS_info.state == regState_Refresh))
+                       {
+                       AssignDomainName(dst, hi->arv4->resrec.name);
+                       return mDNStrue;
+                       }
                hi = hi->next;
                }
 
@@ -1513,7 +1557,7 @@ mDNSlocal void UpdateSRV(mDNS *m, ServiceRecordSet *srs)
        NATTraversalInfo *nat = srs->uDNS_info.NATinfo;
        mDNSIPPort port = srs->RR_SRV.resrec.rdata->u.srv.port;
        mDNSBool NATChanged = mDNSfalse;
-       mDNSBool NowBehindNAT = port.NotAnInteger && IsPrivateV4Addr(&u->PrimaryIP);
+       mDNSBool NowBehindNAT = port.NotAnInteger && IsPrivateV4Addr(&u->AdvertisedV4);
        mDNSBool WereBehindNAT = nat != mDNSNULL;
        mDNSBool NATRouterChanged = nat && nat->Router.ip.v4.NotAnInteger != u->Router.ip.v4.NotAnInteger;
        mDNSBool PortWasMapped = nat && (nat->state == NATState_Established || nat->state == NATState_Legacy) && nat->PublicPort.NotAnInteger != port.NotAnInteger;
@@ -1525,7 +1569,7 @@ mDNSlocal void UpdateSRV(mDNS *m, ServiceRecordSet *srs)
        if (!TargetChanged && !NATChanged) return;
 
        debugf("UpdateSRV (%##s) HadZoneData=%d, TargetChanged=%d, HaveTarget=%d, NowBehindNAT=%d, WereBehindNAT=%d, NATRouterChanged=%d, PortWasMapped=%d",
-                  srs->RR_SRV.resrec.name->c,  HaveZoneData, TargetChanged, HaveTarget, NowBehindNAT, WereBehindNAT, NATRouterChanged, PortWasMapped); 
+                  srs->RR_SRV.resrec.name->c,  HaveZoneData, TargetChanged, HaveTarget, NowBehindNAT, WereBehindNAT, NATRouterChanged, PortWasMapped);
        
        switch(srs->uDNS_info.state)
                {
@@ -1554,7 +1598,7 @@ mDNSlocal void UpdateSRV(mDNS *m, ServiceRecordSet *srs)
                case regState_NoTarget:
                        if (HaveTarget)
                                {
-                               debugf("UpdateSRV: %s service %##s", HaveZoneData ? (NATChanged && NowBehindNAT ? "Starting Port Map for" : "Registering") : "Getting Zone Data for", srs->RR_SRV.resrec.name->c);      
+                               debugf("UpdateSRV: %s service %##s", HaveZoneData ? (NATChanged && NowBehindNAT ? "Starting Port Map for" : "Registering") : "Getting Zone Data for", srs->RR_SRV.resrec.name->c);
                                if (!HaveZoneData)
                                        {
                                        srs->uDNS_info.state = regState_FetchingZoneData;
@@ -1589,12 +1633,16 @@ mDNSlocal void UpdateSRVRecords(mDNS *m)
 mDNSlocal void HostnameCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
        {
        uDNS_HostnameInfo *hi = (uDNS_HostnameInfo *)rr->RecordContext;
-       mDNSu8 *ip = rr->resrec.rdata->u.ipv4.b;
-       
+               
        if (result == mStatus_MemFree)
                {
-               debugf("MemFree:  %##s IP %d.%d.%d.%d", rr->resrec.name->c, ip[0], ip[1], ip[2], ip[3]);
-               if (hi) ufree(hi);
+               if (hi)
+                       {
+                       if      (hi->arv4 == rr)                hi->arv4 = mDNSNULL;
+                       else if (hi->arv4 == rr)                hi->arv6 = mDNSNULL;
+                       rr->RecordContext = mDNSNULL;
+                       if (!hi->arv4 && !hi->arv6) ufree(hi);  // free hi when both v4 and v6 AuthRecs deallocated
+                       }
                ufree(rr);
                return;
                }
@@ -1602,22 +1650,34 @@ mDNSlocal void HostnameCallback(mDNS *const m, AuthRecord *const rr, mStatus res
        if (result)
                {
                // don't unlink or free - we can retry when we get a new address/router
-               LogMsg("HostnameCallback: Error %ld for registration of %##s IP %d.%d.%d.%d", result, rr->resrec.name->c, ip[0], ip[1], ip[2], ip[3]);
+               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);
+               else
+                       LogMsg("HostnameCallback: Error %ld for registration of %##s IP %.16a", result, rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
                if (!hi) { ufree(rr); return; }
-               if (hi->ar->uDNS_info.state != regState_Unregistered) LogMsg("Error: HostnameCallback invoked with error code for record not in regState_Unregistered!");
-               rr->RecordContext = (void *)hi->StatusContext;
-               if (hi->StatusCallback)
-                       hi->StatusCallback(m, rr, result); // client may NOT make API calls here
-               rr->RecordContext = (void *)hi;
+               if (rr->uDNS_info.state != regState_Unregistered) LogMsg("Error: HostnameCallback invoked with error code for record not in regState_Unregistered!");
+
+               if ((!hi->arv4 || hi->arv4->uDNS_info.state == regState_Unregistered) &&
+                       (!hi->arv6 || hi->arv6->uDNS_info.state == regState_Unregistered))
+                       {
+                       // only deliver status if both v4 and v6 fail
+                       rr->RecordContext = (void *)hi->StatusContext;
+                       if (hi->StatusCallback)
+                               hi->StatusCallback(m, rr, result); // client may NOT make API calls here
+                       rr->RecordContext = (void *)hi;
+                       }
                return;
                }
-
        // register any pending services that require a target
        UpdateSRVRecords(m);
        
        // Deliver success to client
        if (!hi) { LogMsg("HostnameCallback invoked with orphaned address record"); return; }
-       LogMsg("Registered hostname %##s IP %d.%d.%d.%d", rr->resrec.name->c, ip[0], ip[1], ip[2], ip[3]);
+       if (rr->resrec.rrtype == kDNSType_A)
+               LogMsg("Registered hostname %##s IP %.4a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv4);
+       else
+               LogMsg("Registered hostname %##s IP %.16a", rr->resrec.name->c, &rr->resrec.rdata->u.ipv6);
+
        rr->RecordContext = (void *)hi->StatusContext;
        if (hi->StatusCallback)
                hi->StatusCallback(m, rr, result); // client may NOT make API calls here
@@ -1627,14 +1687,23 @@ mDNSlocal void HostnameCallback(mDNS *const m, AuthRecord *const rr, mStatus res
 // register record or begin NAT traversal
 mDNSlocal void AdvertiseHostname(mDNS *m, uDNS_HostnameInfo *h)
        {
-       if (IsPrivateV4Addr(&m->uDNS_info.PrimaryIP))
-               StartGetPublicAddr(m, h);
-       else
-         {
-         mDNSu8 *ip = m->uDNS_info.PrimaryIP.ip.v4.b;
-         LogMsg("Advertising %##s IP %d.%d.%d.%d", h->ar->resrec.name->c, ip[0], ip[1], ip[2], ip[3]);
-         uDNS_RegisterRecord(m, h->ar);
-         }
+       uDNS_GlobalInfo *u = &m->uDNS_info;
+       
+       if (u->AdvertisedV4.ip.v4.NotAnInteger && h->arv4->uDNS_info.state == regState_Unregistered)
+               {
+               if (IsPrivateV4Addr(&u->AdvertisedV4))
+                       StartGetPublicAddr(m, h->arv4);
+               else
+                       {
+                       LogMsg("Advertising %##s IP %.4a", h->arv4->resrec.name->c, &u->AdvertisedV4.ip.v4);
+                       uDNS_RegisterRecord(m, h->arv4);
+                       }
+               }
+       if (u->AdvertisedV6.ip.v6.b[0] && h->arv6->uDNS_info.state == regState_Unregistered)
+               {
+               LogMsg("Advertising %##s IP %.16a", h->arv4->resrec.name->c, &u->AdvertisedV6.ip.v6);
+               uDNS_RegisterRecord(m, h->arv6);
+               }
        }
 
 mDNSlocal void FoundStaticHostname(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, mDNSBool AddRecord)
@@ -1651,7 +1720,8 @@ mDNSlocal void FoundStaticHostname(mDNS *const m, DNSQuestion *question, const R
                AssignDomainName(storedname, pktname);
                while (h)
                        {
-                       if (h->ar && (h->ar->uDNS_info.state == regState_FetchingZoneData || h->ar->uDNS_info.state == regState_Pending || h->ar->uDNS_info.state == regState_NATMap))
+                       if ((h->arv4 && (h->arv4->uDNS_info.state == regState_FetchingZoneData || h->arv4->uDNS_info.state == regState_Pending || h->arv4->uDNS_info.state == regState_NATMap)) ||
+                           (h->arv6 && (h->arv6->uDNS_info.state == regState_FetchingZoneData || h->arv6->uDNS_info.state == regState_Pending)))
                                {
                                // if we're in the process of registering a dynamic hostname, delay SRV update so we don't have to reregister services if the dynamic name succeeds
                                m->uDNS_info.DelaySRVUpdate = mDNStrue;
@@ -1673,7 +1743,7 @@ mDNSlocal void GetStaticHostname(mDNS *m)
        {
        char buf[MAX_ESCAPED_DOMAIN_NAME];
        DNSQuestion *q = &m->uDNS_info.ReverseMap;
-       mDNSu8 *ip = m->uDNS_info.PrimaryIP.ip.v4.b;
+       mDNSu8 *ip = m->uDNS_info.AdvertisedV4.ip.v4.b;
        mStatus err;
        
        if (m->uDNS_info.ReverseMapActive)
@@ -1683,7 +1753,7 @@ mDNSlocal void GetStaticHostname(mDNS *m)
                }
 
        m->uDNS_info.StaticHostname.c[0] = 0;
-       if (!m->uDNS_info.PrimaryIP.ip.v4.NotAnInteger) return;
+       if (!m->uDNS_info.AdvertisedV4.ip.v4.NotAnInteger) return;
        ubzero(q, sizeof(*q));
        mDNS_snprintf(buf, MAX_ESCAPED_DOMAIN_NAME, "%d.%d.%d.%d.in-addr.arpa.", ip[3], ip[2], ip[1], ip[0]);
     if (!MakeDomainNameFromDNSNameString(&q->qname, buf)) { LogMsg("Error: GetStaticHostname - bad name %s", buf); return; }
@@ -1703,6 +1773,42 @@ mDNSlocal void GetStaticHostname(mDNS *m)
        else m->uDNS_info.ReverseMapActive = mDNStrue;
        }
 
+mDNSlocal void AssignHostnameInfoAuthRecord(mDNS *m, uDNS_HostnameInfo *hi, int type)
+       {
+       AuthRecord **dst = (type == mDNSAddrType_IPv4 ? &hi->arv4 : &hi->arv6);
+       AuthRecord *ar =  umalloc(sizeof(*ar));
+       uDNS_GlobalInfo *u = &m->uDNS_info;
+       
+       if (type != mDNSAddrType_IPv4 && type != mDNSAddrType_IPv6) { LogMsg("ERROR: AssignHostnameInfoAuthRecord - bad type %d", type); return; }
+       if (!ar) { LogMsg("ERROR: AssignHostnameInfoAuthRecord - malloc"); return; }
+       
+       mDNS_SetupResourceRecord(ar, mDNSNULL, 0, type == mDNSAddrType_IPv4 ? kDNSType_A : kDNSType_AAAA,  1, kDNSRecordTypeKnownUnique, HostnameCallback, hi);
+       AssignDomainName(ar->resrec.name, &hi->fqdn);
+
+       // only set RData if we have a valid IP
+       if (type == mDNSAddrType_IPv4 && u->AdvertisedV4.ip.v4.NotAnInteger)
+               {
+               if (u->MappedV4.ip.v4.NotAnInteger) ar->resrec.rdata->u.ipv4 = u->MappedV4.ip.v4;
+               else                                ar->resrec.rdata->u.ipv4 = u->AdvertisedV4.ip.v4;
+               }
+       else if (type == mDNSAddrType_IPv6 && u->AdvertisedV6.ip.v6.b[0])
+               {
+               ar->resrec.rdata->u.ipv6 = u->AdvertisedV6.ip.v6;
+               }
+
+       ar->uDNS_info.state = regState_Unregistered;
+
+       if (*dst)
+               {
+               LogMsg("ERROR: AssignHostnameInfoAuthRecord - overwriting %s AuthRec", type == mDNSAddrType_IPv4 ? "IPv4" : "IPv6");
+               unlinkAR(&u->RecordRegistrations, *dst);
+               (*dst)->RecordContext = mDNSNULL;  // defensively clear backpointer to aviod doubly-referenced context
+               }
+
+       *dst = ar;
+       }
+
+
 // Deregister hostnames and  register new names for each host domain with the current global
 // values for the hostlabel and primary IP address
 mDNSlocal void UpdateHostnameRegistrations(mDNS *m)
@@ -1712,18 +1818,30 @@ mDNSlocal void UpdateHostnameRegistrations(mDNS *m)
 
        for (i = u->Hostnames; i; i = i->next)
                {
-               // unlink and clear uDNS state (old registrations just get overwritten)
-               if (i->ar->uDNS_info.state != regState_Unregistered) unlinkAR(&u->RecordRegistrations, i->ar);
-               ubzero(&i->ar->uDNS_info, sizeof(i->ar->uDNS_info));
+               if (i->arv4 && i->arv4->uDNS_info.state != regState_Unregistered &&
+                       i->arv4->resrec.rdata->u.ipv4.NotAnInteger != u->AdvertisedV4.ip.v4.NotAnInteger &&
+                       i->arv4->resrec.rdata->u.ipv4.NotAnInteger !=u->MappedV4.ip.v4.NotAnInteger)
+                       {
+                       uDNS_DeregisterRecord(m, i->arv4);
+                       i->arv4 = mDNSNULL;
+                       }
+               if (i->arv6 && !mDNSPlatformMemSame(i->arv6->resrec.rdata->u.ipv6.b, u->AdvertisedV6.ip.v6.b, 16) && i->arv6->uDNS_info.state != regState_Unregistered)
+                       {
+                       uDNS_DeregisterRecord(m, i->arv6);
+                       i->arv6 = mDNSNULL;
+                       }
+               
+               if (!i->arv4 && u->AdvertisedV4.ip.v4.NotAnInteger)                    AssignHostnameInfoAuthRecord(m, i, mDNSAddrType_IPv4);
+               else if (i->arv4 && i->arv4->uDNS_info.state == regState_Unregistered) i->arv4->resrec.rdata->u.ipv4 = u->AdvertisedV4.ip.v4;  // simply overwrite unregistered
+               if (!i->arv6 && u->AdvertisedV6.ip.v6.b[0])                            AssignHostnameInfoAuthRecord(m, i, mDNSAddrType_IPv6);
+               else if (i->arv6 &&i->arv6->uDNS_info.state == regState_Unregistered)  i->arv6->resrec.rdata->u.ipv6 = u->AdvertisedV6.ip.v6;
 
-               // set rdata and register
-               i->ar->resrec.rdata->u.ipv4 = u->PrimaryIP.ip.v4;
-               AdvertiseHostname(m, i);                
+               AdvertiseHostname(m, i);
                }
        }
 
 mDNSexport void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext)
-       {
+   {
        uDNS_GlobalInfo *u = &m->uDNS_info;
        uDNS_HostnameInfo *ptr, *new;
 
@@ -1732,28 +1850,28 @@ mDNSexport void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSReco
        // check if domain already registered
        for (ptr = u->Hostnames; ptr; ptr = ptr->next)
                {
-               if (SameDomainName(fqdn, ptr->ar->resrec.name))
+               if (SameDomainName(fqdn, &ptr->fqdn))
                        { LogMsg("Host Domain %##s already in list", fqdn->c); goto exit; }
                }
 
        // allocate and format new address record
        new = umalloc(sizeof(*new));
-       if (new) new->ar = umalloc(sizeof(AuthRecord));
-       if (!new || !new->ar) { LogMsg("ERROR: mDNS_AddDynDNSHostname - malloc"); goto exit; }
+       if (!new) { LogMsg("ERROR: mDNS_AddDynDNSHostname - malloc"); goto exit; }
+       ubzero(new, sizeof(*new));
+    new->next = u->Hostnames;
+       u->Hostnames = new;
+       
+       AssignDomainName(&new->fqdn, fqdn);
        new->StatusCallback = StatusCallback;
        new->StatusContext = StatusContext;
-       mDNS_SetupResourceRecord(new->ar, mDNSNULL, 0, kDNSType_A,  1, kDNSRecordTypeKnownUnique, HostnameCallback, new);
-       AppendDomainName(new->ar->resrec.name, fqdn);
-       new->next = u->Hostnames;
-       u->Hostnames = new;
-       if (u->PrimaryIP.ip.v4.NotAnInteger)
-               {
-               // only set RData if we have a valid IP
-               if (u->MappedPrimaryIP.ip.v4.NotAnInteger) new->ar->resrec.rdata->u.ipv4 = u->MappedPrimaryIP.ip.v4;  //!!!KRS implement code that caches this
-               else                                       new->ar->resrec.rdata->u.ipv4 = u->PrimaryIP.ip.v4;
-               AdvertiseHostname(m, new);
-               }
-       else new->ar->uDNS_info.state = regState_Unregistered;
+
+       if (u->AdvertisedV4.ip.v4.NotAnInteger) AssignHostnameInfoAuthRecord(m, new, mDNSAddrType_IPv4);
+       else new->arv4 = mDNSNULL;
+       if (u->AdvertisedV6.ip.v6.b[0])         AssignHostnameInfoAuthRecord(m, new, mDNSAddrType_IPv6);
+       else new->arv6 = mDNSNULL;
+
+        if (u->AdvertisedV6.ip.v6.b[0] || u->AdvertisedV4.ip.v4.NotAnInteger) AdvertiseHostname(m, new);
+       
 exit:
        mDNS_Unlock(m);
        }
@@ -1765,46 +1883,61 @@ mDNSexport void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn)
 
        mDNS_Lock(m);
 
-       while (*ptr && !SameDomainName(fqdn, (*ptr)->ar->resrec.name)) ptr = &(*ptr)->next;
+       while (*ptr && !SameDomainName(fqdn, &(*ptr)->fqdn)) ptr = &(*ptr)->next;
        if (!*ptr) LogMsg("mDNS_RemoveDynDNSHostName: no such domainname %##s", fqdn->c);
        else
                {
                uDNS_HostnameInfo *hi = *ptr;
                *ptr = (*ptr)->next; // unlink
-               hi->ar->RecordContext = mDNSNULL; // about to free wrapper struct
-               if (hi->ar->uDNS_info.state != regState_Unregistered) uDNS_DeregisterRecord(m, hi->ar);
-               else { ufree(hi->ar); hi->ar = mDNSNULL; }
+               if (hi->arv4)
+                       {
+                       hi->arv4->RecordContext = mDNSNULL; // about to free wrapper struct
+                       if (hi->arv4->uDNS_info.state != regState_Unregistered) uDNS_DeregisterRecord(m, hi->arv4);
+                       else { ufree(hi->arv4); hi->arv4 = mDNSNULL; }
+                       }
+               if (hi->arv6)
+                       {
+                       hi->arv6->RecordContext = mDNSNULL; // about to free wrapper struct
+                       if (hi->arv6->uDNS_info.state != regState_Unregistered) uDNS_DeregisterRecord(m, hi->arv6);
+                       else { ufree(hi->arv6); hi->arv6 = mDNSNULL; }
+                       }
                ufree(hi);
                }
        UpdateSRVRecords(m);
        mDNS_Unlock(m);
        }
 
-mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *addr, const mDNSAddr *router)
+mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router)
        {
        uDNS_GlobalInfo *u = &m->uDNS_info;
-       mDNSBool AddrChanged, RouterChanged;
+       mDNSBool v4Changed, v6Changed, RouterChanged;
    
-       if (addr && addr->type !=mDNSAddrType_IPv4) { LogMsg("mDNS_SetPrimaryInterfaceInfo passed non-V4 address.  Discarding."); return; }
-       if (router && router->type !=mDNSAddrType_IPv4) { LogMsg("mDNS_SetPrimaryInterfaceInfo passed non-V4 address.  Discarding."); return; }
+       if (v4addr && v4addr->type != mDNSAddrType_IPv4) { LogMsg("mDNS_SetPrimaryInterfaceInfo V4 address - incorrect type.  Discarding."); return; }
+       if (v6addr && v6addr->type != mDNSAddrType_IPv6) { LogMsg("mDNS_SetPrimaryInterfaceInfo V6 address - incorrect type.  Discarding."); return; }
+       if (router && router->type != mDNSAddrType_IPv4) { LogMsg("mDNS_SetPrimaryInterfaceInfo passed non-V4 router.  Discarding."); return; }
+
        mDNS_Lock(m);
 
-       AddrChanged   = ((addr   ? addr  ->ip.v4.NotAnInteger : 0) != u->PrimaryIP.ip.v4.NotAnInteger);
-       RouterChanged = ((router ? router->ip.v4.NotAnInteger : 0) != u->Router   .ip.v4.NotAnInteger);
+       v4Changed   = (v4addr ? v4addr->ip.v4.NotAnInteger : 0) != u->AdvertisedV4.ip.v4.NotAnInteger;
+       v6Changed   = v6addr ? !mDNSPlatformMemSame(v6addr, &u->AdvertisedV6, sizeof(*v6addr)) : (u->AdvertisedV6.ip.v6.b[0] != 0);
+       RouterChanged = (router ? router->ip.v4.NotAnInteger : 0) != u->Router.ip.v4.NotAnInteger;
        
 #if MDNS_DEBUGMSGS
-       if (addr && (AddrChanged || RouterChanged))
+       if (v4addr && (v4Changed || RouterChanged))
                LogMsg("mDNS_SetPrimaryInterfaceInfo: address changed from %d.%d.%d.%d to %d.%d.%d.%d:%d",
-                          u->PrimaryIP.ip.v4.b[0], u->PrimaryIP.ip.v4.b[1], u->PrimaryIP.ip.v4.b[2], u->PrimaryIP.ip.v4.b[3],
-                          addr->ip.v4.b[0], addr->ip.v4.b[1], addr->ip.v4.b[2], addr->ip.v4.b[3], mDNSVal16(m->UnicastPort4));
+                          u->AdvertisedV4.ip.v4.b[0], u->AdvertisedV4.ip.v4.b[1], u->AdvertisedV4.ip.v4.b[2], u->AdvertisedV4.ip.v4.b[3],
+                          v4addr->ip.v4.b[0], v4addr->ip.v4.b[1], v4addr->ip.v4.b[2], v4addr->ip.v4.b[3]);
 #endif // MDNS_DEBUGMSGS
-                                                                                       
-       if (addr)   u->PrimaryIP = *addr;
-       if (router) u->Router = *router;
-       else        u->Router.ip.v4.NotAnInteger = 0; // setting router to zero indicates that nat mappings must be reestablished when router is reset
+
+       if ((v4Changed || RouterChanged) && u->MappedV4.ip.v4.NotAnInteger) u->MappedV4.ip.v4.NotAnInteger = 0;
+       if (v4addr) u->AdvertisedV4 = *v4addr;  else u->AdvertisedV4.ip.v4.NotAnInteger = 0;
+       if (v6addr) u->AdvertisedV6 = *v6addr;  else ubzero(u->AdvertisedV6.ip.v6.b, 16);
+       if (router) u->Router       = *router;  else u->Router.ip.v4.NotAnInteger = 0;
+       // setting router to zero indicates that nat mappings must be reestablished when router is reset
        
-       if ((AddrChanged || RouterChanged ) && (addr && router))
+       if ((v4Changed || RouterChanged || v6Changed) && (v4addr && router))
                {
+               // don't update these unless we've got V4
                UpdateHostnameRegistrations(m);
                UpdateSRVRecords(m);
                GetStaticHostname(m);  // look up reverse map record to find any static hostnames for our IP address
@@ -2031,8 +2164,12 @@ mDNSlocal void pktResponseHndlr(mDNS * const m, DNSMessage *msg, const  mDNSu8 *
                if (llq && llqInfo->deriveRemovesOnResume) llqInfo->deriveRemovesOnResume = mDNSfalse;
                }
 
-       // our interval may be set lower to recover from failures - now that we have an answer, fully back off retry
-       if (question->ThisQInterval < MAX_UCAST_POLL_INTERVAL) question->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
+       // Our interval may be set lower to recover from failures -- now that we have an answer, fully back off retry.
+       // If the server advertised an LLQ-specific port number then that implies that this zone
+       // *wants* to support LLQs, so if the setup fails (e.g. because we are behind a NAT)
+       // then we use a slightly faster polling rate to give slightly better user experience.
+       if (llq && llqInfo->state == LLQ_Poll && llqInfo->servPort.NotAnInteger) question->ThisQInterval = LLQ_POLL_INTERVAL;
+       else if (question->ThisQInterval < MAX_UCAST_POLL_INTERVAL) question->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
        return;
 
        pkt_error:
@@ -2150,12 +2287,13 @@ mDNSlocal mStatus checkUpdateResult(domainname *displayname, mDNSu8 rcode, mDNS
        }
 
 mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mStatus err)
-       {       
-       mDNSBool InvokeCallback = mDNSfalse;    
+       {
+       mDNSBool InvokeCallback = mDNSfalse;
        uDNS_RegInfo *info = &srs->uDNS_info;
        NATTraversalInfo *nat = srs->uDNS_info.NATinfo;
        ExtraResourceRecord **e = &srs->Extras;
-       
+       AuthRecord *txt = &srs->RR_TXT;
+       uDNS_RegInfo *txtInfo = &txt->uDNS_info;
        switch (info->state)
                {
                case regState_Pending:
@@ -2209,7 +2347,7 @@ mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mS
                        InvokeCallback = mDNStrue;
                        if (nat)
                                {
-                               if (nat->state == NATState_Deleted) { FreeNATInfo(m, nat); info->NATinfo = mDNSNULL; } // deletion copmleted
+                               if (nat->state == NATState_Deleted) { info->NATinfo = mDNSNULL; FreeNATInfo(m, nat); } // deletion copmleted
                                else nat->reg.ServiceRegistration = mDNSNULL;  // allow mapping deletion to continue
                                }
                        info->state = regState_Unregistered;
@@ -2231,10 +2369,21 @@ mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mS
                                return;
                                }
                case regState_UpdatePending:
-                       // mDNS clients don't expect asyncronous UpdateRecord errors, so we just log (rare) failures
-                       if (err) LogMsg("hndlServiceUpdateReply: error updating TXT record for service %##s", srs->RR_SRV.resrec.name->c);
-                       info->state = regState_Registered;
-                       SwapRData(m, &srs->RR_TXT, mDNStrue);  // deallocate old rdata
+                       if (err)
+                               {
+                               LogMsg("hndlServiceUpdateReply: error updating TXT record for service %##s", srs->RR_SRV.resrec.name->c);
+                               info->state = regState_Unregistered;
+                               InvokeCallback = mDNStrue;
+                               }
+                       else
+                               {
+                               info->state = regState_Registered;
+                               // deallocate old RData
+                               if (txtInfo->UpdateRDCallback) txtInfo->UpdateRDCallback(m, txt, txtInfo->OrigRData);
+                               SetNewRData(&txt->resrec, txtInfo->InFlightRData, txtInfo->InFlightRDLen);
+                               txtInfo->OrigRData = mDNSNULL;
+                               txtInfo->InFlightRData = mDNSNULL;
+                               }
                        break;
                case regState_FetchingZoneData:
                case regState_Registered:
@@ -2256,7 +2405,7 @@ mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mS
                        info->ClientCallbackDeferred = mDNStrue;
                        info->DeferredStatus = err;
                        }
-               info->SRVChanged = mDNSfalse;           
+               info->SRVChanged = mDNSfalse;
                UpdateSRV(m, srs);
                return;
                }
@@ -2287,8 +2436,9 @@ mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mS
                else e = &(*e)->next;
                }
 
+       srs->RR_SRV.ThisAPInterval = INIT_UCAST_POLL_INTERVAL - 1;  // reset retry delay for future refreshes, dereg, etc.
        if (info->state == regState_Unregistered) unlinkSRS(m, srs);
-       else if (srs->RR_TXT.uDNS_info.UpdateQueued && !err)
+       else if (txtInfo->QueuedRData && info->state == regState_Registered)
                {
                if (InvokeCallback)
                        {
@@ -2296,12 +2446,15 @@ mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mS
                        info->ClientCallbackDeferred = mDNStrue;
                        info->DeferredStatus = err;
                        }
-               srs->RR_TXT.uDNS_info.UpdateQueued = mDNSfalse;
                info->state = regState_UpdatePending;
+               txtInfo->InFlightRData = txtInfo->QueuedRData;
+               txtInfo->InFlightRDLen = txtInfo->QueuedRDLen;
+               info->OrigRData = txt->resrec.rdata;
+               info->OrigRDLen = txt->resrec.rdlength;
+               txtInfo->QueuedRData = mDNSNULL;
                SendServiceRegistration(m, srs);
                return;
                }
-       else srs->RR_SRV.ThisAPInterval = INIT_UCAST_POLL_INTERVAL - 1;  // reset retry delay for future refreshes, dereg, etc.
        
        m->mDNS_reentrancy++; // Increment to allow client to legally make mDNS API calls from the callback
        if (InvokeCallback) srs->ServiceCallback(m, srs, err);
@@ -2316,104 +2469,93 @@ mDNSlocal void hndlServiceUpdateReply(mDNS * const m, ServiceRecordSet *srs,  mS
 
 mDNSlocal void hndlRecordUpdateReply(mDNS *m, AuthRecord *rr, mStatus err)
        {
-       uDNS_GlobalInfo *u = &m->uDNS_info;
+       uDNS_RegInfo *info = &rr->uDNS_info;
+       mDNSBool InvokeCallback = mDNStrue;
        
-       if (rr->uDNS_info.state == regState_UpdatePending)
+       if (info->state == regState_UpdatePending)
                {
                if (err)
                        {
                        LogMsg("Update record failed for %##s (err %d)", rr->resrec.name->c, err);
-                       rr->uDNS_info.state = regState_Unregistered;
+                       info->state = regState_Unregistered;
                        }
                else
                        {
                        debugf("Update record %##s - success", rr->resrec.name->c);
-                       rr->uDNS_info.state = regState_Registered;
-                       SwapRData(m, rr, mDNStrue);
+                       info->state = regState_Registered;
+                       // deallocate old RData
+                       if (info->UpdateRDCallback) info->UpdateRDCallback(m, rr, info->OrigRData);
+                       SetNewRData(&rr->resrec, info->InFlightRData, info->InFlightRDLen);
+                       info->OrigRData = mDNSNULL;
+                       info->InFlightRData = mDNSNULL;
                        }
-               m->mDNS_reentrancy++; // Increment to allow client to legally make mDNS API calls from the callback
-               if (rr->RecordCallback) rr->RecordCallback(m, rr, err);
-               m->mDNS_reentrancy--; // Decrement to block mDNS API calls again
-               return;
                }
 
-       if (rr->uDNS_info.state == regState_DeregPending)
+       if (info->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",
                                                rr->resrec.name->c, rr->resrec.rrtype, err);
                err = mStatus_MemFree;
-               if (unlinkAR(&m->uDNS_info.RecordRegistrations, rr))
-                       LogMsg("ERROR: Could not unlink resource record following deregistration");
-               rr->uDNS_info.state = regState_Unregistered;
-               m->mDNS_reentrancy++; // Increment to allow client to legally make mDNS API calls from the callback
-               if (rr->RecordCallback) rr->RecordCallback(m, rr, err);
-               m->mDNS_reentrancy--; // Decrement to block mDNS API calls again
-               return;
+               info->state = regState_Unregistered;
                }
 
-       if (rr->uDNS_info.state == regState_DeregDeferred)
+       if (info->state == regState_DeregDeferred)
                {
                if (err)
                        {
                        LogMsg("Cancelling deferred deregistration record %##s type %d due to registration error %ld",
                                   rr->resrec.name->c, rr->resrec.rrtype, err);
-                       unlinkAR(&m->uDNS_info.RecordRegistrations, rr);
-                       rr->uDNS_info.state = regState_Unregistered;
-                       return;
+                       info->state = regState_Unregistered;
                        }
-               LogMsg("Calling deferred deregistration of record %##s type %d",
-                          rr->resrec.name->c, rr->resrec.rrtype);
-               rr->uDNS_info.state = regState_Registered;
+               debugf("Calling deferred deregistration of record %##s type %d",  rr->resrec.name->c, rr->resrec.rrtype);
+               info->state = regState_Registered;
                uDNS_DeregisterRecord(m, rr);
                return;
                }
 
-       if (rr->uDNS_info.state == regState_Pending || rr->uDNS_info.state == regState_Refresh)
+       if (info->state == regState_Pending || info->state == regState_Refresh)
                {
-               if (err)
+               if (!err)
                        {
-                       if (rr->uDNS_info.lease && err == mStatus_UnknownErr)
-                               {
-                               LogMsg("Re-trying update of record %##s without lease option", rr->resrec.name->c);
-                               rr->uDNS_info.lease = mDNSfalse;
-                               sendRecordRegistration(m, rr);
-                               return;
-                               }
-                       
-                       LogMsg("Registration of record %##s type %d failed with error %ld",
-                                  rr->resrec.name->c, rr->resrec.rrtype, err);
-                       unlinkAR(&u->RecordRegistrations, rr);
-                       rr->uDNS_info.state = regState_Unregistered;
-                       m->mDNS_reentrancy++; // Increment to allow client to legally make mDNS API calls from the callback
-                       if (rr->RecordCallback) rr->RecordCallback(m, rr, err);
-                       m->mDNS_reentrancy--; // Decrement to block mDNS API calls again
-                       return;
+                       info->state = regState_Registered;
+                       if (info->state == regState_Refresh) InvokeCallback = mDNSfalse;
                        }
                else
                        {
-                       if (rr->uDNS_info.UpdateQueued)
+                       if (info->lease && err == mStatus_UnknownErr)
                                {
-                               debugf("%##s: sending queued update", rr->resrec.name->c);
-                               rr->uDNS_info.state = regState_Registered;
-                               SendRecordUpdate(m ,rr, &rr->uDNS_info);
+                               LogMsg("Re-trying update of record %##s without lease option", rr->resrec.name->c);
+                               info->lease = mDNSfalse;
+                               sendRecordRegistration(m, rr);
                                return;
                                }
-                       if (rr->uDNS_info.state == regState_Refresh)
-                               rr->uDNS_info.state = regState_Registered;
-                       else
-                               {
-                               rr->uDNS_info.state = regState_Registered;
-                               m->mDNS_reentrancy++; // Increment to allow client to legally make mDNS API calls from the callback
-                               if (rr->RecordCallback) rr->RecordCallback(m, rr, err);
-                               m->mDNS_reentrancy--; // Decrement to block mDNS API calls again
-                               }
-                       return;
+                       LogMsg("Registration of record %##s type %d failed with error %ld", rr->resrec.name->c, rr->resrec.rrtype, err);
+                       info->state = regState_Unregistered;
                        }
                }
        
-       LogMsg("Received unexpected response for record %##s type %d, in state %d, with response error %ld",
-                  rr->resrec.name->c, rr->resrec.rrtype, rr->uDNS_info.state, err);
+       if (info->state == regState_Unregistered) unlinkAR(&m->uDNS_info.RecordRegistrations, rr);
+       else rr->ThisAPInterval = INIT_UCAST_POLL_INTERVAL - 1;  // reset retry delay for future refreshes, dereg, etc.
+
+       if (info->QueuedRData && info->state == regState_Registered)
+               {
+               info->state = regState_UpdatePending;
+               info->InFlightRData = info->QueuedRData;
+               info->InFlightRDLen = info->QueuedRDLen;
+               info->OrigRData = rr->resrec.rdata;
+               info->OrigRDLen = rr->resrec.rdlength;
+               info->QueuedRData = mDNSNULL;
+               sendRecordRegistration(m, rr);
+               return;
+               }
+
+       if (InvokeCallback)
+               {
+               m->mDNS_reentrancy++; // Increment to allow client to legally make mDNS API calls from the callback
+               if (rr->RecordCallback) rr->RecordCallback(m, rr, err);
+               m->mDNS_reentrancy--; // Decrement to block mDNS API calls again
+               }
        }
 
 
@@ -2471,7 +2613,7 @@ mDNSexport void uDNS_ReceiveNATMap(mDNS *m, mDNSu8 *pkt, mDNSu16 len)
                if ((ptr->state == NATState_Request || ptr->state == NATState_Refresh) && (ptr->op | NATMAP_RESPONSE_MASK) == op)
                        if (ptr->ReceiveResponse(ptr, m, pkt, len)) break;  // note callback may invalidate ptr if it return value is non-zero
                ptr = ptr->next;
-               }   
+               }
        }
 
 mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
@@ -2734,7 +2876,7 @@ mDNSlocal mDNSBool recvLLQEvent(mDNS *m, DNSQuestion *q, DNSMessage *msg, const
        if (!getLLQAtIndex(m, msg, end, &opt, 0))  { debugf("Pkt does not contain LLQ Opt");                                   return mDNSfalse; }
        if (!q->uDNS_info.llq) { LogMsg("Error: recvLLQEvent - question object does not contain LLQ metadata");                return mDNSfalse; }
        if (!sameID(opt.id, q->uDNS_info.llq->id)) {                                                                           return mDNSfalse; }
-       if (opt.llqOp != kLLQOp_Event) { if (!q->uDNS_info.llq->ntries) LogMsg("recvLLQEvent - Bad LLQ Opcode %d", opt.llqOp); return mDNSfalse; }              
+       if (opt.llqOp != kLLQOp_Event) { if (!q->uDNS_info.llq->ntries) LogMsg("recvLLQEvent - Bad LLQ Opcode %d", opt.llqOp); return mDNSfalse; }
 
     // invoke response handler
        m->uDNS_info.CurrentQuery = q;
@@ -2743,8 +2885,8 @@ mDNSlocal mDNSBool recvLLQEvent(mDNS *m, DNSQuestion *q, DNSMessage *msg, const
        
     //  format and send ack
        InitializeDNSMessage(&ack.h, msg->h.id, ResponseFlags);
-       ackEnd = putQuestion(&ack, ack.data, ack.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
-       if (!ackEnd) { LogMsg("ERROR: recvLLQEvent - putQuestion");  return mDNSfalse; }
+       ackEnd = putLLQ(&ack, ack.data, mDNSNULL, &opt, mDNSfalse);
+       if (!ackEnd) { LogMsg("ERROR: recvLLQEvent - putLLQ");  return mDNSfalse; }
        err = mDNSSendDNSMessage(m, &ack, ackEnd, mDNSInterface_Any, srcaddr, srcport, -1, mDNSNULL);
        if (err) debugf("ERROR: recvLLQEvent - mDNSSendDNSMessage returned %ld", err);
        return mDNStrue;
@@ -2916,7 +3058,7 @@ mDNSlocal void startLLQHandshake(mDNS *m, LLQ_Info *info, mDNSBool defer)
        mDNSs32 timenow = mDNSPlatformTimeNow(m);
        uDNS_GlobalInfo *u = &m->uDNS_info;
        
-       if (IsPrivateV4Addr(&u->PrimaryIP))
+       if (IsPrivateV4Addr(&u->AdvertisedV4))
                {
                if (!u->LLQNatInfo)
                        {
@@ -3006,8 +3148,8 @@ mDNSlocal void startLLQHandshakeCallback(mStatus err, mDNS *const m, void *llqIn
        zoneInfo = &result->zoneData;
 
        if (!zoneInfo->llqPort.NotAnInteger)
-               { debugf("LLQ port lookup failed - reverting to polling"); goto poll; }
-               
+               { debugf("LLQ port lookup failed - reverting to polling"); info->servPort.NotAnInteger = 0; goto poll; }
+       
     // cache necessary zone data
        info->servAddr.type = zoneInfo->primaryAddr.type;
        info->servAddr.ip.v4.NotAnInteger = zoneInfo->primaryAddr.ip.v4.NotAnInteger;
@@ -3229,7 +3371,7 @@ mDNSlocal mStatus startQuery(mDNS *const m, DNSQuestion *const question, mDNSBoo
                if (err) { debugf("ERROR: startQuery - %ld (keeping question in list for retransmission", err); }
                if (err == mStatus_TransientErr) err = mStatus_NoError;  // don't return transient errors to caller
                }
-       return err;  
+       return err;
        }
        
 mDNSexport mStatus uDNS_StartQuery(mDNS *const m, DNSQuestion *const question)
@@ -3702,7 +3844,7 @@ mDNSlocal smAction hndlLookupPorts(DNSMessage *msg, const mDNSu8 *end, ntaContex
 typedef struct
        {
     DNSQuestion  *question;
-    DNSMessage reply;
+    DNSMessage *reply;
     mDNSu16  replylen;
     int nread;
     mDNS *m;
@@ -3745,14 +3887,18 @@ mDNSlocal void conQueryCallback(int sd, void *context, mDNSBool ConnectionEstabl
                                goto error;
                                }
                        info->replylen = (mDNSu16)((mDNSu16)lenbuf[0] << 8 | lenbuf[1]);
+                       if (info->replylen < sizeof(DNSMessageHeader))
+                               { LogMsg("ERROR: conQueryCallback - length too short (%d bytes)", info->replylen);  goto error; }
+                       info->reply = umalloc(info->replylen);
+                       if (!info->reply) { LogMsg("ERROR: conQueryCallback - malloc failed"); goto error; }
                        }
-               n = mDNSPlatformReadTCP(sd, ((char *)&info->reply) + info->nread, info->replylen - info->nread);
+               n = mDNSPlatformReadTCP(sd, ((char *)info->reply) + info->nread, info->replylen - info->nread);
                if (n < 0) { LogMsg("ERROR: conQueryCallback - read returned %d", n); goto error; }
                info->nread += n;
                if (info->nread == info->replylen)
                        {
                        // Finished reading message; convert the integer parts which are in IETF byte-order (MSB first, LSB second)
-                       DNSMessage *msg = &info->reply;
+                       DNSMessage *msg = info->reply;
                        mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
                        msg->h.numQuestions   = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
                        msg->h.numAnswers     = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]);
@@ -3760,6 +3906,7 @@ mDNSlocal void conQueryCallback(int sd, void *context, mDNSBool ConnectionEstabl
                        msg->h.numAdditionals = (mDNSu16)((mDNSu16)ptr[6] << 8 | ptr[7]);
                        uDNS_ReceiveMsg(m, msg, (mDNSu8 *)msg + info->replylen, mDNSNULL, zeroIPPort, mDNSNULL, zeroIPPort, question->InterfaceID);
                        mDNSPlatformTCPCloseConnection(sd);
+                       ufree(info->reply);
                        ufree(info);
                        }
                }
@@ -3769,6 +3916,7 @@ mDNSlocal void conQueryCallback(int sd, void *context, mDNSBool ConnectionEstabl
 
        error:
        mDNSPlatformTCPCloseConnection(sd);
+       if (info->reply) ufree(info->reply);
        ufree(info);
        mDNS_Unlock(m);
        }
@@ -3806,8 +3954,6 @@ mDNSlocal void hndlTruncatedAnswer(DNSQuestion *question, const  mDNSAddr *src,
 #pragma mark - Dynamic Updates
 #endif
 
-
-
 mDNSlocal void sendRecordRegistration(mDNS *const m, AuthRecord *rr)
        {
        DNSMessage msg;
@@ -3825,23 +3971,37 @@ mDNSlocal void sendRecordRegistration(mDNS *const m, AuthRecord *rr)
     // set zone
        ptr = putZone(&msg, ptr, end, &regInfo->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
        if (!ptr) goto error;
-       
-       if (rr->resrec.RecordType == kDNSRecordTypeKnownUnique)
-         {
-         // KnownUnique: Delete any previous value
-         ptr = putDeleteRRSet(&msg, ptr, rr->resrec.name, rr->resrec.rrtype);
-         if (!ptr) goto error;
-         }
 
-       else if (rr->resrec.RecordType != kDNSRecordTypeShared)
+       if (regInfo->state == regState_UpdatePending)
                {
-               ptr = putPrereqNameNotInUse(rr->resrec.name, &msg, ptr, end);
-               if (!ptr) goto error;
+               // delete old RData
+               SetNewRData(&rr->resrec, regInfo->OrigRData, regInfo->OrigRDLen);
+               if (!(ptr = putDeletionRecord(&msg, ptr, &rr->resrec))) goto error;  // delete old rdata
+               
+               // add new RData
+               SetNewRData(&rr->resrec, regInfo->InFlightRData, regInfo->InFlightRDLen);
+               if (!(ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl))) goto error;
                }
 
-       ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl);
-       if (!ptr) goto error;
-
+       else
+               {
+               if (rr->resrec.RecordType == kDNSRecordTypeKnownUnique)
+                       {
+                       // KnownUnique: Delete any previous value
+                       ptr = putDeleteRRSet(&msg, ptr, rr->resrec.name, rr->resrec.rrtype);
+                       if (!ptr) goto error;
+                       }
+               
+               else if (rr->resrec.RecordType != kDNSRecordTypeShared)
+                       {
+                       ptr = putPrereqNameNotInUse(rr->resrec.name, &msg, ptr, end);
+                       if (!ptr) goto error;
+                       }
+               
+               ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl);
+               if (!ptr) goto error;
+               }
+       
        if (rr->uDNS_info.lease)
                { ptr = putUpdateLease(&msg, ptr, DEFAULT_UPDATE_LEASE); if (!ptr) goto error; }
 
@@ -3850,7 +4010,9 @@ mDNSlocal void sendRecordRegistration(mDNS *const m, AuthRecord *rr)
    
        SetRecordRetry(m, rr, err);
        
-       if (regInfo->state != regState_Refresh && regInfo->state != regState_DeregDeferred) regInfo->state = regState_Pending;
+       if (regInfo->state != regState_Refresh && regInfo->state != regState_DeregDeferred && regInfo->state != regState_UpdatePending)
+               regInfo->state = regState_Pending;
+
        return;
 
 error:
@@ -4006,13 +4168,17 @@ mDNSlocal void SendServiceRegistration(mDNS *m, ServiceRecordSet *srs)
        for (i = 0; i < srs->NumSubTypes; i++)
                if (!(ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &srs->SubTypes[i].resrec, srs->SubTypes[i].resrec.rroriginalttl))) goto error;
        
-       if (rInfo->state == regState_UpdatePending)
+       if (rInfo->state == regState_UpdatePending) // we're updating the txt record
                {
-               // we're updating the txt record - delete old, add new
+               AuthRecord *txt = &srs->RR_TXT;
+               uDNS_RegInfo *txtInfo = &txt->uDNS_info;
+               // delete old RData
+               SetNewRData(&txt->resrec, txtInfo->OrigRData, txtInfo->OrigRDLen);
                if (!(ptr = putDeletionRecord(&msg, ptr, &srs->RR_TXT.resrec))) goto error;  // delete old rdata
-               SwapRData(m, &srs->RR_TXT, mDNSfalse); // add the new rdata
+
+               // add new RData
+               SetNewRData(&txt->resrec, txtInfo->InFlightRData, txtInfo->InFlightRDLen);
                if (!(ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &srs->RR_TXT.resrec, srs->RR_TXT.resrec.rroriginalttl))) goto error;
-               SwapRData(m, &srs->RR_TXT, mDNSfalse); // replace old rdata in case we need to retransmit
                }
        else
                if (!(ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &srs->RR_TXT.resrec, srs->RR_TXT.resrec.rroriginalttl))) goto error;
@@ -4103,7 +4269,7 @@ mDNSlocal void serviceRegistrationCallback(mStatus err, mDNS *const m, void *srs
                srs->uDNS_info.lease = mDNSfalse;
                }
 
-       if (srs->RR_SRV.resrec.rdata->u.srv.port.NotAnInteger && IsPrivateV4Addr(&m->uDNS_info.PrimaryIP))
+       if (srs->RR_SRV.resrec.rdata->u.srv.port.NotAnInteger && IsPrivateV4Addr(&m->uDNS_info.AdvertisedV4))
                { srs->uDNS_info.state = regState_NATMap; StartNATPortMap(m, srs); }
        else SendServiceRegistration(m, srs);
        return;
@@ -4206,12 +4372,12 @@ mDNSexport mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr)
                {
                case regState_NATMap:
             // we're in the middle of a NAT traversal operation
+            rr->uDNS_info.NATinfo = mDNSNULL;
                        if (!n) LogMsg("uDNS_DeregisterRecord: no NAT info context");
                        else FreeNATInfo(m, n); // cause response to outstanding request to be ignored.
                                                // Note: normally here we're trying to determine our public address,
                                                //in which case there is not state to be torn down.  For simplicity,
                                                //we allow other operations to expire.
-            rr->uDNS_info.NATinfo = mDNSNULL;
                        rr->uDNS_info.state = regState_Unregistered;
                        break;
                case regState_ExtraQueued:
@@ -4255,9 +4421,9 @@ mDNSexport mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr)
                return mStatus_NoError;
                }
 
-       if (n) FreeNATInfo(m, n);
        rr->uDNS_info.NATinfo = mDNSNULL;
-
+       if (n) FreeNATInfo(m, n);
+       
        SendRecordDeregistration(m, rr);
        return mStatus_NoError;
        }
@@ -4288,7 +4454,7 @@ mDNSexport mStatus uDNS_RegisterService(mDNS *const m, ServiceRecordSet *srs)
                debugf("uDNS_RegisterService - no target for %##s", srs->RR_SRV.resrec.name->c);
                info->state = regState_NoTarget;
                return mStatus_NoError;
-               }  
+               }
        
        info->state = regState_FetchingZoneData;
        return startGetZoneData(srs->RR_SRV.resrec.name, m, mDNStrue, mDNSfalse, serviceRegistrationCallback, srs);
@@ -4402,53 +4568,6 @@ mDNSexport mStatus uDNS_DeregisterService(mDNS *const m, ServiceRecordSet *srs)
        return mStatus_BadReferenceErr;
        }
 
-mDNSlocal void SendRecordUpdate(mDNS *m, AuthRecord *rr, uDNS_RegInfo *info)
-       {
-       DNSMessage msg;
-       mDNSu8 *ptr = msg.data;
-       mDNSu8 *end = (mDNSu8 *)&msg + sizeof(DNSMessage);
-       uDNS_GlobalInfo *u = &m->uDNS_info;
-       mDNSOpaque16 id;
-       mStatus err = mStatus_UnknownErr;
-       
-       if (info != &rr->uDNS_info) LogMsg("ERROR: SendRecordUpdate - incorrect info struct!");
-       rr->uDNS_info.UpdateQueued = mDNSfalse;  // if this was queued, clear flag
-       id = newMessageID(u);
-       InitializeDNSMessage(&msg.h, id, UpdateReqFlags);
-       info->id.NotAnInteger = id.NotAnInteger;
-       
-    // set zone
-       ptr = putZone(&msg, ptr, end, &info->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
-       if (!ptr) goto error;
-               
-       // delete the original record
-       ptr = putDeletionRecord(&msg, ptr, &rr->resrec);
-       if (!ptr) goto error;
-
-       // change the rdata, add the new record
-       SwapRData(m, rr, mDNSfalse);
-       ptr = PutResourceRecordTTLJumbo(&msg, ptr, &msg.h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl);
-       SwapRData(m, rr, mDNSfalse);  // swap rdata back to original in case we need to retransmit
-       if (!ptr) goto error;         // (rdata gets changed permanently on success)
-
-       if (info->lease)
-               { ptr = putUpdateLease(&msg, ptr, DEFAULT_UPDATE_LEASE); if (!ptr) goto error; }
-       
-       // don't report send errors - retransmission will occurr if necessary
-       err = mDNSSendDNSMessage(m, &msg, ptr, mDNSInterface_Any, &info->ns, info->port, -1, GetAuthInfoForName(u, rr->resrec.name));
-       if (err) debugf("ERROR: sendRecordRegistration - mDNSSendDNSMessage - %ld", err);
-
-       SetRecordRetry(m, rr, err);
-       
-       rr->uDNS_info.state = regState_UpdatePending;
-       if (&rr->uDNS_info != info) info->state = regState_UpdatePending; // set parent SRS
-       return;
-
-error:
-       LogMsg("ERROR: SendRecordUpdate.  Error formatting update message.");
-       info ->state = regState_Registered;
-       }
-
 mDNSexport mStatus uDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra)
        {
        mStatus err = mStatus_UnknownErr;
@@ -4475,30 +4594,24 @@ mDNSexport mStatus uDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
 mDNSexport mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr)
        {
        uDNS_GlobalInfo *u = &m->uDNS_info;
-       ServiceRecordSet *sptr, *parent = mDNSNULL;
+       ServiceRecordSet *parent = mDNSNULL;
        AuthRecord *rptr;
-       uDNS_RegInfo *info = mDNSNULL;
+       uDNS_RegInfo *info = &rr->uDNS_info;
+       regState_t *stateptr = mDNSNULL;
        
        // find the record in registered service list
-       for (sptr = u->ServiceRegistrations; sptr; sptr = sptr->next)
-               if (&sptr->RR_TXT == rr) { info = &sptr->uDNS_info; parent = sptr; break; }
+       for (parent = u->ServiceRegistrations; parent; parent = parent->next)
+               if (&parent->RR_TXT == rr) { stateptr = &parent->uDNS_info.state; break; }
 
        if (!parent)
                {
                // record not part of a service - check individual record registrations
                for (rptr = u->RecordRegistrations; rptr; rptr = rptr->next)
-                       if (rptr == rr) { info = &rr->uDNS_info; break; }
+                       if (rptr == rr) { stateptr = &rr->uDNS_info.state; break; }
+               if (!rptr) goto unreg_error;
                }
-
-       if (!info) goto unreg_error;
-
-       // uDNS-private pointers so that mDNS.c layer doesn't nuke rdata of an in-flight update
-       rr->uDNS_info.UpdateRData = rr->NewRData;
-       rr->uDNS_info.UpdateRDLen = rr->newrdlength;
-       rr->uDNS_info.UpdateRDCallback = rr->UpdateCallback;
-       rr->NewRData = mDNSNULL;
        
-       switch(info->state)
+       switch(*stateptr)
                {
                case regState_DeregPending:
                case regState_DeregDeferred:
@@ -4510,25 +4623,38 @@ mDNSexport mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr)
                case regState_FetchingZoneData:
                case regState_NATMap:
                case regState_ExtraQueued:
+               case regState_NoTarget:
                        // change rdata directly since it hasn't been sent yet
-                       SwapRData(m, rr, mDNStrue);
+                       if (info->UpdateRDCallback) info->UpdateRDCallback(m, rr, rr->resrec.rdata);
+                       SetNewRData(&rr->resrec, rr->NewRData, rr->newrdlength);
+                       rr->NewRData = mDNSNULL;
                        return mStatus_NoError;
                        
                case regState_Pending:
                case regState_Refresh:
                case regState_UpdatePending:
-                       // registration in-flight.  mark for update after service registration completes
-                       rr->uDNS_info.UpdateQueued = mDNStrue;  // note that we mark the record's Queued flag, not its parent's
+                       // registration in-flight.  queue rdata and return
+                       if (info->QueuedRData && info->UpdateRDCallback)
+                               // if unsent rdata is already queued, free it before we replace it
+                               info->UpdateRDCallback(m, rr, info->QueuedRData);
+                       info->QueuedRData = rr->NewRData;
+                       info->QueuedRDLen = rr->newrdlength;
+                       rr->NewRData = mDNSNULL;
                        return mStatus_NoError;
                        
                case regState_Registered:
-                       if (parent) { info->state = regState_UpdatePending; SendServiceRegistration(m, parent); }
-                       else SendRecordUpdate(m, rr, info);                             
+                       info->OrigRData = rr->resrec.rdata;
+                       info->OrigRDLen = rr->resrec.rdlength;
+                       info->InFlightRData = rr->NewRData;
+                       info->InFlightRDLen = rr->newrdlength;
+                       rr->NewRData = mDNSNULL;
+                       *stateptr = regState_UpdatePending;
+                       if (parent)  SendServiceRegistration(m, parent);
+                       else sendRecordRegistration(m, rr);
                        return mStatus_NoError;
 
                case regState_NATError:
-               case regState_NoTarget:
-                       LogMsg("ERROR: uDNS_UpdateRecord called for record %##s with bad state %s", rr->resrec.name->c, rr->uDNS_info.state == regState_NoTarget ? "regState_NoTarget" : "regState_NATError");
+                       LogMsg("ERROR: uDNS_UpdateRecord called for record %##s with bad state regState_NATError", rr->resrec.name->c);
                        return mStatus_UnknownErr;  // states for service records only
                }
 
@@ -4547,15 +4673,12 @@ mDNSexport mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr)
 
 mDNSlocal mDNSs32 CheckNATMappings(mDNS *m, mDNSs32 timenow)
        {
-       NATTraversalInfo *ptr, *cur;
-       mDNSs32 nextevent;
-
-       ptr = m->uDNS_info.NATTraversals;
-       nextevent = timenow + MIN_UCAST_PERIODIC_EXEC;
+       NATTraversalInfo *ptr = m->uDNS_info.NATTraversals;
+       mDNSs32 nextevent = timenow + MIN_UCAST_PERIODIC_EXEC;
        
        while (ptr)
                {
-               cur = ptr;
+               NATTraversalInfo *cur = ptr;
                ptr = ptr->next;
                if (cur->op != NATOp_AddrRequest || cur->state != NATState_Established)  // no refresh necessary for established Add requests
                        {
@@ -4682,7 +4805,6 @@ mDNSlocal mDNSs32 CheckRecordRegistrations(mDNS *m, mDNSs32 timenow)
 #endif
                                //LogMsg("Retransmit record %##s", rr->resrec.name->c);
                                if      (rInfo->state == regState_DeregPending)   SendRecordDeregistration(m, rr);
-                               else if (rInfo->state == regState_UpdatePending)  SendRecordUpdate(m, rr, rInfo);
                                else                                              sendRecordRegistration(m, rr);
                                }
                        if (rr->LastAPTime + rr->ThisAPInterval - nextevent < 0) nextevent = rr->LastAPTime + rr->ThisAPInterval;
@@ -4715,7 +4837,7 @@ mDNSlocal mDNSs32 CheckServiceRegistrations(mDNS *m, mDNSs32 timenow)
                // and then if we tried to do srs = srs->next at the end we'd be referencing a dead object
                s = s->next;
                
-               rInfo = &srs->uDNS_info;        
+               rInfo = &srs->uDNS_info;
                if (rInfo->state == regState_Pending || rInfo->state == regState_DeregPending || rInfo->state == regState_DeregDeferred || rInfo->state == regState_Refresh  || rInfo->state == regState_UpdatePending)
                        {
                        if (srs->RR_SRV.LastAPTime + srs->RR_SRV.ThisAPInterval - timenow < 0)
@@ -4923,20 +5045,42 @@ mDNSlocal void WakeRecordRegistrations(mDNS *m)
 
 mDNSlocal void SleepServiceRegistrations(mDNS *m)
        {
-       mDNSs32 timenow = mDNSPlatformTimeNow(m);
        ServiceRecordSet *srs = m->uDNS_info.ServiceRegistrations;
        while(srs)
                {
-               if (srs->uDNS_info.state == regState_Registered ||
-                       srs->uDNS_info.state == regState_Refresh)
+               uDNS_RegInfo *info = &srs->uDNS_info;
+               NATTraversalInfo *nat = info->NATinfo;
+               
+               if (nat)
+                       {
+                       if (nat->state == NATState_Established || nat->state == NATState_Refresh || nat->state == NATState_Legacy)
+                               DeleteNATPortMapping(m, nat, srs);
+                       nat->reg.ServiceRegistration = mDNSNULL;
+                       srs->uDNS_info.NATinfo = mDNSNULL;
+                       FreeNATInfo(m, nat);
+                       }
+
+               if (info->state == regState_UpdatePending)
+                       {
+                       // act as if the update succeeded, since we're about to delete the name anyway
+                       AuthRecord *txt = &srs->RR_TXT;
+                       uDNS_RegInfo *txtInfo = &txt->uDNS_info;
+                       info->state = regState_Registered;
+                       // deallocate old RData
+                       if (txtInfo->UpdateRDCallback) txtInfo->UpdateRDCallback(m, txt, txtInfo->OrigRData);
+                       SetNewRData(&txt->resrec, txtInfo->InFlightRData, txtInfo->InFlightRDLen);
+                       txtInfo->OrigRData = mDNSNULL;
+                       txtInfo->InFlightRData = mDNSNULL;
+                       }
+
+               if (info->state == regState_Registered || info->state == regState_Refresh)
                        {
                        mDNSOpaque16 origid  = srs->uDNS_info.id;
-                       srs->uDNS_info.state = regState_DeregPending;  // state expected by SendDereg()
+                       info->state = regState_DeregPending;  // state expected by SendDereg()
                        SendServiceDeregistration(m, srs);
-                       srs->uDNS_info.id = origid;
-                       srs->uDNS_info.state = regState_Refresh;
-                       srs->RR_SRV.LastAPTime = timenow;
-                       srs->RR_SRV.ThisAPInterval = 300 * mDNSPlatformOneSecond;
+                       info->id = origid;
+                       info->state = regState_NoTarget;  // when we wake, we'll re-register (and optionally nat-map) once our address record completes
+                       srs->RR_SRV.resrec.rdata->u.srv.target.c[0] = 0;
                        }
                srs = srs->next;
                }
index 616d7122f7bd9171548ff7162261c3bb9e1ef94b..6d86705370e358c537ae86cb5b44a24f73c057bc 100755 (executable)
@@ -23,6 +23,9 @@
     Change History (most recent first):
 
 $Log: uDNS.h,v $
+Revision 1.32  2005/07/29 19:46:10  ksekar
+<rdar://problem/4191860> reduce polling period on failed LLQs to 15 minutes
+
 Revision 1.31  2005/03/31 02:19:56  cheshire
 <rdar://problem/4021486> Fix build warnings
 Reviewed by: Scott Herscher
@@ -140,6 +143,7 @@ Revision 1.1  2003/12/13 03:05:27  ksekar
 #define INIT_UCAST_POLL_INTERVAL (3 * mDNSPlatformOneSecond) // this interval is used after send failures on network transitions
                                                                 // which typically heal quickly, so we start agressively and exponentially back off
 #define MAX_UCAST_POLL_INTERVAL (60 * 60 * mDNSPlatformOneSecond)
+#define LLQ_POLL_INTERVAL       (15 * 60 * mDNSPlatformOneSecond) // Polling interval for zones w/ an advertised LLQ port (ie not static zones) if LLQ fails due to NAT, etc.
 #define RESPONSE_WINDOW (60 * mDNSPlatformOneSecond)         // require server responses within one minute of request
 #define UPDATE_PORT_NAME "_dns-update._udp."
 #define LLQ_PORT_NAME "_dns-llq._udp"
index ab3b3453539d348c0a062eaf1da99f2c6daa6eea..a518d9de105ba1b477be90789e04664bf81410ac 100644 (file)
@@ -23,9 +23,6 @@
     Change History (most recent first):
 
 $Log: mDNSLibraryResources.r,v $
-Revision 1.32  2005/05/05 00:06:58  ksekar
-Update version string to 1.0a107.1
-
 Revision 1.31  2005/03/15 02:14:14  cheshire
 mDNSResponder-107
 
@@ -137,15 +134,15 @@ like Muse Research who want to be able to use mDNS/DNS-SD from GPL-licensed code
 
 resource 'vers' (1, purgeable)
        {
-   0x01, 0x00, alpha, 107.1, verUS,
-   "1.0a107.1",
-   "Multicast DNS & DNS Service Discovery 1.0a107.1"
+   0x01, 0x00, alpha, 107, verUS,
+   "1.0a107",
+   "Multicast DNS & DNS Service Discovery 1.0a107"
        };
 
 resource 'vers' (2, purgeable)
        {
-   0x01, 0x00, alpha, 107.1, verUS,
-   "1.0a107.1",
+   0x01, 0x00, alpha, 107, verUS,
+   "1.0a107",
    "developer.apple.com/darwin/projects/bonjour/"
        };
 
index d8f0480bbe1d12643d5cd0ceb90238f7e00e6cef..500e67c143d1f0b0c2910c642c7ffcee47cc1799 100644 (file)
@@ -24,6 +24,9 @@
     Change History (most recent first):
 
 $Log: LegacyNATTraversal.c,v $
+Revision 1.12  2005/07/22 21:36:16  ksekar
+Fix GCC 4.0/Intel compiler warnings
+
 Revision 1.11  2004/12/03 03:34:20  ksekar
 <rdar://problem/3882674> LegacyNATTraversal.c leaks threads
 
@@ -1312,20 +1315,20 @@ static void *TCPProc(void *in)
                        (g_dwLocalIP >> 0) & 0xFF,
                        g_wEventPort);
 
-               n = sprintf(buf,
+               n = sprintf((char *)buf,
                        szEventMsgSubscribeFMT,
                        g_szEventURL,
                        callback, g_szRouterHostPortEvent, 1800);
 
                memset(response, 0, 2000);
                n = SendTCPMsg_saddr_parse(
-                       buf, n,
+                       (char *)buf, n,
                        response, 2000,
                        &g_saddrRouterEvent);
                if (n > 0)
                {
                        response[n] = '\0';
-                       resp = NewHTTPResponse_sz(buf, n, TRUE);
+                       resp = NewHTTPResponse_sz((char *)buf, n, TRUE);
                        if (NULL != resp)
                        {
 ////TracePrint(ELL_TRACE, "UPnP Subscribe returns %s/%d\n", resp->pszStatus, n);
@@ -1352,7 +1355,7 @@ static void *TCPProc(void *in)
        {
 //             ssize_t                         n;
                struct sockaddr_in      recvaddr;
-               int                                     recvaddrlen;
+               socklen_t                   recvaddrlen;
                fd_set                          readfds;
                struct timeval          timeout;
                int                                     sEvent;
@@ -1473,7 +1476,7 @@ static void *UDPProc(void *in)
        for (;;) {
                ssize_t                         n;
                struct sockaddr_in      recvaddr;
-               int                                     recvaddrlen;
+               socklen_t                                       recvaddrlen;
                fd_set                          readfds;
                //struct timeval                timeout;
                //int                                   i;
@@ -1513,8 +1516,8 @@ static void *UDPProc(void *in)
                        return NULL;
                }
                buf[n] = '\0';
-               if (strncmp(buf, "HTTP/1.1", 8) == 0) {
-                       PHTTPResponse pResponse = NewHTTPResponse_sz(buf, n, TRUE);
+               if (strncmp((char *)buf, "HTTP/1.1", 8) == 0) {
+                       PHTTPResponse pResponse = NewHTTPResponse_sz((char *)buf, n, TRUE);
                        PrintHTTPResponse(pResponse);
                        if (DiscoverRouter(pResponse) == 0)
                        {
@@ -1529,11 +1532,11 @@ static void *UDPProc(void *in)
                        }
                        DeleteHTTPResponse(pResponse);
                }
-               else if (strncmp(buf, "NOTIFY * HTTP/1.1", 7) == 0) {
+               else if (strncmp((char *)buf, "NOTIFY * HTTP/1.1", 7) == 0) {
                        // temporarily use this to fudge - will have the exact same
                        // parsing, only status/reason set to "*" and "HTTP/1.1".
                        // TODO: add support for HTTP requests
-                       PHTTPResponse pResponse = NewHTTPResponse_sz(buf, n, TRUE);
+                       PHTTPResponse pResponse = NewHTTPResponse_sz((char *)buf, n, TRUE);
                        if (DiscoverRouter(pResponse) == 0)
                        {
                                time_t  now = time(NULL);
@@ -2810,7 +2813,7 @@ static int GetMappingUnused(unsigned short eport, int protocol)
        char                    szPort[10];
        Property                propArgs[3];
        PHTTPResponse   resp;
-       unsigned long   ip;
+       unsigned long   ip = 0;
 
        sprintf( szPort, "%u", eport);
 
diff --git a/mDNSMacOSX/PreferencePane/BonjourPref.icns b/mDNSMacOSX/PreferencePane/BonjourPref.icns
deleted file mode 100644 (file)
index 97b560f..0000000
Binary files a/mDNSMacOSX/PreferencePane/BonjourPref.icns and /dev/null differ
diff --git a/mDNSMacOSX/PreferencePane/BonjourPref.tiff b/mDNSMacOSX/PreferencePane/BonjourPref.tiff
deleted file mode 100644 (file)
index 55cb212..0000000
Binary files a/mDNSMacOSX/PreferencePane/BonjourPref.tiff and /dev/null differ
diff --git a/mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.icns b/mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.icns
new file mode 100644 (file)
index 0000000..028a3a2
Binary files /dev/null and b/mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.icns differ
diff --git a/mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.tiff b/mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.tiff
new file mode 100644 (file)
index 0000000..985ae19
Binary files /dev/null and b/mDNSMacOSX/PreferencePane/DNSServiceDiscoveryPref.tiff differ
index de12870102e51913e7a328edece68366422654a2..779447941c2ad40e0534f25c854d9fe909f3b7ae 100644 (file)
     Change History (most recent first):
 
 $Log: daemon.c,v $
-Revision 1.257  2005/03/28 19:28:55  cheshire
-Fix minor typos in LogOperation() messages
-
-Revision 1.256  2005/03/17 22:01:22  cheshire
-Tidy up alignment of lines to make code more readable
+Revision 1.255.2.1  2005/07/22 21:45:04  ksekar
+Fix GCC 4.0/Intel compiler warnings
 
 Revision 1.255  2005/03/09 00:48:43  cheshire
 <rdar://problem/4015157> QU packets getting sent too early on wake from sleep
@@ -905,8 +902,8 @@ mDNSlocal void AbortClient(mach_port_t ClientMachPort, void *m)
                while (qptr)
                        {
                        if (m && m != x)
-                               LogMsg("%5d: DNSServiceBrowse(%##s) STOP; WARNING m %p != x %p", ClientMachPort, qptr->q.qname.c, m, x);
-                       else LogOperation("%5d: DNSServiceBrowse(%##s) STOP", ClientMachPort, qptr->q.qname.c);
+                               LogMsg("%5d: DNSServiceBrowser(%##s) STOP; WARNING m %p != x %p", ClientMachPort, qptr->q.qname.c, m, x);
+                       else LogOperation("%5d: DNSServiceBrowser(%##s) STOP", ClientMachPort, qptr->q.qname.c);
                        mDNS_StopBrowse(&mDNSStorage, &qptr->q);
                        freePtr = qptr;
                        qptr = qptr->next;
@@ -928,8 +925,8 @@ mDNSlocal void AbortClient(mach_port_t ClientMachPort, void *m)
                DNSServiceResolver *x = *l;
                *l = (*l)->next;
                if (m && m != x)
-                       LogMsg("%5d: DNSServiceResolve(%##s) STOP; WARNING m %p != x %p", ClientMachPort, x->i.name.c, m, x);
-               else LogOperation("%5d: DNSServiceResolve(%##s) STOP", ClientMachPort, x->i.name.c);
+                       LogMsg("%5d: DNSServiceResolver(%##s) STOP; WARNING m %p != x %p", ClientMachPort, x->i.name.c, m, x);
+               else LogOperation("%5d: DNSServiceResolver(%##s) STOP", ClientMachPort, x->i.name.c);
                mDNS_StopResolveService(&mDNSStorage, &x->q);
                freeL("DNSServiceResolver", x);
                return;
@@ -979,21 +976,19 @@ mDNSlocal void AbortClientWithLogMessage(mach_port_t c, char *reason, char *msg,
        while (b && b->ClientMachPort != c) b = b->next;
        while (l && l->ClientMachPort != c) l = l->next;
        while (r && r->ClientMachPort != c) r = r->next;
-
-       if      (e) LogMsg("%5d: DomainEnumeration(%##s) %s%s",                   c, e->dom.qname.c,                reason, msg);
+       if      (e)     LogMsg("%5d: DomainEnumeration(%##s) %s%s",                   c, e->dom.qname.c,            reason, msg);
        else if (b)
-                       {
-                       for (qptr = b->qlist; qptr; qptr = qptr->next)
-                               LogMsg("%5d: Browser(%##s) %s%s",                             c, qptr->q.qname.c,               reason, msg);
-                       }
-       else if (l) LogMsg("%5d: Resolver(%##s) %s%s",                            c, l->i.name.c,                   reason, msg);
+               {
+               for (qptr = b->qlist; qptr; qptr = qptr->next)
+                               LogMsg("%5d: Browser(%##s) %s%s",                             c, qptr->q.qname.c,              reason, msg);
+               }
+       else if (l)     LogMsg("%5d: Resolver(%##s) %s%s",                            c, l->i.name.c,               reason, msg);
        else if (r)
-                       {
-                       ServiceInstance *si;
-                       for (si = r->regs; si; si = si->next)
-                               LogMsg("%5d: Registration(%##s) %s%s",                        c, si->srs.RR_SRV.resrec.name->c, reason, msg);
-                       }
-       else        LogMsg("%5d: (%s) %s, but no record of client can be found!", c,                                reason, msg);
+               {
+               ServiceInstance *si;
+               for (si = r->regs; si; si = si->next) LogMsg("%5d: Registration(%##s) %s%s", c, si->srs.RR_SRV.resrec.name->c, reason, msg);
+               }
+       else            LogMsg("%5d: (%s) %s, but no record of client can be found!", c,                            reason, msg);
 
        AbortClient(c, m);
        }
@@ -1415,7 +1410,7 @@ mDNSexport kern_return_t provide_DNSServiceResolverResolve_rpc(mach_port_t unuse
        DNSServiceResolverList = x;
 
        // Do the operation
-       LogOperation("%5d: DNSServiceResolve(%##s) START", client, x->i.name.c);
+       LogOperation("%5d: DNSServiceResolver(%##s) START", client, x->i.name.c);
        err = mDNS_StartResolveService(&mDNSStorage, &x->q, &x->i, FoundInstanceInfo, x);
        if (err) { AbortClient(client, x); errormsg = "mDNS_StartResolveService"; goto fail; }
 
@@ -1893,8 +1888,8 @@ mDNSexport kern_return_t provide_DNSServiceRegistrationAddRecord_rpc(mach_port_t
        uint32_t id;
        mStatus err = mStatus_NoError;
        const char *errormsg = "Unknown";
-       if (client == (mach_port_t)-1) { err = mStatus_Invalid;         errormsg = "Client id -1 invalid"; goto fail; }
        DNSServiceRegistration *x = DNSServiceRegistrationList;
+       if (client == (mach_port_t)-1) { err = mStatus_Invalid;         errormsg = "Client id -1 invalid"; goto fail; }
        ServiceInstance *si;
        size_t size;
        (void)unusedserver;             // Unused
index 2b3e4eaf017d646ea70b961e4cb73327c9cd7c05..7537a904ba8ccfe334d890e5ec67d2f5bd7cbe31 100644 (file)
     Change History (most recent first):
 
 $Log: mDNSMacOSX.c,v $
-Revision 1.310  2005/04/07 00:49:58  cheshire
-<rdar://problem/4080074> PPP connection disables Bonjour ".local" lookups
+Revision 1.308.2.2  2005/08/05 01:12:24  ksekar
+<rdar://problem/4137930> SUTiger: Hostname registration should register IPv6 AAAA record with DNS Update
+<rdar://problem/4147774> SUTiger: Be defensive against invalid UTF-8 in dynamic host names
+<rdar://problem/3923098> SUTiger: Things are showing up with a bogus interface index
+<rdar://problem/4080074> SUTiger: PPP connection disables same-host Bonjour ".local" lookups
 
-Revision 1.309  2005/03/23 05:53:29  cheshire
-Fix %s where it should have been %##s in debugf & LogMsg calls
+
+Revision 1.308.2.1  2005/07/22 21:42:59  ksekar
+Fix GCC 4.0/Intel compiler warnings
 
 Revision 1.308  2005/03/09 00:48:44  cheshire
 <rdar://problem/4015157> QU packets getting sent too early on wake from sleep
@@ -1366,18 +1370,13 @@ mDNSlocal ssize_t myrecvfrom(const int s, void *const buffer, const size_t max,
 // On entry, context points to our CFSocketSet
 // If ss->info is NULL, we received this packet on our anonymous unicast socket
 // If ss->info is non-NULL, we received this packet on port 5353 on the indicated interface
-mDNSlocal void myCFSocketCallBack(CFSocketRef cfs, CFSocketCallBackType CallBackType, CFDataRef address, const void *data, void *context)
+mDNSlocal void myCFSocketCallBack(const CFSocketRef cfs, const CFSocketCallBackType CallBackType, const CFDataRef address, const void *const data, void *const context)
        {
-       mDNSAddr senderAddr, destAddr;
-       mDNSIPPort senderPort, destPort = MulticastDNSPort;
-       const CFSocketSet *ss = (const CFSocketSet *)context;
+       const CFSocketSet *const ss = (const CFSocketSet *)context;
        mDNS *const m = ss->m;
-       mDNSInterfaceID InterfaceID = ss->info ? ss->info->ifinfo.InterfaceID : mDNSNULL;
-       struct sockaddr_storage from;
-       size_t fromlen = sizeof(from);
-       char packetifname[IF_NAMESIZE] = "";
-       int err, s1 = -1, skt = CFSocketGetNative(cfs);
-       int count = 0;
+       const int skt = CFSocketGetNative(cfs);
+       const int s1  = (cfs == ss->cfsv4) ? ss->sktv4 : (cfs == ss->cfsv6) ? ss->sktv6 : -1;
+       int err, count = 0;
        
        (void)address; // Parameter not used
        (void)data;    // Parameter not used
@@ -1385,9 +1384,6 @@ mDNSlocal void myCFSocketCallBack(CFSocketRef cfs, CFSocketCallBackType CallBack
        if (CallBackType != kCFSocketReadCallBack)
                LogMsg("myCFSocketCallBack: Why is CallBackType %d not kCFSocketReadCallBack?", CallBackType);
 
-       if      (cfs == ss->cfsv4) s1 = ss->sktv4;
-       else if (cfs == ss->cfsv6) s1 = ss->sktv6;
-
        if (s1 < 0 || s1 != skt)
                {
                LogMsg("myCFSocketCallBack: s1 %d native socket %d, cfs %p", s1, skt, cfs);
@@ -1395,9 +1391,19 @@ mDNSlocal void myCFSocketCallBack(CFSocketRef cfs, CFSocketCallBackType CallBack
                LogMsg("myCFSocketCallBack: cfsv6 %p, sktv6 %d", ss->cfsv6, ss->sktv6);
                }
 
-       mDNSu8 ttl;
-       while ((err = myrecvfrom(s1, &m->imsg, sizeof(m->imsg), (struct sockaddr *)&from, &fromlen, &destAddr, packetifname, &ttl)) >= 0)
+       while (1)
                {
+               // NOTE: When handling multiple packets in a batch, MUST reset InterfaceID before handling each packet
+               mDNSInterfaceID InterfaceID = ss->info ? ss->info->ifinfo.InterfaceID : mDNSNULL;
+               mDNSAddr senderAddr, destAddr;
+               mDNSIPPort senderPort, destPort = MulticastDNSPort;
+               struct sockaddr_storage from;
+               size_t fromlen = sizeof(from);
+               char packetifname[IF_NAMESIZE] = "";
+               mDNSu8 ttl;
+               err = myrecvfrom(s1, &m->imsg, sizeof(m->imsg), (struct sockaddr *)&from, &fromlen, &destAddr, packetifname, &ttl);
+               if (err < 0) break;
+               
                count++;
                if (from.ss_family == AF_INET)
                        {
@@ -1432,20 +1438,22 @@ mDNSlocal void myCFSocketCallBack(CFSocketRef cfs, CFSocketCallBackType CallBack
                                verbosedebugf("myCFSocketCallBack got multicast packet from %#a to %#a on unicast socket (Ignored)", &senderAddr, &destAddr);
                                return;
                                }
-                       else if (!strcmp(ss->info->ifa_name, packetifname))
-                               verbosedebugf("myCFSocketCallBack got multicast packet from %#a to %#a on interface %#a/%s",
-                                       &senderAddr, &destAddr, &ss->info->ifinfo.ip, ss->info->ifa_name);
-                       else
+                       else if (strcmp(ss->info->ifa_name, packetifname))
                                {
                                verbosedebugf("myCFSocketCallBack got multicast packet from %#a to %#a on interface %#a/%s (Ignored -- really arrived on interface %s)",
                                        &senderAddr, &destAddr, &ss->info->ifinfo.ip, ss->info->ifa_name, packetifname);
                                return;
                                }
+                       else
+                               verbosedebugf("myCFSocketCallBack got multicast packet from %#a to %#a on interface %#a/%s",
+                                       &senderAddr, &destAddr, &ss->info->ifinfo.ip, ss->info->ifa_name);
                        }
                else
                        {
-                       // Note: For unicast packets, try to find the matching mDNSCore interface object 
-                       // (though we may not be able to, for unicast packets received over something like a PPP link)
+                       // Note: Unicast packets are delivered to *one* of our listening sockets,
+                       // not necessarily the one bound to the physical interface where the packet arrived.
+                       // To sort this out we search our interface list and update InterfaceID to reference
+                       // the mDNSCore interface object for the interface where the packet was actually received.
                        NetworkInterfaceInfo *intf = m->HostInterfaces;
                        while (intf && strcmp(intf->ifname, packetifname)) intf = intf->next;
                        if (intf) InterfaceID = intf->InterfaceID;
@@ -1465,7 +1473,7 @@ mDNSlocal void myCFSocketCallBack(CFSocketRef cfs, CFSocketCallBackType CallBack
                int so_error = -1;
                int so_nread = -1;
                int fionread = -1;
-               int solen = sizeof(int);
+               socklen_t solen = sizeof(int);
                fd_set readfds;
                FD_ZERO(&readfds);
                FD_SET(s1, &readfds);
@@ -1772,25 +1780,45 @@ mDNSlocal void SetDDNSNameStatus(domainname *const dname, mStatus status)
                        if (!(*(p+1)) && *p == '.') *p = 0; // if last character, strip trailing dot
                        p++;
                        }
-               
-               const void *StatusKey = CFSTR("Status");                
-               const void *StatusVal = CFNumberCreate(NULL, kCFNumberSInt32Type, &status); // CFNumberRef
-               const void *StatusDict = CFDictionaryCreate(NULL, &StatusKey, &StatusVal, 1, NULL, NULL);
-
-               const void *HostKey = CFStringCreateWithCString(NULL, uname, kCFStringEncodingUTF8);
-               const void *HostDict = CFDictionaryCreate(NULL, &HostKey, &StatusDict, 1, NULL, NULL);
-                               
-               const void *StateKey = CFSTR("HostNames"); // CFStringRef
-               CFDictionaryRef StateDict = CFDictionaryCreate(NULL, &StateKey, &HostDict, 1, NULL, NULL);
-               SCDynamicStoreSetValue(store, CFSTR("State:/Network/DynamicDNS"), StateDict);
-
-               CFRelease(StateDict);
-               CFRelease(StateKey);
-               CFRelease(HostDict);
-               CFRelease(HostKey);
-               CFRelease(StatusDict);
-               CFRelease(StatusVal);
-               CFRelease(StatusKey);
+
+               // We need to make a CFDictionary called "State:/Network/DynamicDNS" containing (at present) a single entity.
+               // That single entity is a CFDictionary with name "HostNames".
+               // The "HostNames" CFDictionary contains a set of name/value pairs, where the each name is the FQDN
+               // in question, and the corresponding value is a CFDictionary giving the state for that FQDN.
+               // (At present we only support a single FQDN, so this dictionary holds just a single name/value pair.)
+               // The CFDictionary for each FQDN holds (at present) a single name/value pair,
+               // where the name is "Status" and the value is a CFNumber giving an errror code (with zero meaning success).
+
+               const CFStringRef StateKeys [1] = { CFSTR("HostNames") };
+               const CFStringRef HostKeys  [1] = { CFStringCreateWithCString(NULL, uname, kCFStringEncodingUTF8) };
+               const CFStringRef StatusKeys[1] = { CFSTR("Status") };
+               if (!HostKeys[0]) LogMsg("SetDDNSNameStatus: CFStringCreateWithCString(%s) failed", uname);
+               else
+                       {
+                       const CFNumberRef StatusVals[1] = { CFNumberCreate(NULL, kCFNumberSInt32Type, &status) };
+                       if (!StatusVals[0]) LogMsg("SetDDNSNameStatus: CFNumberCreate(%ld) failed", status);
+                       else
+                               {
+                               const CFDictionaryRef HostVals[1] = { CFDictionaryCreate(NULL, (void*)StatusKeys, (void*)StatusVals, 1, NULL, NULL) };
+                               if (HostVals[0])
+                                       {
+                                       const CFDictionaryRef StateVals[1] = { CFDictionaryCreate(NULL, (void*)HostKeys, (void*)HostVals, 1, NULL, NULL) };
+                                       if (StateVals[0])
+                                               {
+                                               CFDictionaryRef StateDict = CFDictionaryCreate(NULL, (void*)StateKeys, (void*)StateVals, 1, NULL, NULL);
+                                               if (StateDict)
+                                                       {
+                                                       SCDynamicStoreSetValue(store, CFSTR("State:/Network/DynamicDNS"), StateDict);
+                                                       CFRelease(StateDict);
+                                                       }
+                                               CFRelease(StateVals[0]);
+                                               }
+                                       CFRelease(HostVals[0]);
+                                       }
+                               CFRelease(StatusVals[0]);
+                               }
+                       CFRelease(HostKeys[0]);
+                       }
                CFRelease(store);
                }
        }
@@ -3003,7 +3031,7 @@ mDNSlocal void DynDNSConfigChanged(mDNS *const m)
        CFRelease(store);
        if (!dict)                              // lost v4
                {
-               mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL);
+               mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL);
                if (DynDNSHostname.c[0]) SetDDNSNameStatus(&DynDNSHostname, 1); // Set status to 1 to indicate temporary failure
                return;
                } 
@@ -3033,42 +3061,64 @@ mDNSlocal void DynDNSConfigChanged(mDNS *const m)
 
        // handle primary interface changes
        // if we gained or lost DNS servers (e.g. logged into VPN) "toggle" primary address so it gets re-registered even if it is unchanged
-       if (nAdditions || nDeletions) mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL);
+       if (nAdditions || nDeletions) mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL);
        CFStringRef primary = CFDictionaryGetValue(dict, kSCDynamicStorePropNetPrimaryInterface);
        if (primary)
                {
+               mDNSAddr v4 = zeroAddr, v6 = zeroAddr;
+               mDNSBool HavePrimaryGlobalv6 = mDNSfalse;  // does  the primary interface have a global v6 address?
                struct ifaddrs *ifa = myGetIfAddrs(1);
-
+               
                if (!CFStringGetCString(primary, buf, 256, kCFStringEncodingUTF8))
                        { LogMsg("Could not convert router to CString"); goto error; }          
 
                // find primary interface in list
-               while (ifa)
+               while (ifa && (!v4.ip.v4.NotAnInteger || !HavePrimaryGlobalv6))
                        {
-                       if (ifa->ifa_addr->sa_family == AF_INET && !strcmp(buf, ifa->ifa_name))
+                       mDNSAddr tmp6 = zeroAddr;
+                       if (!strcmp(buf, ifa->ifa_name))
+                               {                               
+                               if      (ifa->ifa_addr->sa_family == AF_INET) SetupAddr(&v4, ifa->ifa_addr);                                    
+                               else if (ifa->ifa_addr->sa_family == AF_INET6)                          
+                                       {
+                                       SetupAddr(&tmp6, ifa->ifa_addr);
+                                       if (tmp6.ip.v6.b[0] >> 5 == 1)   // global prefix: 001
+                                               { HavePrimaryGlobalv6 = mDNStrue; v6 = tmp6; }
+                                       }
+                               }
+                       else
                                {
-                               mDNSAddr ip;
-                               SetupAddr(&ip, ifa->ifa_addr);
-                               if (ip.ip.v4.b[0] == 169 && ip.ip.v4.b[1] == 254)
-                                       { mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL); break; }  // primary IP is link-local                            
-                               if (ip.ip.v4.NotAnInteger != u->PrimaryIP.ip.v4.NotAnInteger ||
-                                       r.ip.v4.NotAnInteger != u->Router.ip.v4.NotAnInteger)
+                               // We'll take a V6 address from the non-primary interface if the primary interface doesn't have a global V6 address
+                               if (!HavePrimaryGlobalv6 && ifa->ifa_addr->sa_family == AF_INET6 && !v6.ip.v6.b[0])
                                        {
-                                       if (LegacyNATInitialized) { LegacyNATDestroy(); LegacyNATInitialized = mDNSfalse; }
-                                       if (r.ip.v4.NotAnInteger && IsPrivateV4Addr(&ip))
-                                               {
-                                               mStatus err = LegacyNATInit();
-                                               if (err)  LogMsg("ERROR: LegacyNATInit");
-                                               else LegacyNATInitialized = mDNStrue;
-                                               }                                       
-                                       mDNS_SetPrimaryInterfaceInfo(m, &ip, r.ip.v4.NotAnInteger ? &r : NULL);
-                                       break;
+                                       SetupAddr(&tmp6, ifa->ifa_addr);
+                                       if (tmp6.ip.v6.b[0] >> 5 == 1) v6 = tmp6;
                                        }
                                }
                        ifa = ifa->ifa_next;
                        }
+
+               // Note that while we advertise v6, we still require v4 (possibly NAT'd, but not link-local) because we must use
+               // V4 to communicate w/ our DNS server
+                                       
+               if (v4.ip.v4.b[0] == 169 && v4.ip.v4.b[1] == 254) mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL);  // primary IP is link-local
+               else
+                       {
+                       if (v4.ip.v4.NotAnInteger != u->AdvertisedV4.ip.v4.NotAnInteger ||
+                               memcmp(v6.ip.v6.b, u->AdvertisedV6.ip.v6.b, 16)             ||
+                               r.ip.v4.NotAnInteger != u->Router.ip.v4.NotAnInteger)
+                               {
+                               if (LegacyNATInitialized) { LegacyNATDestroy(); LegacyNATInitialized = mDNSfalse; }
+                               if (r.ip.v4.NotAnInteger && IsPrivateV4Addr(&v4))
+                                       {
+                                       mStatus err = LegacyNATInit();
+                                       if (err)  LogMsg("ERROR: LegacyNATInit");
+                                       else LegacyNATInitialized = mDNStrue;
+                                       }                                       
+                               mDNS_SetPrimaryInterfaceInfo(m, &v4, v6.ip.v6.b[0] ? &v6 : NULL, r.ip.v4.NotAnInteger ? &r : NULL);
+                               }
+                       }
                }
-       
        error:
        CFRelease(dict);
        }
@@ -3459,8 +3509,8 @@ mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
 
        struct sockaddr_in s4;
        struct sockaddr_in6 s6;
-       int n4 = sizeof(s4);
-       int n6 = sizeof(s6);
+       socklen_t n4 = sizeof(s4);
+       socklen_t n6 = sizeof(s6);
        if (getsockname(m->p->unicastsockets.sktv4, (struct sockaddr *)&s4, &n4) < 0) LogMsg("getsockname v4 error %d (%s)", errno, strerror(errno));
        else m->UnicastPort4.NotAnInteger = s4.sin_port;
        if (getsockname(m->p->unicastsockets.sktv6, (struct sockaddr *)&s6, &n6) < 0) LogMsg("getsockname v6 error %d (%s)", errno, strerror(errno));
index 37d071d1bc2f9e9765df5e4fa094f15a3b62bf36..8eac6b3f23a5ef06508157664f788ce6e06f2a6d 100644 (file)
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "";
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               GCC_VERSION = 3.3;
                                HEADER_SEARCH_PATHS = "../mDNSShared \"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\" \"$(OBJROOT)\"";
                                LIBRARY_SEARCH_PATHS = "";
                                MACOSX_DEPLOYMENT_TARGET = 10.2;
                                OPTIMIZATION_CFLAGS = "-O0";
                                OTHER_CFLAGS = "-no-cpp-precomp -mdynamic-no-pic -D__MACOSX__ -DmDNSResponderVersion=$(MVERS) -D_LEGACY_NAT_TRAVERSAL_ -DMDNS_DEBUGMSGS=1";
-                               OTHER_LDFLAGS = "-weak-ldnsinfo";
+                               OTHER_LDFLAGS = "-ldnsinfo";
                                OTHER_REZFLAGS = "";
                                PRODUCT_NAME = mDNSResponder.debug;
                                REZ_EXECUTABLE = YES;
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "";
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               GCC_VERSION = 3.3;
                                HEADER_SEARCH_PATHS = "../mDNSShared \"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\" \"$(OBJROOT)\"";
                                INSTALL_PATH = /usr/sbin;
                                LIBRARY_SEARCH_PATHS = "";
                                MACOSX_DEPLOYMENT_TARGET = 10.2;
                                OTHER_CFLAGS = "-no-cpp-precomp -mdynamic-no-pic -D__MACOSX__ -DmDNSResponderVersion=$(MVERS) -D_LEGACY_NAT_TRAVERSAL_";
-                               OTHER_LDFLAGS = "-weak-ldnsinfo";
+                               OTHER_LDFLAGS = "-ldnsinfo";
                                OTHER_REZFLAGS = "";
                                PRODUCT_NAME = mDNSResponder;
                                REZ_EXECUTABLE = YES;
                        );
                        buildSettings = {
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               GCC_VERSION = 3.3;
                                INSTALL_PATH = /usr/bin;
                                MACOSX_DEPLOYMENT_TARGET = 10.2;
                                OTHER_CFLAGS = "-no-cpp-precomp -mdynamic-no-pic -D__MACOSX__ -DmDNSResponderVersion=$(MVERS)";
                        buildSettings = {
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = 1;
-                               GCC_VERSION = 3.3;
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Java/Extensions";
                                JAVA_ARCHIVE_CLASSES = YES;
                                JAVA_ARCHIVE_COMPRESSION = YES;
                                DEBUGGING_SYMBOLS = NO;
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                DYLIB_CURRENT_VERSION = 1;
-                               GCC_VERSION = 3.3;
                                HEADER_SEARCH_PATHS = "../mDNSShared \"$(SYSTEM_LIBRARY_DIR)/Frameworks/JavaVM.framework/Versions/A/Headers\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/JavaVM.framework/Versions/1.3.1/Headers\" \"$(OBJROOT)/mDNSResponder.build/dns_sd.jar.build\"";
                                INSTALL_PATH = /usr/lib/java;
                                LIBRARY_STYLE = DYNAMIC;
                        );
                        buildSettings = {
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               GCC_VERSION = 3.3;
                                INSTALL_PATH = /usr/bin;
                                MACOSX_DEPLOYMENT_TARGET = 10.2;
                                OTHER_CFLAGS = "-no-cpp-precomp -mdynamic-no-pic -D__MACOSX__ -DmDNSResponderVersion=$(MVERS) -I../mDNSShared";
                        buildSettings = {
                                FRAMEWORK_SEARCH_PATHS = "";
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               GCC_VERSION = 3.3;
                                HEADER_SEARCH_PATHS = "\"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\"";
                                INSTALL_PATH = /usr/sbin;
                                LIBRARY_SEARCH_PATHS = "";
                        );
                        buildSettings = {
                                EXPORTED_SYMBOLS_FILE = "";
-                               GCC_VERSION = 3.3;
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PreferencePanes";
                                MACOSX_DEPLOYMENT_TARGET = 10.2;
                                OTHER_CFLAGS = "";
        <key>CFBundleGetInfoString</key>
        <string></string>
        <key>CFBundleIconFile</key>
-       <string>BonjourPref</string>
+       <string>DNSServiceDiscoveryPref</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.preference.bonjour</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>NSMainNibFile</key>
        <string>DNSServiceDiscoveryPref</string>
        <key>NSPrefPaneIconFile</key>
-       <string>BonjourPref.tiff</string>
+       <string>DNSServiceDiscoveryPref.tiff</string>
        <key>NSPrefPaneIconLabel</key>
        <string>Bonjour</string>
        <key>NSPrincipalClass</key>
                };
                FF260A3207B4466900CE10E5 = {
                        isa = PBXFileReference;
-                       name = BonjourPref.icns;
-                       path = PreferencePane/BonjourPref.icns;
+                       name = DNSServiceDiscoveryPref.icns;
+                       path = PreferencePane/DNSServiceDiscoveryPref.icns;
                        refType = 2;
                };
                FF260A3307B4466900CE10E5 = {
                        isa = PBXFileReference;
-                       name = BonjourPref.tiff;
-                       path = PreferencePane/BonjourPref.tiff;
+                       name = DNSServiceDiscoveryPref.tiff;
+                       path = PreferencePane/DNSServiceDiscoveryPref.tiff;
                        refType = 2;
                };
                FF260A3407B4466900CE10E5 = {
index 4ef7ccfb55635624adf270173baf13c2b14337b1..638b56d36ad4e7194113d793512b351b22c0768b 100755 (executable)
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 # $Log: Makefile,v $
-# Revision 1.59  2005/04/14 21:07:10  rpantos
-# Bug #: 4089257, Clean build broken for Java support on POSIX
-# Submitted by: Roger Pantos
-# Reviewed by: Kiren Sekar
-#
-# Revision 1.58  2005/04/08 21:37:57  ksekar
-# <rdar://problem/3792767> get_ifi_info doesn't return IPv6 interfaces on Linux
-#
-# Revision 1.57  2005/03/17 04:02:28  cheshire
-# <rdar://problem/3986419> mDNSResponder won't compile with gcc4 on Tiger
-# Changed Makefile to link using gcc instead of libtool
-#
 # Revision 1.56  2005/02/02 02:25:21  cheshire
 # <rdar://problem/3980388> /var/run/mDNSResponder should be /var/run/mdnsd on Linux
 #
@@ -265,7 +253,7 @@ endif
 else
 
 ifeq ($(os),linux)
-CFLAGS_OS = -DNOT_HAVE_SA_LEN -DUSES_NETLINK -DHAVE_LINUX
+CFLAGS_OS = -DNOT_HAVE_SA_LEN -DUSES_NETLINK
 JAVACFLAGS_OS += -I$(JDK)/include/linux
 OPTIONALTARG = nss_mdns
 OPTINSTALL   = InstalledNSS
@@ -313,7 +301,7 @@ else
 ifeq ($(os),tiger)
 CFLAGS_OS = -DHAVE_IPV6 -no-cpp-precomp -Wdeclaration-after-statement
 CC = @gcc-4.0
-LD = $(CC) -dynamiclib
+LD = libtool -dynamic
 LIBFLAGS = -lSystem
 LDSUFFIX = dylib
 JDK = /System/Library/Frameworks/JavaVM.framework/Home
@@ -521,8 +509,8 @@ Java: setup $(BUILDDIR)/dns_sd.jar $(BUILDDIR)/libjdns_sd.$(LDSUFFIX)
 
 JAVASRC        = $(SHAREDDIR)/Java
 JARCONTENTS =  $(OBJDIR)/com/apple/dnssd/DNSSDService.class \
-                               $(OBJDIR)/com/apple/dnssd/DNSSDException.class \
                                $(OBJDIR)/com/apple/dnssd/DNSRecord.class \
+                               $(OBJDIR)/com/apple/dnssd/DNSSDException.class \
                                $(OBJDIR)/com/apple/dnssd/TXTRecord.class \
                                $(OBJDIR)/com/apple/dnssd/DNSSDRegistration.class \
                                $(OBJDIR)/com/apple/dnssd/BaseListener.class \
index 8903d8184a4ec90ccfcfbd8146669784978dbf91..6acf92ef42a06bf580fca2719b6ce9937f4d91bf 100644 (file)
     Change History (most recent first):
 
 $Log: dnsextd.c,v $
-Revision 1.35  2005/03/17 03:57:43  cheshire
-LEASE_OPT_SIZE is now LEASE_OPT_RDLEN; LLQ_OPT_SIZE is now LLQ_OPT_RDLEN
-
-Revision 1.34  2005/03/16 18:47:37  ksekar
-<rdar://problem/4046465> dnsextd doesn't clean up on exit
+Revision 1.33.2.1  2005/08/05 21:14:00  ksekar
+<rdar://problem/4012279> Long-lived queries not working on windows
+Change constant names
 
 Revision 1.33  2005/03/11 19:09:02  ksekar
 Fixed ZERO_LLQID macro
@@ -981,30 +979,37 @@ mDNSlocal void DeleteRecord(DaemonInfo *d, CacheRecord *rr, domainname *zone)
        if (reply) free(reply);
        }
 
-// iterate over table, deleting expired records (or all records if DeleteAll is true)
-mDNSlocal void DeleteRecords(DaemonInfo *d, mDNSBool DeleteAll)
+// iterate over table, deleting expired records
+mDNSlocal void DeleteExpiredRecords(DaemonInfo *d)
        {
        int i;
-       RRTableElem **ptr, *fptr;       
+       RRTableElem *ptr, *prev, *fptr; 
        struct timeval now;
 
-       if (gettimeofday(&now, NULL)) { LogErr("DeleteRecords ", "gettimeofday"); return; }
-       if (pthread_mutex_lock(&d->tablelock)) { LogErr("DeleteRecords", "pthread_mutex_lock"); return; }
+       if (gettimeofday(&now, NULL)) { LogErr("DeleteExpiredRecords ", "gettimeofday"); return; }
+       if (pthread_mutex_lock(&d->tablelock)) { LogErr("DeleteExpiredRecords", "pthread_mutex_lock"); return; }
        for (i = 0; i < d->nbuckets; i++)
                {
-               ptr = &d->table[i];
-               while (*ptr)
+               ptr = d->table[i];
+               prev = NULL;
+               while (ptr)
                        {
-                       if (DeleteAll || (*ptr)->expire - now.tv_sec < 0)
+                       if (ptr->expire - now.tv_sec < 0)
                                {
                                // delete record from server
-                               DeleteRecord(d, &(*ptr)->rr, &(*ptr)->zone);
-                               fptr = *ptr;
-                               *ptr = (*ptr)->next;
+                               DeleteRecord(d, &ptr->rr, &ptr->zone);
+                               if (prev) prev->next = ptr->next;
+                               else d->table[i] = ptr->next;
+                               fptr = ptr;
+                               ptr = ptr->next;
                                free(fptr);
                                d->nelems--;
                                }
-                       else ptr = &(*ptr)->next;
+                       else
+                               {
+                               prev = ptr;
+                               ptr = ptr->next;
+                               }
                        }
                }
        pthread_mutex_unlock(&d->tablelock);
@@ -1413,28 +1418,6 @@ mDNSlocal void SendEvents(DaemonInfo *d, LLQEntry *e)
        if (SendLLQ(d, &response, e->cli) < 0) LogMsg("Error: SendEvents - SendLLQ");           
        }
 
-mDNSlocal void PrintLLQAnswers(DaemonInfo *d)
-       {
-       int i;
-       char rrbuf[80];
-       
-       Log("Printing LLQ Answer Table contents");
-
-       for (i = 0; i < LLQ_TABLESIZE; i++)
-               {
-               AnswerListElem *a = d->AnswerTable[i];
-               while(a)
-                       {
-                       int ancount = 0;
-                       const CacheRecord *rr = a->KnownAnswers;
-                       while (rr) { ancount++; rr = rr->next; }                
-                       Log("%p : Question %##s;  type %d;  referenced by %d LLQs; %d answers:", a, a->name.c, a->type, a->refcount, ancount);
-                       for (rr = a->KnownAnswers; rr; rr = rr->next) Log("\t%s", GetRRDisplayString_rdb(&rr->resrec, &rr->resrec.rdata->u, rrbuf));
-                       a = a->next;
-                       }
-               }
-       }
-
 mDNSlocal void PrintLLQTable(DaemonInfo *d)
        {
        LLQEntry *e;
@@ -1448,19 +1431,9 @@ mDNSlocal void PrintLLQTable(DaemonInfo *d)
                e = d->LLQTable[i];
                while(e)
                        {
-                       char *state;
-                       
-                       switch (e->state)
-                               {
-                               case RequestReceived: state = "RequestReceived"; break;
-                               case ChallengeSent:   state = "ChallengeSent";   break;
-                               case Established:     state = "Established";     break;
-                               default:              state = "unknown";                                        
-                               }
-                       inet_ntop(AF_INET, &e->cli.sin_addr, addr, 32);                         
-                       
-                       Log("LLQ from %s in state %s; %##s; type %d; orig lease %d; remaining lease %d; AnswerList %p)",
-                               addr, state, e->qname.c, e->qtype, e->lease, LLQLease(e), e->AnswerList);
+                       inet_ntop(AF_INET, &e->cli.sin_addr, addr, 32);
+                       Log("LLQ from %##s type %d lease %d (%d remaining)",
+                               addr, e->qname.c, e->qtype, e->lease, LLQLease(e));
                        e = e->next;
                        }
                }
@@ -2061,7 +2034,7 @@ mDNSlocal int ListenForUpdates(DaemonInfo *d)
                if (gettimeofday(&timenow, NULL)) { LogErr("ListenForUpdates", "gettimeofday"); return -1; }
                if (timenow.tv_sec >= NextTableCheck)
                        {
-                       DeleteRecords(d, mDNSfalse);
+                       DeleteExpiredRecords(d);
                        NextTableCheck = timenow.tv_sec + EXPIRATION_INTERVAL;
                        }
                timeout.tv_sec = NextTableCheck - timenow.tv_sec;
@@ -2075,8 +2048,8 @@ mDNSlocal int ListenForUpdates(DaemonInfo *d)
                        {
                        if (errno == EINTR)
                                {
-                               if (terminate) { DeleteRecords(d, mDNStrue); return 0; }
-                               else if (dumptable) { PrintLeaseTable(d); PrintLLQTable(d); PrintLLQAnswers(d); dumptable = 0; }
+                               if (terminate) { DeleteExpiredRecords(d); return 0; }
+                               else if (dumptable) { PrintLeaseTable(d); PrintLLQTable(d); dumptable = 0; }
                                else Log("Received unhandled signal - continuing"); 
                                }
                        else { LogErr("ListenForUpdates", "select"); return -1; }
index a0491386854647f844018a5a58b51d692ff3a45b..32a016cdd2ba15f13fdc2638afe196667db856aa 100755 (executable)
     Change History (most recent first):
 
 $Log: mDNSUNP.c,v $
-Revision 1.26  2005/04/08 21:43:59  ksekar
-<rdar://problem/4083426>  mDNSPosix (v98) retrieve interface list bug on AMD64 architecture
-Submitted by Andrew de Quincey
-
-Revision 1.25  2005/04/08 21:37:57  ksekar
-<rdar://problem/3792767> get_ifi_info doesn't return IPv6 interfaces on Linux
-
-Revision 1.24  2005/04/08 21:30:16  ksekar
-<rdar://problem/4007457> Compiling problems with mDNSResponder-98 on Solaris/Sparc v9
-Patch submitted by Bernd Kuhls
-
 Revision 1.23  2004/12/01 04:25:05  cheshire
 <rdar://problem/3872803> Darwin patches for Solaris and Suse
 Provide daemon() for platforms that don't have it
@@ -140,135 +129,10 @@ First checkin
     #include <net/if_dl.h>
 #endif
 
-#if defined(AF_INET6) && HAVE_IPV6 && !HAVE_LINUX
+#if defined(AF_INET6) && HAVE_IPV6
 #include <netinet6/in6_var.h>
 #endif
 
-#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
-#include <netdb.h>
-#include <arpa/inet.h>
-
-/* Converts a prefix length to IPv6 network mask */
-void plen_to_mask(int plen, char *addr) {
-       int i;
-       int colons=7; /* Number of colons in IPv6 address */
-       int bits_in_block=16; /* Bits per IPv6 block */
-       for(i=0;i<=colons;i++) {
-               int block, ones=0xffff, ones_in_block;
-               if(plen>bits_in_block) ones_in_block=bits_in_block;
-               else                   ones_in_block=plen;
-               block = ones & (ones << (bits_in_block-ones_in_block));
-               i==0 ? sprintf(addr, "%x", block) :
- sprintf(addr, "%s:%x", addr, block);
-               plen -= ones_in_block;
-               }
-       }
-
-/* Gets IPv6 interface information from the /proc filesystem in linux*/
-struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
-       {
-       struct ifi_info *ifi, *ifihead, **ifipnext;
-       FILE *fp;
-       char addr[8][5];
-       int flags, myflags, index, plen, scope;
-       char ifname[8], lastname[IFNAMSIZ];
-       char addr6[33];
-       struct addrinfo hints, *res0;
-       struct sockaddr_in6 *sin6;
-       struct in6_addr *addrptr;
-       int err;
-
-       res0=NULL;
-       ifihead = NULL;
-       ifipnext = &ifihead;
-       lastname[0] = 0;
-
-       if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
-               while (fscanf(fp,
-                                         "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
-                                         addr[0],addr[1],addr[2],addr[3],
-                                         addr[4],addr[5],addr[6],addr[7],
-                                         &index, &plen, &scope, &flags, ifname) != EOF) {
-
-                       myflags = 0;
-                       if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
-                               if (doaliases == 0)
-                                       continue;   /* already processed this interface */
-                               myflags = IFI_ALIAS;
-                               }
-                       memcpy(lastname, ifname, IFNAMSIZ);
-                       ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
-                       if (ifi == NULL) {
-                               goto gotError;
-                               }
-
-                       *ifipnext = ifi;            /* prev points to this new one */
-                       ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */
-
-                       sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
-                                       addr[0],addr[1],addr[2],addr[3],
-                                       addr[4],addr[5],addr[6],addr[7]);
-
-                       /* Add address of the interface */
-                       memset(&hints, 0, sizeof(hints));
-                       hints.ai_family = AF_INET6;
-                       hints.ai_flags = AI_NUMERICHOST;
-                       err = getaddrinfo(addr6, NULL, &hints, &res0);
-                       if (err) {
-                               goto gotError;
-                               }
-                       ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
-                       if (ifi->ifi_addr == NULL) {
-                               goto gotError;
-                               }
-                       memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));
-
-                       /* Add netmask of the interface */
-                       char ipv6addr[INET6_ADDRSTRLEN];
-                       plen_to_mask(plen, ipv6addr);
-                       ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
-                       if (ifi->ifi_addr == NULL) {
-                               goto gotError;
-                               }
-                       sin6=calloc(1, sizeof(struct sockaddr_in6));
-                       addrptr=calloc(1, sizeof(struct in6_addr));
-                       inet_pton(family, ipv6addr, addrptr);
-                       sin6->sin6_family=family;
-                       sin6->sin6_addr=*addrptr;
-                       sin6->sin6_scope_id=scope;
-                       memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
-                       free(sin6);
-
-
-                       /* Add interface name */
-                       memcpy(ifi->ifi_name, ifname, IFI_NAME);
-
-                       /* Add interface index */
-                       ifi->ifi_index = index;
-
-                       /* If interface is in /proc then it is up*/
-                       ifi->ifi_flags = IFF_UP;
-
-                       freeaddrinfo(res0);
-                       res0=NULL;
-                       }
-               }
-       goto done;
-
-       gotError:
-       if (ifihead != NULL) {
-               free_ifi_info(ifihead);
-               ifihead = NULL;
-               }
-       if (res0 != NULL) {
-               freeaddrinfo(res0);
-               res0=NULL;
-               }
-       done:
-       return(ifihead);    /* pointer to first structure in linked list */
-       }
-#endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
-
 struct ifi_info *get_ifi_info(int family, int doaliases)
 {
     int                 junk;
@@ -286,11 +150,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
     struct sockaddr_in6 *sinptr6;
 #endif
 
-#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
- if(family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases);
-#endif
-
-       sockfd = -1;
+    sockfd = -1;
     sockf6 = -1;
     buf = NULL;
     ifihead = NULL;
@@ -331,7 +191,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
         ifr = (struct ifreq *) ptr;
 
                len = GET_SA_LEN(ifr->ifr_addr);
-               ptr += sizeof(struct ifreq); /* for next one in buffer */
+        ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */
     
 //        fprintf(stderr, "intf %d name=%s AF=%d\n", index, ifr->ifr_name, ifr->ifr_addr.sa_family);
         
@@ -674,8 +534,6 @@ struct in_pktinfo
 #ifdef NOT_HAVE_DAEMON
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <signal.h>
-
 int daemon(int nochdir, int noclose)
     {
        switch (fork())
index 912c9d8ff1a75c3ed7547b2114e1e4c2e693954b..786fef7e50a42940d444d7d4f95af61569defac5 100755 (executable)
@@ -24,9 +24,6 @@
     Change History (most recent first):
 
 $Log: mDNSUNP.h,v $
-Revision 1.18  2005/04/08 21:37:57  ksekar
-<rdar://problem/3792767> get_ifi_info doesn't return IPv6 interfaces on Linux
-
 Revision 1.17  2004/12/17 19:32:43  cheshire
 Add missing semicolon
 
@@ -93,10 +90,6 @@ First checkin
 #include <net/if.h>
 #include <netinet/in.h>
 
-#ifdef HAVE_LINUX
-#include <linux/socket.h>
-#endif
-
 #ifdef  __cplusplus
     extern "C" {
 #endif
@@ -106,12 +99,8 @@ First checkin
 #endif
 
 #if !defined(_SS_MAXSIZE)
-#if HAVE_IPV6
-#define sockaddr_storage sockaddr_in6
-#else
-#define sockaddr_storage sockaddr
-#endif // HAVE_IPV6    
-#endif // !defined(_SS_MAXSIZE)
+    #define sockaddr_storage sockaddr
+#endif
 
 #ifndef NOT_HAVE_SA_LEN
 #define GET_SA_LEN(X) (sizeof(struct sockaddr) > ((struct sockaddr*)&(X))->sa_len ? \
@@ -157,17 +146,6 @@ struct ifi_info {
   struct ifi_info  *ifi_next;   /* next of these structures */
 };
 
-#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
-#define PROC_IFINET6_PATH "/proc/net/if_inet6"
-extern struct ifi_info  *get_ifi_info_linuxv6(int family, int doaliases);
-#endif
-       
-#if defined(AF_INET6) && HAVE_IPV6
-#define INET6_ADDRSTRLEN 46 /*Maximum length of IPv6 address */
-#endif
-       
-
-       
 #define IFI_ALIAS   1           /* ifi_addr is an alias */
 
 /* From the text (Stevens, section 16.6): */
index a034e3e82b36562f3d50827f30ca2c46a6a82abf..423805fa990269c2ba755e1c3bc6f0a5c9f98ee5 100755 (executable)
@@ -34,7 +34,6 @@ Global
                {F4F15529-F0EB-402F-8662-73C5797EE557}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
                {BB8AC1B5-6587-4163-BDC6-788B157705CA}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
                {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
-               {F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
                {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
                {B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
                {BB8AC1B5-6587-4163-BDC6-788B157705CA}.0 = {AB581101-18F0-46F6-B56A-83A6B1EA657E}\r
index 831b4b458142c7aa24985123149c006534731519..d8a7ce1aba660215aef13e99c99cb2a7ce414b4c 100644 (file)
     Change History (most recent first):
 
 $Log: DNSSD.java,v $
+Revision 1.8  2005/07/11 01:55:21  cheshire
+<rdar://problem/4175511> Race condition in Java API
+
+Revision 1.7  2005/07/05 13:01:52  cheshire
+<rdar://problem/4169791> If mDNSResponder daemon is stopped, Java API spins, burning CPU time
+
+Revision 1.6  2005/07/05 00:02:25  cheshire
+Add missing comma
+
+Revision 1.5  2005/07/04 21:13:47  cheshire
+Add missing error message strings
+
 Revision 1.4  2004/12/11 03:00:59  rpantos
 <rdar://problem/3907498> Java DNSRecord API should be cleaned up
 
@@ -514,13 +526,23 @@ class     AppleDNSSDException extends DNSSDException
                        "BAD_FLAGS",
                        "UNSUPPORTED",
                        "NOT_INITIALIZED",
-                       "",             // there is NO number 6
+                       "NO_CACHE",
                        "ALREADY_REGISTERED",
                        "NAME_CONFLICT",
                        "INVALID",
-                       "",             // another MIA
+                       "FIREWALL",
                        "INCOMPATIBLE",
-                       "BAD_INTERFACE_INDEX"
+                       "BAD_INTERFACE_INDEX",
+                       "REFUSED",
+                       "NOSUCHRECORD",
+                       "NOAUTH",
+                       "NOSUCHKEY",
+                       "NATTRAVERSAL",
+                       "DOUBLENAT",
+                       "BADTIME",
+                       "BADSIG",
+                       "BADKEY",
+                       "TRANSIENT"
                };
        
                if ( fErrorCode <= UNKNOWN && fErrorCode > ( UNKNOWN - kMessages.length))
@@ -626,29 +648,17 @@ class     AppleDNSSD extends DNSSD
 
 class  AppleService implements DNSSDService, Runnable
 {
-       public                                  AppleService()  { fNativeContext = 0; }
+       public                                  AppleService(BaseListener listener)     { fNativeContext = 0; fListener = listener; }
 
        public void                             stop() { this.HaltOperation(); }
 
-       public void                             finalize() throws Throwable
-       {
-               this.stop();    
-               super.finalize();
-       }
-
-       /* The run() method is used internally to schedule an update from another thread */
-       public void                             run()
-       {
-               this.ProcessResults();
-       }
-
        /* Block for timeout ms (or forever if -1). Returns 1 if data present, 0 if timed out, -1 if not browsing. */
        protected native int    BlockForData( int msTimeout);
 
        /* Call ProcessResults when data appears on socket descriptor. */
-       protected native void   ProcessResults();
+       protected native int    ProcessResults();
 
-       protected native void   HaltOperation();
+       protected synchronized native void HaltOperation();
 
        protected void                  ThrowOnErr( int rc) throws DNSSDException
        {
@@ -657,32 +667,43 @@ class     AppleService implements DNSSDService, Runnable
        }
 
        protected int   /* warning */   fNativeContext;         // Private storage for native side
-}
-
-
-// A ServiceThread calls AppleService.BlockForData() and schedules its client
-// when data appears.
-class  ServiceThread extends Thread
-{
-       public                  ServiceThread( AppleService owner) { fOwner = owner; }
 
        public void             run()
        {
-               int             result;
-               
                while ( true )
                {
-                       result = fOwner.BlockForData( -1);
-                       if ( result == 1)
+                       // We have to be very careful here. Suppose our DNS-SD operation is stopped from some other thread,
+                       // and then immediately afterwards that thread (or some third, unrelated thread) starts a new DNS-SD
+                       // operation. The Unix kernel always allocates the lowest available file descriptor to a new socket,
+                       // so the same file descriptor is highly likely to be reused for the new operation, and if our old
+                       // stale ServiceThread accidentally consumes bytes off that new socket we'll get really messed up.
+                       // To guard against that, before calling ProcessResults we check to ensure that our
+                       // fNativeContext has not been deleted, which is a telltale sign that our operation was stopped.
+                       // After calling ProcessResults we check again, because it's extremely common for callback
+                       // functions to stop their own operation and start others. For example, a resolveListener callback
+                       // may well stop the resolve and then start a QueryRecord call to monitor the TXT record.
+                       //
+                       // The remaining risk is that between our checking fNativeContext and calling ProcessResults(),
+                       // some other thread could stop the operation and start a new one using same file descriptor, and
+                       // we wouldn't know. To prevent this, the AppleService object's HaltOperation() routine is declared
+                       // synchronized and we perform our checks synchronized on the AppleService object, which ensures
+                       // that HaltOperation() can't execute while we're doing it. Because Java locks are re-entrant this
+                       // locking DOESN'T prevent the callback routine from stopping its own operation, but DOES prevent
+                       // any other thread from stopping it until after the callback has completed and returned to us here.
+
+                       int result = BlockForData(-1);
+                       if (result != 1) break; // If socket has been closed, time to terminate this thread
+                       synchronized (this)
                        {
-                               fOwner.run();
+                               if (fNativeContext == 0) break; // Some other thread stopped our DNSSD operation; time to terminate this thread
+                               result = ProcessResults();
+                               if (fNativeContext == 0) break; // Event listener stopped its own DNSSD operation; terminate this thread
+                               if (result != 0) { fListener.operationFailed(this, result); break; }    // If error, notify listener
                        }
-                       else
-                               break;  // terminate thread
                }
        }
 
-       protected AppleService  fOwner;
+       protected BaseListener fListener;
 }
 
 
@@ -691,16 +712,14 @@ class     AppleBrowser extends AppleService
        public                  AppleBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client) 
        throws DNSSDException
        { 
-               fClient = client; 
+               super(client);
                this.ThrowOnErr( this.CreateBrowser( flags, ifIndex, regType, domain));
                if ( !AppleDNSSD.hasAutoCallbacks)
-                       new ServiceThread( this).start();
+                       new Thread(this).start();
        }
 
        // Sets fNativeContext. Returns non-zero on error.
        protected native int    CreateBrowser( int flags, int ifIndex, String regType, String domain);
-
-       protected BrowseListener        fClient;
 }
 
 class  AppleResolver extends AppleService
@@ -709,17 +728,15 @@ class     AppleResolver extends AppleService
                                                                        String domain, ResolveListener client) 
        throws DNSSDException
        { 
-               fClient = client
+               super(client)
                this.ThrowOnErr( this.CreateResolver( flags, ifIndex, serviceName, regType, domain));
                if ( !AppleDNSSD.hasAutoCallbacks)
-                       new ServiceThread( this).start();
+                       new Thread(this).start();
        }
 
        // Sets fNativeContext. Returns non-zero on error.
        protected native int    CreateResolver( int flags, int ifIndex, String serviceName, String regType, 
                                                                                        String domain);
-
-       protected ResolveListener       fClient;
 }
 
 // An AppleDNSRecord is a simple wrapper around a dns_sd DNSRecord.
@@ -763,10 +780,10 @@ class     AppleRegistration extends AppleService implements DNSSDRegistration
                                                                String host, int port, byte[] txtRecord, RegisterListener client) 
        throws DNSSDException
        { 
-               fClient = client
+               super(client)
                this.ThrowOnErr( this.BeginRegister( ifIndex, flags, serviceName, regType, domain, host, port, txtRecord));
                if ( !AppleDNSSD.hasAutoCallbacks)
-                       new ServiceThread( this).start();
+                       new Thread(this).start();
        }
 
        public DNSRecord        addRecord( int flags, int rrType, byte[] rData, int ttl)
@@ -791,8 +808,6 @@ class       AppleRegistration extends AppleService implements DNSSDRegistration
 
        // Sets fNativeContext. Returns non-zero on error.
        protected native int    AddRecord( int flags, int rrType, byte[] rData, int ttl, AppleDNSRecord destObj);
-
-       protected RegisterListener      fClient;
 }
 
 class  AppleQuery extends AppleService
@@ -801,33 +816,29 @@ class     AppleQuery extends AppleService
                                                                                int rrclass, QueryListener client) 
        throws DNSSDException
        { 
-               fClient = client
+               super(client)
                this.ThrowOnErr( this.CreateQuery( flags, ifIndex, serviceName, rrtype, rrclass));
                if ( !AppleDNSSD.hasAutoCallbacks)
-                       new ServiceThread( this).start();
+                       new Thread(this).start();
        }
 
        // Sets fNativeContext. Returns non-zero on error.
        protected native int    CreateQuery( int flags, int ifIndex, String serviceName, int rrtype, int rrclass);
-
-       protected QueryListener fClient;
 }
 
 class  AppleDomainEnum extends AppleService
 {
-       public                  AppleDomainEnum( int flags, int ifIndex, DomainListener listener
+       public                  AppleDomainEnum( int flags, int ifIndex, DomainListener client
        throws DNSSDException
        { 
-               fClient = listener
+               super(client)
                this.ThrowOnErr( this.BeginEnum( flags, ifIndex));
                if ( !AppleDNSSD.hasAutoCallbacks)
-                       new ServiceThread( this).start();
+                       new Thread(this).start();
        }
 
        // Sets fNativeContext. Returns non-zero on error.
        protected native int    BeginEnum( int flags, int ifIndex);
-
-       protected DomainListener        fClient;
 }
 
 
index ef9940a55d099ba982cc03942aae93cc30de26cb..902e85d02cefb95eb86823cbc54e1ec1cbabd158 100644 (file)
     Change History (most recent first):
 
 $Log: JNISupport.c,v $
+Revision 1.12  2005/07/13 19:20:32  cheshire
+<rdar://problem/4175511> Race condition in Java API
+Additional cleanup suggested by Roger -- NewContext() doesn't need ownerClass parameter any more
+
+Revision 1.11  2005/07/11 01:55:21  cheshire
+<rdar://problem/4175511> Race condition in Java API
+
+Revision 1.10  2005/07/05 13:01:52  cheshire
+<rdar://problem/4169791> If mDNSResponder daemon is stopped, Java API spins, burning CPU time
+
 Revision 1.9  2004/12/11 03:01:00  rpantos
 <rdar://problem/3907498> Java DNSRecord API should be cleaned up
 
@@ -124,7 +134,7 @@ JavaVM              *gJavaVM = NULL;
 #endif
 
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_InitLibrary( JNIEnv *pEnv, jclass cls, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_InitLibrary( JNIEnv *pEnv, jclass cls,
                                                jint callerVersion)
 {
        /* Ensure that caller & interface versions match. */
@@ -194,7 +204,7 @@ static void TeardownCallbackState( void )
 #endif // AUTO_CALLBACKS
 
 
-static OpContext       *NewContext( JNIEnv *pEnv, jobject owner, const char *ownerClass,
+static OpContext       *NewContext( JNIEnv *pEnv, jobject owner,
                                                                const char *callbackName, const char *callbackSig)
 // Create and initialize a new OpContext.
 {
@@ -202,14 +212,14 @@ static OpContext  *NewContext( JNIEnv *pEnv, jobject owner, const char *ownerClas
 
        if ( pContext != NULL)
        {
-               jfieldID                clientField = (*pEnv)->GetFieldID( pEnv, (*pEnv)->GetObjectClass( pEnv, owner), 
-                                                                                                                       "fClient", ownerClass);
+               jfieldID                clientField = (*pEnv)->GetFieldID( pEnv, (*pEnv)->GetObjectClass( pEnv, owner),
+                                                                                                                       "fListener", "Lcom/apple/dnssd/BaseListener;");
 
                pContext->JavaObj = (*pEnv)->NewWeakGlobalRef( pEnv, owner);    // must convert local ref to global to cache;
                pContext->ClientObj = (*pEnv)->GetObjectField( pEnv, owner, clientField);
                pContext->ClientObj = (*pEnv)->NewWeakGlobalRef( pEnv, pContext->ClientObj);    // must convert local ref to global to cache
-               pContext->Callback = (*pEnv)->GetMethodID( pEnv, 
-                                                               (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj), 
+               pContext->Callback = (*pEnv)->GetMethodID( pEnv,
+                                                               (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
                                                                callbackName, callbackSig);
                pContext->Callback2 = NULL;             // not always used
        }
@@ -222,7 +232,7 @@ static void                 ReportError( JNIEnv *pEnv, jobject target, jobject service, DNSSer
 // Invoke operationFailed() method on target with err.
 {
        jclass                  cls = (*pEnv)->GetObjectClass( pEnv, target);
-       jmethodID               opFailed = (*pEnv)->GetMethodID( pEnv, cls, "operationFailed", 
+       jmethodID               opFailed = (*pEnv)->GetMethodID( pEnv, cls, "operationFailed",
                                                                "(Lcom/apple/dnssd/DNSSDService;I)V");
 
        (*pEnv)->CallVoidMethod( pEnv, target, opFailed, service, err);
@@ -239,6 +249,7 @@ JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_HaltOperation( JNIEnv *
                OpContext       *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
                if ( pContext != NULL)
                {
+                       // MUST clear fNativeContext first, BEFORE calling DNSServiceRefDeallocate()
                        (*pEnv)->SetIntField( pEnv, pThis, contextField, 0);
                        if ( pContext->ServiceRef != NULL)
                                DNSServiceRefDeallocate( pContext->ServiceRef);
@@ -283,7 +294,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_BlockForData( JNIEnv *p
 }
 
 
-JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv *pEnv, jobject pThis)
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv *pEnv, jobject pThis)
 /* Call through to DNSServiceProcessResult() while data remains on socket. */
 {
 #if !AUTO_CALLBACKS    // ProcessResults() not supported with AUTO_CALLBACKS 
@@ -291,6 +302,7 @@ JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv
        jclass                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
        jfieldID                contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
        OpContext               *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+       DNSServiceErrorType err = kDNSServiceErr_BadState;
 
        if ( pContext != NULL)
        {
@@ -303,17 +315,27 @@ JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv
                FD_ZERO( &readFDs);
                FD_SET( sd, &readFDs);
 
-               while ( 0 < select( sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout))
+               err = kDNSServiceErr_NoError;
+               if (0 < select(sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout))
                {
-                       DNSServiceProcessResult( pContext->ServiceRef);
+                       err = DNSServiceProcessResult(pContext->ServiceRef);
+                       // Use caution here!
+                       // We cannot touch any data structures associated with this operation!
+                       // The DNSServiceProcessResult() routine should have invoked our callback,
+                       // and our callback could have terminated the operation with op.stop();
+                       // and that means HaltOperation() will have been called, which frees pContext.
+                       // Basically, from here we just have to get out without touching any stale
+                       // data structures that could blow up on us! Particularly, any attempt
+                       // to loop here reading more results from the file descriptor is unsafe.
                }
        }
+       return err;
 #endif // AUTO_CALLBACKS
 }
 
 
-static void DNSSD_API  ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex, 
-                                                               DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, 
+static void DNSSD_API  ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
+                                                               DNSServiceErrorType errorCode, const char *serviceName, const char *regtype,
                                                                const char *replyDomain, void *context)
 {
        OpContext               *pContext = (OpContext*) context;
@@ -324,9 +346,9 @@ static void DNSSD_API       ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServic
        {
                if ( errorCode == kDNSServiceErr_NoError)
                {
-                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, 
-                                                               ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2, 
-                                                               pContext->JavaObj, flags, interfaceIndex, 
+                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
+                                                               ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
+                                                               pContext->JavaObj, flags, interfaceIndex,
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, regtype),
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
@@ -338,7 +360,7 @@ static void DNSSD_API       ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServic
        TeardownCallbackState();
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *pEnv, jobject pThis, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *pEnv, jobject pThis,
                                                        jint flags, jint ifIndex, jstring regType, jstring domain)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -347,7 +369,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *
        DNSServiceErrorType             err = kDNSServiceErr_NoError;
 
        if ( contextField != 0)
-               pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/BrowseListener;", "serviceFound", 
+               pContext = NewContext( pEnv, pThis, "serviceFound",
                                                                "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
        else
                err = kDNSServiceErr_BadParam;
@@ -357,8 +379,8 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *
                const char      *regStr = SafeGetUTFChars( pEnv, regType);
                const char      *domainStr = SafeGetUTFChars( pEnv, domain);
 
-               pContext->Callback2 = (*pEnv)->GetMethodID( pEnv, 
-                                                               (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj), 
+               pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
+                                                               (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
                                                                "serviceLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
 
                err = DNSServiceBrowse( &pContext->ServiceRef, flags, ifIndex, regStr, domainStr, ServiceBrowseReply, pContext);
@@ -377,8 +399,8 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *
 }
 
 
-static void DNSSD_API  ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex, 
-                                                               DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, 
+static void DNSSD_API  ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
+                                                               DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget,
                                                                uint16_t port, uint16_t txtLen, const char *txtRecord, void *context)
 {
        OpContext               *pContext = (OpContext*) context;
@@ -411,8 +433,8 @@ static void DNSSD_API       ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServi
                        txtObj = (*pContext->Env)->NewObject( pContext->Env, txtCls, txtCtor, txtBytes);
                        (*pContext->Env)->DeleteLocalRef( pContext->Env, txtBytes);
        
-                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback, 
-                                                               pContext->JavaObj, flags, interfaceIndex, 
+                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+                                                               pContext->JavaObj, flags, interfaceIndex,
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, hosttarget),
                                                                port, txtObj);
@@ -424,7 +446,7 @@ static void DNSSD_API       ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServi
        TeardownCallbackState();
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv *pEnv, jobject pThis, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv *pEnv, jobject pThis,
                                                        jint flags, jint ifIndex, jstring serviceName, jstring regType, jstring domain)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -433,7 +455,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv
        DNSServiceErrorType             err = kDNSServiceErr_NoError;
 
        if ( contextField != 0)
-               pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/ResolveListener;", "serviceResolved", 
+               pContext = NewContext( pEnv, pThis, "serviceResolved",
                                                                "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;ILcom/apple/dnssd/TXTRecord;)V");
        else
                err = kDNSServiceErr_BadParam;
@@ -444,7 +466,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv
                const char      *regStr = SafeGetUTFChars( pEnv, regType);
                const char      *domainStr = SafeGetUTFChars( pEnv, domain);
 
-               err = DNSServiceResolve( &pContext->ServiceRef, flags, ifIndex, 
+               err = DNSServiceResolve( &pContext->ServiceRef, flags, ifIndex,
                                                                servStr, regStr, domainStr, ServiceResolveReply, pContext);
                if ( err == kDNSServiceErr_NoError)
                {
@@ -462,8 +484,8 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv
 }
 
 
-static void DNSSD_API  ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, 
-                                                               DNSServiceErrorType errorCode, const char *fullname, 
+static void DNSSD_API  ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags,
+                                                               DNSServiceErrorType errorCode, const char *serviceName,
                                                                const char *regType, const char *domain, void *context)
 {
        OpContext               *pContext = (OpContext*) context;
@@ -474,9 +496,9 @@ static void DNSSD_API       ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServ
        {
                if ( errorCode == kDNSServiceErr_NoError)
                {
-                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback, 
-                                                               pContext->JavaObj, flags, 
-                                                               (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
+                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+                                                               pContext->JavaObj, flags,
+                                                               (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, regType),
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, domain));
                }
@@ -486,8 +508,8 @@ static void DNSSD_API       ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServ
        TeardownCallbackState();
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNIEnv *pEnv, jobject pThis, 
-                                                       jint ifIndex, jint flags, jstring serviceName, jstring regType, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNIEnv *pEnv, jobject pThis,
+                                                       jint ifIndex, jint flags, jstring serviceName, jstring regType,
                                                        jstring domain, jstring host, jint port, jbyteArray txtRecord)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -498,7 +520,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNI
        jsize                                   numBytes;
 
        if ( contextField != 0)
-               pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/RegisterListener;", "serviceRegistered", 
+               pContext = NewContext( pEnv, pThis, "serviceRegistered",
                                                                "(Lcom/apple/dnssd/DNSSDRegistration;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
        else
                err = kDNSServiceErr_BadParam;
@@ -519,7 +541,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNI
                numBytes = txtRecord ? (*pEnv)->GetArrayLength( pEnv, txtRecord) : 0;
 
                err = DNSServiceRegister( &pContext->ServiceRef, flags, ifIndex, servStr, regStr,  
-                                                               domainStr, hostStr, portBits, 
+                                                               domainStr, hostStr, portBits,
                                                                numBytes, pBytes, ServiceRegisterReply, pContext);
                if ( err == kDNSServiceErr_NoError)
                {
@@ -540,7 +562,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNI
        return err;
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv *pEnv, jobject pThis, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv *pEnv, jobject pThis,
                                                        jint flags, jint rrType, jbyteArray rData, jint ttl, jobject destObj)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -573,7 +595,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv
        return err;
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Update( JNIEnv *pEnv, jobject pThis, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Update( JNIEnv *pEnv, jobject pThis,
                                                                                                                jint flags, jbyteArray rData, jint ttl)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -637,7 +659,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Remove( JNIEnv *pEnv,
 }
 
 
-static void DNSSD_API  ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex, 
+static void DNSSD_API  ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
                                                                DNSServiceErrorType errorCode, const char *serviceName,
                                                                uint16_t rrtype, uint16_t rrclass, uint16_t rdlen,
                                                                const void *rdata, uint32_t ttl, void *context)
@@ -658,8 +680,8 @@ static void DNSSD_API       ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSService
                        memcpy( pBytes, rdata, rdlen);
                        (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, rDataObj, pBytes, JNI_COMMIT);
        
-                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback, 
-                                                               pContext->JavaObj, flags, interfaceIndex, 
+                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+                                                               pContext->JavaObj, flags, interfaceIndex,
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
                                                                rrtype, rrclass, rDataObj, ttl);
                }
@@ -669,7 +691,7 @@ static void DNSSD_API       ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSService
        TeardownCallbackState();
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis,
                                                        jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -678,7 +700,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv
        DNSServiceErrorType             err = kDNSServiceErr_NoError;
 
        if ( contextField != 0)
-               pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/QueryListener;", "queryAnswered", 
+               pContext = NewContext( pEnv, pThis, "queryAnswered",
                                                                "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V");
        else
                err = kDNSServiceErr_BadParam;
@@ -687,7 +709,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv
        {
                const char      *servStr = SafeGetUTFChars( pEnv, serviceName);
 
-               err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr, 
+               err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr,
                                                                        rrtype, rrclass, ServiceQueryReply, pContext);
                if ( err == kDNSServiceErr_NoError)
                {
@@ -703,7 +725,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv
 }
 
 
-static void DNSSD_API  DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex, 
+static void DNSSD_API  DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
                                                                DNSServiceErrorType errorCode, const char *replyDomain, void *context)
 {
        OpContext               *pContext = (OpContext*) context;
@@ -714,9 +736,9 @@ static void DNSSD_API       DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFl
        {
                if ( errorCode == kDNSServiceErr_NoError)
                {
-                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, 
-                                                               ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2, 
-                                                               pContext->JavaObj, flags, interfaceIndex, 
+                       (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
+                                                               ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
+                                                               pContext->JavaObj, flags, interfaceIndex,
                                                                (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
                }
                else
@@ -725,7 +747,7 @@ static void DNSSD_API       DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFl
        TeardownCallbackState();
 }
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *pEnv, jobject pThis, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *pEnv, jobject pThis,
                                                        jint flags, jint ifIndex)
 {
        jclass                                  cls = (*pEnv)->GetObjectClass( pEnv, pThis);
@@ -734,18 +756,18 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *p
        DNSServiceErrorType             err = kDNSServiceErr_NoError;
 
        if ( contextField != 0)
-               pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/DomainListener;", "domainFound", 
+               pContext = NewContext( pEnv, pThis, "domainFound",
                                                                "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
        else
                err = kDNSServiceErr_BadParam;
 
        if ( pContext != NULL)
        {
-               pContext->Callback2 = (*pEnv)->GetMethodID( pEnv, 
-                                                               (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj), 
+               pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
+                                                               (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
                                                                "domainLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
 
-               err = DNSServiceEnumerateDomains( &pContext->ServiceRef, flags, ifIndex, 
+               err = DNSServiceEnumerateDomains( &pContext->ServiceRef, flags, ifIndex,
                                                                                        DomainEnumReply, pContext);
                if ( err == kDNSServiceErr_NoError)
                {
@@ -759,7 +781,7 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *p
 }
 
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pEnv, jobject pThis _UNUSED, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pEnv, jobject pThis _UNUSED,
                                                        jstring serviceName, jstring regtype, jstring domain, jobjectArray pOut)
 {
        DNSServiceErrorType             err = kDNSServiceErr_NoError;
@@ -783,8 +805,8 @@ JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pE
        return err;
 }
 
-JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *pEnv, jobject pThis _UNUSED, 
-                                                       jint flags, jint ifIndex, jstring fullName, 
+JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *pEnv, jobject pThis _UNUSED,
+                                                       jint flags, jint ifIndex, jstring fullName,
                                                        jint rrtype, jint rrclass, jbyteArray rdata)
 {
        jbyte                                   *pBytes;
@@ -804,7 +826,7 @@ JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *
 
 #define LOCAL_ONLY_NAME "loo"
 
-JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNIEnv *pEnv, jobject pThis _UNUSED, 
+JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNIEnv *pEnv, jobject pThis _UNUSED,
                                                        jint ifIndex)
 {
        char                                    *p = LOCAL_ONLY_NAME, nameBuff[IF_NAMESIZE];
@@ -816,7 +838,7 @@ JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNI
 }
 
 
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName( JNIEnv *pEnv, jobject pThis _UNUSED, 
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName( JNIEnv *pEnv, jobject pThis _UNUSED,
                                                        jstring ifName)
 {
        uint32_t                                ifIndex = kDNSServiceInterfaceIndexLocalOnly;
index 6ec40da052ad9c2a8856cb36a3e852db4e4f1d79..3baee26c699bb4c746625fd3f1c303c5b2bc9240 100644 (file)
     Change History (most recent first):
 
 $Log: PlatformCommon.c,v $
-Revision 1.6  2005/04/08 21:30:16  ksekar
-<rdar://problem/4007457> Compiling problems with mDNSResponder-98 on Solaris/Sparc v9
-Patch submitted by Bernd Kuhls
-
 Revision 1.5  2005/02/01 19:33:30  ksekar
 <rdar://problem/3985239> Keychain format too restrictive
 
@@ -48,7 +44,7 @@ Move ReadDDNSSettingsFromConfFile() from mDNSMacOSX.c to PlatformCommon.c
 #include <stdio.h>                             // Needed for fopen() etc.
 #include <unistd.h>                            // Needed for close()
 #include <string.h>                            // Needed for strlen() etc.
-#include <errno.h>                     // Needed for errno etc.
+#include <sys/errno.h>                 // Needed for errno etc.
 #include <sys/socket.h>                        // Needed for socket() etc.
 #include <netinet/in.h>                        // Needed for sockaddr_in
 
index fa18cce743257ce9dac49ffc5ec66af445fa04d1..81e0856d9a42f76856ec5e51563804b1a440ea33 100755 (executable)
 #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;
 typedef UINT16      uint16_t;
 typedef INT16       int16_t;
 typedef UINT32      uint32_t;
 typedef INT32       int32_t;
-#endif
 #else
 #include <stdint.h>
 #endif
index 6284b1e388170b1666fed01d5d72147fdea12b03..40ab0d0edbdbbf4a9c067e4e5f2c0bfcfe4f5fd4 100755 (executable)
@@ -27,9 +27,6 @@
    Change History (most recent first):
 
 $Log: dnssd_clientlib.c,v $
-Revision 1.10  2005/04/06 02:06:56  shersche
-Add DNSSD_API macro to TXTRecord API calls
-
 Revision 1.9  2004/10/06 02:22:19  cheshire
 Changed MacRoman copyright symbol (should have been UTF-8 in any case :-) to ASCII-compatible "(c)"
 
@@ -199,7 +196,7 @@ struct dnssd_clientlib_CompileTimeAssertionCheck
        char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
        };
 
-void DNSSD_API TXTRecordCreate
+void TXTRecordCreate
        (
        TXTRecordRef     *txtRecord,
        uint16_t         bufferLen,
@@ -212,12 +209,12 @@ void DNSSD_API TXTRecordCreate
        txtRec->malloced = 0;
        }
 
-void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
+void TXTRecordDeallocate(TXTRecordRef *txtRecord)
        {
        if (txtRec->malloced) free(txtRec->buffer);
        }
 
-DNSServiceErrorType DNSSD_API TXTRecordSetValue
+DNSServiceErrorType TXTRecordSetValue
        (
        TXTRecordRef     *txtRecord,
        const char       *key,
@@ -262,7 +259,7 @@ DNSServiceErrorType DNSSD_API TXTRecordSetValue
        return(kDNSServiceErr_NoError);
        }
 
-DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
+DNSServiceErrorType TXTRecordRemoveValue
        (
        TXTRecordRef     *txtRecord,
        const char       *key
@@ -279,8 +276,8 @@ DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
        return(kDNSServiceErr_NoError);
        }
 
-uint16_t DNSSD_API TXTRecordGetLength  (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
-const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
+uint16_t       TXTRecordGetLength  (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
+const void *   TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
 
 /*********************************************************************************************
  *
@@ -288,7 +285,7 @@ const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { ret
  *
  *********************************************************************************************/
 
-int DNSSD_API TXTRecordContainsKey
+int TXTRecordContainsKey
        (
        uint16_t         txtLen,
        const void       *txtRecord,
@@ -299,7 +296,7 @@ int DNSSD_API TXTRecordContainsKey
        return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
        }
 
-const void * DNSSD_API TXTRecordGetValuePtr
+const void * TXTRecordGetValuePtr
        (
        uint16_t         txtLen,
        const void       *txtRecord,
@@ -314,7 +311,7 @@ const void * DNSSD_API TXTRecordGetValuePtr
        return (item + 1 + keylen + 1);
        }
 
-uint16_t DNSSD_API TXTRecordGetCount
+uint16_t TXTRecordGetCount
        (
        uint16_t         txtLen,
        const void       *txtRecord
@@ -327,7 +324,7 @@ uint16_t DNSSD_API TXTRecordGetCount
        return((p>e) ? (uint16_t)0 : count);
        }
 
-DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
+DNSServiceErrorType TXTRecordGetItemAtIndex
        (
        uint16_t         txtLen,
        const void       *txtRecord,
index ffc7111588707f7e614c8ff4b981139ee76d078e..8cf98d32bae83e344404bf7c1ad0715f625f45fc 100755 (executable)
     Change History (most recent first):
 
 $Log: dnssd_clientstub.c,v $
-Revision 1.47  2005/03/31 02:19:56  cheshire
-<rdar://problem/4021486> Fix build warnings
-Reviewed by: Scott Herscher
-
-Revision 1.46  2005/03/21 00:39:31  shersche
-<rdar://problem/4021486> Fix build warnings on Win32 platform
-
 Revision 1.45  2005/02/01 01:25:06  shersche
 Define sleep() to be Sleep() for Windows compatibility
 
@@ -273,9 +266,7 @@ static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int
     char *msg = NULL;
     ipc_msg_hdr *hdr;
     int datalen;
-#if !defined(USE_TCP_LOOPBACK)
     char ctrl_path[256];
-#endif
 
     if (!reuse_socket)
         {
@@ -378,7 +369,7 @@ static DNSServiceErrorType deliver_request(void *msg, DNSServiceRef sdr, int reu
     char *data = (char *)msg + sizeof(ipc_msg_hdr);
     dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
        int ret;
-       dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
+       unsigned int len = sizeof(caddr);
     DNSServiceErrorType err = kDNSServiceErr_Unknown;
 
     if (!hdr || sdr->sockfd < 0) return kDNSServiceErr_Unknown;
index 9dc98e44e153140436a830b8ff50595498dc4f49..406b7ab520ed7370d002c22789cbbcd0097d0937 100644 (file)
@@ -24,6 +24,9 @@
     Change History (most recent first):
 
 $Log: uds_daemon.c,v $
+Revision 1.183  2005/06/13 22:39:11  cheshire
+<rdar://problem/4144870> Missing return statement in handle_enum_request() error handling
+
 Revision 1.182  2005/03/21 00:39:31  shersche
 <rdar://problem/4021486> Fix build warnings on Win32 platform
 
@@ -2890,6 +2893,7 @@ static void handle_enum_request(request_state *rstate)
                deliver_error(rstate, mStatus_BadParamErr);
                abort_request(rstate);
                unlink_request(rstate);
+               return;
        }
 
     // allocate context structures
diff --git a/mDNSVxWorks/mDNSVxWorksIPv4Only.c b/mDNSVxWorks/mDNSVxWorksIPv4Only.c
new file mode 100644 (file)
index 0000000..d8c2824
--- /dev/null
@@ -0,0 +1,2193 @@
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+       Contains:       mDNS platform plugin for VxWorks.
+
+       Copyright:  Copyright (C) 2002-2004 Apple Computer, Inc., All Rights Reserved.
+
+       Change History (most recent first):
+
+$Log: mDNSVxWorksIPv4Only.c,v $
+Revision 1.27  2004/12/17 23:37:49  cheshire
+<rdar://problem/3485365> Guard against repeating wireless dissociation/re-association
+(and other repetitive configuration changes)
+
+Revision 1.26  2004/10/28 02:00:35  cheshire
+<rdar://problem/3841770> Call pipeDevDelete when disposing of commandPipe
+
+Revision 1.25  2004/10/16 00:17:01  cheshire
+<rdar://problem/3770558> Replace IP TTL 255 check with local subnet source address check
+
+Revision 1.24  2004/09/21 21:02:56  cheshire
+Set up ifname before calling mDNS_RegisterInterface()
+
+Revision 1.23  2004/09/17 01:08:57  cheshire
+Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
+  The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
+  declared in that file are ONLY appropriate to single-address-space embedded applications.
+  For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
+
+Revision 1.22  2004/09/17 00:19:11  cheshire
+For consistency with AllDNSLinkGroupv6, rename AllDNSLinkGroup to AllDNSLinkGroupv4
+
+Revision 1.21  2004/09/16 00:24:50  cheshire
+<rdar://problem/3803162> Fix unsafe use of mDNSPlatformTimeNow()
+
+Revision 1.20  2004/09/14 23:42:36  cheshire
+<rdar://problem/3801296> Need to seed random number generator from platform-layer data
+
+Revision 1.19  2004/09/14 23:16:09  cheshire
+mDNS_SetFQDNs has been renamed to mDNS_SetFQDN
+
+Revision 1.18  2004/08/14 03:22:42  cheshire
+<rdar://problem/3762579> Dynamic DNS UI <-> mDNSResponder glue
+Add GetUserSpecifiedDDNSName() routine
+Convert ServiceRegDomain to domainname instead of C string
+Replace mDNS_GenerateFQDN/mDNS_GenerateGlobalFQDN with mDNS_SetFQDNs
+
+Revision 1.17  2004/07/29 19:26:03  ksekar
+Plaform-level changes for NATPMP support
+
+Revision 1.16  2004/04/22 05:11:28  bradley
+Added mDNSPlatformUTC for TSIG signed dynamic updates.
+
+Revision 1.15  2004/04/21 02:49:12  cheshire
+To reduce future confusion, renamed 'TxAndRx' to 'McastTxRx'
+
+Revision 1.14  2004/04/09 17:43:04  cheshire
+Make sure to set the McastTxRx field so that duplicate suppression works correctly
+
+Revision 1.13  2004/01/27 20:15:24  cheshire
+<rdar://problem/3541288>: Time to prune obsolete code for listening on port 53
+
+Revision 1.12  2004/01/24 09:12:37  bradley
+Avoid TOS socket options to workaround a TOS routing problem with VxWorks and multiple interfaces
+when sending unicast responses, which resulted in packets going out the wrong interface.
+
+Revision 1.11  2004/01/24 04:59:16  cheshire
+Fixes so that Posix/Linux, OS9, Windows, and VxWorks targets build again
+
+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.
+
+Revision 1.9  2003/11/14 20:59:09  cheshire
+Clients can't use AssignDomainName macro because mDNSPlatformMemCopy is defined in mDNSPlatformFunctions.h.
+Best solution is just to combine mDNSEmbeddedAPI.h and mDNSPlatformFunctions.h into a single file.
+
+Revision 1.8  2003/10/28 10:08:27  bradley
+Removed legacy port 53 support as it is no longer needed.
+
+Revision 1.7  2003/08/20 05:58:54  bradley
+Removed dependence on modified mDNSCore: define structures/prototypes locally.
+
+Revision 1.6  2003/08/18 23:19:05  cheshire
+<rdar://problem/3382647> mDNSResponder divide by zero in mDNSPlatformRawTime()
+
+Revision 1.5  2003/08/15 00:05:04  bradley
+Updated to use name/InterfaceID from new AuthRecord resrec field. Added output of new record sizes.
+
+Revision 1.4  2003/08/14 02:19:55  cheshire
+<rdar://problem/3375491> Split generic ResourceRecord type into two separate types: AuthRecord and CacheRecord
+
+Revision 1.3  2003/08/12 19:56:27  cheshire
+Update to APSL 2.0
+
+Revision 1.2  2003/08/05 23:58:34  cheshire
+Update code to compile with the new mDNSCoreReceive() function that requires a TTL
+Right now this platform layer just reports 255 instead of returning the real value -- we should fix this
+
+Revision 1.1  2003/08/02 10:06:48  bradley
+mDNS platform plugin for VxWorks.
+
+
+       Notes for non-Apple platforms:
+
+               TARGET_NON_APPLE should be defined to 1 to avoid relying on Apple-only header files, macros, or functions.
+
+       To Do:
+
+               - Add support for IPv6 (needs VxWorks IPv6 support).
+*/
+
+// Set up the debug library to use the default category (see DebugServicesLite.h for details).
+
+#if( !TARGET_NON_APPLE )
+       #define DEBUG_USE_DEFAULT_CATEGORY              1
+#endif
+
+#include       <stdarg.h>
+#include       <stddef.h>
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       <sys/types.h>
+#include       <arpa/inet.h>
+#include       <fcntl.h>
+#include       <netinet/if_ether.h>
+#include       <netinet/in.h>
+#include       <netinet/ip.h>
+#include       <sys/ioctl.h>
+#include       <sys/socket.h>
+#include       <unistd.h>
+
+#include       "vxWorks.h"
+#include       "ifLib.h"
+#include       "inetLib.h"
+#include       "pipeDrv.h"
+#include       "selectLib.h"
+#include       "semLib.h"
+#include       "sockLib.h"
+#include       "sysLib.h"
+#include       "taskLib.h"
+#include       "tickLib.h"
+
+#include       "config.h"
+
+#if( !TARGET_NON_APPLE )
+       #include        "ACP/ACPUtilities.h"
+       #include        "Support/DebugServicesLite.h"
+       #include        "Support/MiscUtilities.h"
+#endif
+
+#include       "mDNSEmbeddedAPI.h"
+
+#include       "mDNSVxWorks.h"
+
+#if 0
+#pragma mark == Preprocessor ==
+#endif
+
+//===========================================================================================================================
+//     Preprocessor
+//===========================================================================================================================
+
+#if( !TARGET_NON_APPLE )
+       debug_log_new_default_category( mdns );
+#endif
+
+#if 0
+#pragma mark == Constants ==
+#endif
+
+//===========================================================================================================================
+//     Constants
+//===========================================================================================================================
+
+#define        DEBUG_NAME                                              "[mDNS] "
+
+#define        kMDNSDefaultName                                "My-Device"
+
+#define        kMDNSTaskName                                   "tMDNS"
+#define        kMDNSTaskPriority                               102
+#define        kMDNSTaskStackSize                              49152
+
+#define        kMDNSPipeName                                   "/pipe/mDNS"
+#define        kMDNSPipeMessageQueueSize               32
+#define        kMDNSPipeMessageSize                    1
+
+#define        kInvalidSocketRef                               -1
+
+typedef uint8_t                MDNSPipeCommandCode;
+enum
+{
+       kMDNSPipeCommandCodeInvalid                     = 0, 
+       kMDNSPipeCommandCodeReschedule          = 1, 
+       kMDNSPipeCommandCodeReconfigure         = 2, 
+       kMDNSPipeCommandCodeQuit                        = 3
+};
+
+#if 0
+#pragma mark == Structures ==
+#endif
+
+//===========================================================================================================================
+//     Structures
+//===========================================================================================================================
+
+typedef int            MDNSSocketRef;
+
+struct MDNSInterfaceItem
+{
+       MDNSInterfaceItem *                     next;
+       char                                            name[ 32 ];
+       MDNSSocketRef                           multicastSocketRef;
+       MDNSSocketRef                           sendingSocketRef;
+       NetworkInterfaceInfo            hostSet;
+       mDNSBool                                        hostRegistered;
+       
+       int                                                     sendMulticastCounter;
+       int                                                     sendUnicastCounter;
+       int                                                     sendErrorCounter;
+       
+       int                                                     recvCounter;
+       int                                                     recvErrorCounter;
+       int                                                     recvLoopCounter;
+};
+
+#if 0
+#pragma mark == Macros ==
+#endif
+
+//===========================================================================================================================
+//     Macros
+//===========================================================================================================================
+
+#if( TARGET_NON_APPLE )
+       
+       // Do-nothing versions of the debugging macros for non-Apple platforms.
+       
+       #define check(assertion)
+       #define check_string( assertion, cstring )
+       #define check_noerr(err)
+       #define check_noerr_string( error, cstring )
+       #define check_errno( assertion, errno_value )
+       #define debug_string( cstring )
+       #define require( assertion, label )                                             do { if( !(assertion) ) goto label; } while(0)
+       #define require_string( assertion, label, string )                                              require(assertion, label)
+       #define require_quiet( assertion, label )                                                               require( assertion, label )
+       #define require_noerr( error, label )                                                                   do { if( (error) != 0 ) goto label; } while(0)
+       #define require_noerr_quiet( assertion, label )                                                 require_noerr( assertion, label )
+       #define require_noerr_action( error, label, action )                                    do { if( (error) != 0 ) { {action;}; goto label; } } while(0)
+       #define require_noerr_action_quiet( assertion, label, action )                  require_noerr_action( assertion, label, action )
+       #define require_action( assertion, label, action )                                              do { if( !(assertion) ) { {action;}; goto label; } } while(0)
+       #define require_action_quiet( assertion, label, action )                                require_action( assertion, label, action )
+       #define require_action_string( assertion, label, action, cstring )              do { if( !(assertion) ) { {action;}; goto label; } } while(0)
+       #define require_errno( assertion, errno_value, label )                                  do { if( !(assertion) ) goto label; } while(0)
+       #define require_errno_action( assertion, errno_value, label, action )   do { if( !(assertion) ) { {action;}; goto label; } } while(0)
+       
+       #define dlog( ARGS... )
+       
+       #define DEBUG_UNUSED( X )                       (void)( X )
+#endif
+
+#if 0
+#pragma mark == Prototypes ==
+#endif
+
+//===========================================================================================================================
+//     Prototypes
+//===========================================================================================================================
+
+// ifIndexToIfp is in net/if.c, but not exported by net/if.h so provide it here.
+
+extern struct ifnet * ifIndexToIfp(int ifIndex);
+
+// Platform Internals
+
+mDNSlocal void         SetupNames( mDNS * const inMDNS );
+mDNSlocal mStatus      SetupInterfaceList( mDNS * const inMDNS );
+mDNSlocal mStatus      TearDownInterfaceList( mDNS * const inMDNS );
+mDNSlocal mStatus      SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inAddr, MDNSInterfaceItem **outItem );
+mDNSlocal mStatus      TearDownInterface( mDNS * const inMDNS, MDNSInterfaceItem *inItem );
+mDNSlocal mStatus
+       SetupSocket( 
+               mDNS * const                    inMDNS, 
+               const struct ifaddrs *  inAddr, 
+               mDNSIPPort                              inPort, 
+               MDNSSocketRef *                 outSocketRef );
+
+// Commands
+
+mDNSlocal mStatus      SetupCommandPipe( mDNS * const inMDNS );
+mDNSlocal mStatus      TearDownCommandPipe( mDNS * const inMDNS );
+mDNSlocal mStatus      SendCommand( const mDNS * const inMDNS, MDNSPipeCommandCode inCommandCode );
+mDNSlocal mStatus      ProcessCommand( mDNS * const inMDNS );
+mDNSlocal void         ProcessCommandReconfigure( mDNS *inMDNS );
+
+// Threads
+
+mDNSlocal mStatus      SetupTask( mDNS * const inMDNS );
+mDNSlocal mStatus      TearDownTask( mDNS * const inMDNS );
+mDNSlocal void         Task( mDNS *inMDNS );
+mDNSlocal mStatus      TaskInit( mDNS *inMDNS );
+mDNSlocal void         TaskSetupReadSet( mDNS *inMDNS, fd_set *outReadSet, int *outMaxSocket );
+mDNSlocal void         TaskSetupTimeout( mDNS *inMDNS, mDNSs32 inNextTaskTime, struct timeval *outTimeout );
+mDNSlocal void         TaskProcessPacket( mDNS *inMDNS, MDNSInterfaceItem *inItem, MDNSSocketRef inSocketRef );
+
+// Utilities
+
+#if( TARGET_NON_APPLE )
+       mDNSlocal void  GenerateUniqueHostName( char *outName, long *ioSeed );
+       mDNSlocal void  GenerateUniqueDNSName( char *outName, long *ioSeed );
+#endif
+
+// Platform Accessors
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+typedef struct mDNSPlatformInterfaceInfo       mDNSPlatformInterfaceInfo;
+struct mDNSPlatformInterfaceInfo
+{
+       const char *            name;
+       mDNSAddr                        ip;
+};
+
+mDNSexport mStatus     mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID );
+mDNSexport mStatus     mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo );
+
+#ifdef __cplusplus
+       }
+#endif
+
+#if 0
+#pragma mark == Globals ==
+#endif
+
+//===========================================================================================================================
+//     Globals
+//===========================================================================================================================
+
+mDNSlocal mDNS *                                       gMDNSPtr                                                        = NULL;
+mDNSlocal mDNS_PlatformSupport         gMDNSPlatformSupport;
+mDNSlocal mDNSs32                                      gMDNSTicksToMicrosecondsMultiplier      = 0;
+
+// Platform support
+
+mDNSs32                                                                mDNSPlatformOneSecond;
+
+#if 0
+#pragma mark -
+#pragma mark == Public APIs ==
+#endif
+
+//===========================================================================================================================
+//     mDNSReconfigure
+//===========================================================================================================================
+
+void   mDNSReconfigure( void )
+{
+       // Send a "reconfigure" command to the MDNS task.
+       
+       if( gMDNSPtr )
+       {
+               SendCommand( gMDNSPtr, kMDNSPipeCommandCodeReconfigure );
+       }
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Platform Support ==
+#endif
+
+//===========================================================================================================================
+//     mDNSPlatformInit
+//===========================================================================================================================
+
+mStatus        mDNSPlatformInit( mDNS * const inMDNS )
+{
+       mStatus         err;
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "platform init\n" );
+       
+       // Initialize variables.
+
+       memset( &gMDNSPlatformSupport, 0, sizeof( gMDNSPlatformSupport ) );
+       inMDNS->p                                                       = &gMDNSPlatformSupport;
+       inMDNS->p->commandPipe                          = ERROR;
+       inMDNS->p->task                                         = ERROR;
+       inMDNS->p->rescheduled                          = 1;            // Default to rescheduled until fully initialized.
+       mDNSPlatformOneSecond                           = sysClkRateGet();
+       gMDNSTicksToMicrosecondsMultiplier      = ( 1000000L / mDNSPlatformOneSecond );
+       
+       // Allocate semaphores.
+       
+       inMDNS->p->lockID = semMCreate( SEM_Q_FIFO );
+       require_action( inMDNS->p->lockID, exit, err = mStatus_NoMemoryErr );
+       
+       inMDNS->p->readyEvent = semBCreate( SEM_Q_FIFO, SEM_EMPTY );
+       require_action( inMDNS->p->readyEvent, exit, err = mStatus_NoMemoryErr );
+       
+       inMDNS->p->quitEvent = semBCreate( SEM_Q_FIFO, SEM_EMPTY );
+       require_action( inMDNS->p->quitEvent, exit, err = mStatus_NoMemoryErr );
+       
+       gMDNSPtr = inMDNS;
+       
+       // Set up the task and wait for it to initialize. Initialization is done from the task instead of here to avoid 
+       // stack space issues. Some of the initialization may require a larger stack than the current task supports.
+       
+       err = SetupTask( inMDNS );
+       require_noerr( err, exit );
+       
+       err = semTake( inMDNS->p->readyEvent, WAIT_FOREVER );
+       require_noerr( err, exit );
+       err = inMDNS->p->taskInitErr;
+       require_noerr( err, exit );
+       
+       mDNSCoreInitComplete( inMDNS, err );
+       
+exit:
+       if( err )
+       {
+               mDNSPlatformClose( inMDNS );
+       }
+       dlog( kDebugLevelInfo, DEBUG_NAME "platform init done (err=%ld)\n", err );
+       return( err );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformClose
+//===========================================================================================================================
+
+void   mDNSPlatformClose( mDNS * const inMDNS )
+{
+       mStatus         err;
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "platform close\n" );
+       check( inMDNS );
+       
+       // Tear everything down.
+       
+       err = TearDownTask( inMDNS );
+       check_noerr( err );
+       
+       err = TearDownInterfaceList( inMDNS );
+       check_noerr( err );
+               
+       err = TearDownCommandPipe( inMDNS );
+       check_noerr( err );
+       
+       gMDNSPtr = NULL;
+       
+       // Release semaphores.
+       
+       if( inMDNS->p->quitEvent )
+       {
+               semDelete( inMDNS->p->quitEvent );
+               inMDNS->p->quitEvent = 0;
+       }
+       if( inMDNS->p->readyEvent )
+       {
+               semDelete( inMDNS->p->readyEvent );
+               inMDNS->p->readyEvent = 0;
+       }
+       if( inMDNS->p->lockID )
+       {
+               semDelete( inMDNS->p->lockID );
+               inMDNS->p->lockID = 0;
+       }
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "platform close done\n" );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformSendUDP
+//===========================================================================================================================
+
+mStatus
+       mDNSPlatformSendUDP( 
+               const mDNS * const                      inMDNS, 
+               const void * const              inMsg, 
+               const mDNSu8 * const            inMsgEnd, 
+               mDNSInterfaceID                         inInterfaceID, 
+               const mDNSAddr *                        inDstIP, 
+               mDNSIPPort                                      inDstPort )
+{
+       mStatus                                 err;
+       MDNSInterfaceItem *             item;
+       struct sockaddr_in              addr;
+       int                                             n;
+       
+       dlog( kDebugLevelChatty, DEBUG_NAME "platform send UDP\n" );
+       
+       // Check parameters.
+       
+       check( inMDNS );
+       check( inMsg );
+       check( inMsgEnd );
+       check( inInterfaceID );
+       check( inDstIP );
+       if( inDstIP->type != mDNSAddrType_IPv4 )
+       {
+               err = mStatus_BadParamErr;
+               goto exit;
+       }
+
+#if( DEBUG )
+       // Make sure the InterfaceID is valid.
+       
+       for( item = inMDNS->p->interfaceList; item; item = item->next )
+       {
+               if( item == (MDNSInterfaceItem *) inInterfaceID )
+               {
+                       break;
+               }
+       }
+       require_action( item, exit, err = mStatus_NoSuchNameErr );
+#endif
+
+       // Send the packet.
+       
+       item = (MDNSInterfaceItem *) inInterfaceID;
+       check( item->sendingSocketRef != kInvalidSocketRef );
+       
+       memset( &addr, 0, sizeof( addr ) );
+       addr.sin_family                 = AF_INET;
+       addr.sin_port                   = inDstPort.NotAnInteger;
+       addr.sin_addr.s_addr    = inDstIP->ip.v4.NotAnInteger;
+       
+       n = inMsgEnd - ( (const mDNSu8 * const) inMsg );
+       n = sendto( item->sendingSocketRef, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
+       check_errno( n, errno );
+       
+       item->sendErrorCounter          += ( n < 0 );
+       item->sendMulticastCounter      += ( inDstPort.NotAnInteger == MulticastDNSPort.NotAnInteger );
+       item->sendUnicastCounter        += ( inDstPort.NotAnInteger != MulticastDNSPort.NotAnInteger );
+       
+       dlog( kDebugLevelChatty, DEBUG_NAME "sent (to=%u.%u.%u.%u:%hu)\n", 
+                 inDstIP->ip.v4.b[ 0 ], inDstIP->ip.v4.b[ 1 ], inDstIP->ip.v4.b[ 2 ], inDstIP->ip.v4.b[ 3 ], 
+                 htons( inDstPort.NotAnInteger ) );
+       err = mStatus_NoError;
+
+exit:
+       dlog( kDebugLevelChatty, DEBUG_NAME "platform send UDP done\n" );
+       return( err );
+}
+
+//===========================================================================================================================
+//     Connection-oriented (TCP) functions
+//===========================================================================================================================
+
+mDNSexport mStatus mDNSPlatformTCPConnect(const mDNSAddr *dst, mDNSOpaque16 dstport, mDNSInterfaceID InterfaceID,
+                                                                                 TCPConnectionCallback callback, void *context, int *descriptor)
+       {
+       (void)dst;                      // Unused
+       (void)dstport;          // Unused
+       (void)InterfaceID;      // Unused
+       (void)callback;         // Unused
+       (void)context;          // Unused
+       (void)descriptor;       // Unused
+       return(mStatus_UnsupportedErr);
+       }
+
+mDNSexport void mDNSPlatformTCPCloseConnection(int sd)
+       {
+       (void)sd;                       // Unused
+       }
+
+mDNSexport int mDNSPlatformReadTCP(int sd, void *buf, int buflen)
+       {
+       (void)sd;                       // Unused
+       (void)buf;                      // Unused
+       (void)buflen;                   // Unused
+       return(0);
+       }
+
+mDNSexport int mDNSPlatformWriteTCP(int sd, const char *msg, int len)
+       {
+       (void)sd;                       // Unused
+       (void)msg;                      // Unused
+       (void)len;                      // Unused
+       return(0);
+       }
+
+//===========================================================================================================================
+//     mDNSPlatformLock
+//===========================================================================================================================
+
+void   mDNSPlatformLock( const mDNS * const inMDNS )
+{
+       check( inMDNS->p->lockID );
+       
+       if( inMDNS->p->lockID )
+       {
+               #if( TARGET_NON_APPLE )
+                       semTake( inMDNS->p->lockID, WAIT_FOREVER );
+               #else
+                       semTakeDeadlockDetect( inMDNS->p->lockID, WAIT_FOREVER );
+               #endif
+       }
+}
+
+//===========================================================================================================================
+//     mDNSPlatformUnlock
+//===========================================================================================================================
+
+void   mDNSPlatformUnlock( const mDNS * const inMDNS )
+{
+       check( inMDNS );
+       check( inMDNS->p );
+       check( inMDNS->p->lockID );
+       check_string( inMDNS->p->task != ERROR, "mDNS task not started" );
+       
+       // When an API routine is called, "m->NextScheduledEvent" is reset to "timenow" before calling mDNSPlatformUnlock()
+       // Since our main mDNS_Execute() loop is on a different thread, we need to wake up that thread to:
+       // (a) handle immediate work (if any) resulting from this API call
+       // (b) calculate the next sleep time between now and the next interesting event
+       
+       if( ( mDNS_TimeNow(inMDNS) - inMDNS->NextScheduledEvent ) >= 0 )
+       {
+               // We only need to send the reschedule event when called from a task other than the mDNS task since if we are 
+               // called from mDNS task, we'll loop back and call mDNS_Execute. This avoids filling up the command queue.
+               
+               if( ( inMDNS->p->rescheduled++ == 0 ) && ( taskIdSelf() != inMDNS->p->task ) )
+               {
+                       SendCommand( inMDNS, kMDNSPipeCommandCodeReschedule );
+               }
+       }
+       
+       if( inMDNS->p->lockID )
+       {
+               semGive( inMDNS->p->lockID );
+       }
+}
+
+//===========================================================================================================================
+//     mDNSPlatformStrLen
+//===========================================================================================================================
+
+mDNSu32  mDNSPlatformStrLen( const void *inSrc )
+{
+       check( inSrc );
+       
+       return( (mDNSu32) strlen( (const char *) inSrc ) );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformStrCopy
+//===========================================================================================================================
+
+void   mDNSPlatformStrCopy( const void *inSrc, void *inDst )
+{
+       check( inSrc );
+       check( inDst );
+       
+       strcpy( (char *) inDst, (const char*) inSrc );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformMemCopy
+//===========================================================================================================================
+
+void   mDNSPlatformMemCopy( const void *inSrc, void *inDst, mDNSu32 inSize )
+{
+       check( inSrc );
+       check( inDst );
+       
+       memcpy( inDst, inSrc, inSize );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformMemSame
+//===========================================================================================================================
+
+mDNSBool       mDNSPlatformMemSame( const void *inSrc, const void *inDst, mDNSu32 inSize )
+{
+       check( inSrc );
+       check( inDst );
+       
+       return( memcmp( inSrc, inDst, inSize ) == 0 );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformMemZero
+//===========================================================================================================================
+
+void   mDNSPlatformMemZero( void *inDst, mDNSu32 inSize )
+{
+       check( inDst );
+       
+       memset( inDst, 0, inSize );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformMemAllocate
+//===========================================================================================================================
+
+mDNSexport void *      mDNSPlatformMemAllocate( mDNSu32 inSize )
+{
+       void *          mem;
+       
+       check( inSize > 0 );
+       
+       mem = malloc( inSize );
+       check( mem );
+       
+       return( mem );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformMemFree
+//===========================================================================================================================
+
+mDNSexport void        mDNSPlatformMemFree( void *inMem )
+{
+       check( inMem );
+       
+       free( inMem );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformRandomSeed
+//===========================================================================================================================
+
+mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
+{
+       return( tickGet() );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformTimeInit
+//===========================================================================================================================
+
+mDNSexport mStatus mDNSPlatformTimeInit( void )
+{
+       // No special setup is required on VxWorks -- we just use tickGet().
+       return( mStatus_NoError );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformRawTime
+//===========================================================================================================================
+
+mDNSs32        mDNSPlatformRawTime( void )
+{
+       return( (mDNSs32) tickGet() );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformUTC
+//===========================================================================================================================
+
+mDNSexport mDNSs32     mDNSPlatformUTC( void )
+{
+       return( -1 );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformInterfaceNameToID
+//===========================================================================================================================
+
+mStatus        mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID )
+{
+       mStatus                                 err;
+       MDNSInterfaceItem *             ifd;
+       
+       check( inMDNS );
+       check( inMDNS->p );
+       check( inName );
+       
+       // Search for an interface with the specified name,
+       
+       for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
+       {
+               if( strcmp( ifd->name, inName ) == 0 )
+               {
+                       break;
+               }
+       }
+       if( !ifd )
+       {
+               err = mStatus_NoSuchNameErr;
+               goto exit;
+       }
+               
+       // Success!
+       
+       if( outID )
+       {
+               *outID = (mDNSInterfaceID) ifd;
+       }
+       err = mStatus_NoError;
+       
+exit:
+       return( err );
+}
+
+//===========================================================================================================================
+//     mDNSPlatformInterfaceIDToInfo
+//===========================================================================================================================
+
+mStatus        mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo )
+{
+       mStatus                                 err;
+       MDNSInterfaceItem *             ifd;
+       
+       check( inMDNS );
+       check( inID );
+       check( outInfo );
+       
+       // Search for an interface with the specified ID,
+       
+       for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
+       {
+               if( ifd == (MDNSInterfaceItem *) inID )
+               {
+                       break;
+               }
+       }
+       if( !ifd )
+       {
+               err = mStatus_NoSuchNameErr;
+               goto exit;
+       }
+       
+       // Success!
+       
+       outInfo->name   = ifd->name;
+       outInfo->ip     = ifd->hostSet.ip;
+       err                     = mStatus_NoError;
+       
+exit:
+       return( err );
+}
+
+//===========================================================================================================================
+//     debugf_
+//===========================================================================================================================
+
+#if( MDNS_DEBUGMSGS )
+mDNSexport void debugf_( const char *format, ... )
+{
+       char            buffer[ 512 ];
+    va_list            args;
+    mDNSu32            length;
+    
+       va_start( args, format );
+       length = mDNS_vsnprintf( buffer, sizeof( buffer ), format, args );
+       va_end( args );
+
+       dlog( kDebugLevelInfo, "%s\n", buffer );
+}
+#endif
+
+//===========================================================================================================================
+//     verbosedebugf_
+//===========================================================================================================================
+
+#if( MDNS_DEBUGMSGS > 1 )
+mDNSexport void verbosedebugf_( const char *format, ... )
+{
+       char            buffer[ 512 ];
+    va_list            args;
+    mDNSu32            length;
+    
+       va_start( args, format );
+       length = mDNS_vsnprintf( buffer, sizeof( buffer ), format, args );
+       va_end( args );
+       
+       dlog( kDebugLevelVerbose, "%s\n", buffer );
+}
+#endif
+
+//===========================================================================================================================
+//     LogMsg
+//===========================================================================================================================
+
+void LogMsg( const char *inFormat, ... )
+{
+       char            buffer[ 512 ];
+    va_list            args;
+    mDNSu32            length;
+       
+       va_start( args, inFormat );
+       length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
+       va_end( args );
+       
+       dlog( kDebugLevelWarning, "%s\n", buffer );
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Platform Internals ==
+#endif
+
+//===========================================================================================================================
+//     SetupNames
+//===========================================================================================================================
+
+mDNSlocal void SetupNames( mDNS * const inMDNS )
+{
+       char                    tempCString[ 128 ];
+       mDNSu8                  tempPString[ 128 ];
+       mDNSu8 *                namePtr;
+       
+       // Set up the host name.
+       
+       tempCString[ 0 ] = '\0';
+       GenerateUniqueHostName( tempCString, NULL );
+       check( tempCString[ 0 ] != '\0' );
+       if( tempCString[ 0 ] == '\0' )
+       {
+               // No name so use the default.
+               
+               strcpy( tempCString, kMDNSDefaultName );
+       }
+       inMDNS->nicelabel.c[ 0 ] = strlen( tempCString );
+       memcpy( &inMDNS->nicelabel.c[ 1 ], tempCString, inMDNS->nicelabel.c[ 0 ] );
+       check( inMDNS->nicelabel.c[ 0 ] > 0 );
+       
+       // Set up the DNS name.
+       
+       tempCString[ 0 ] = '\0';
+       GenerateUniqueDNSName( tempCString, NULL );
+       if( tempCString[ 0 ] != '\0' )
+       {
+               tempPString[ 0 ] = strlen( tempCString );
+               memcpy( &tempPString[ 1 ], tempCString, tempPString[ 0 ] );
+               namePtr = tempPString;
+       }
+       else
+       {
+               // No DNS name so use the host name.
+               
+               namePtr = inMDNS->nicelabel.c;
+       }
+       ConvertUTF8PstringToRFC1034HostLabel( namePtr, &inMDNS->hostlabel );
+       if( inMDNS->hostlabel.c[ 0 ] == 0 )
+       {
+               // Nice name has no characters that are representable as an RFC 1034 name (e.g. Japanese) so use the default.
+               
+               MakeDomainLabelFromLiteralString( &inMDNS->hostlabel, kMDNSDefaultName );
+       }
+       check( inMDNS->hostlabel.c[ 0 ] > 0 );
+
+       mDNS_SetFQDN( inMDNS );
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "nice name \"%.*s\"\n", inMDNS->nicelabel.c[ 0 ], &inMDNS->nicelabel.c[ 1 ] );
+       dlog( kDebugLevelInfo, DEBUG_NAME "host name \"%.*s\"\n", inMDNS->hostlabel.c[ 0 ], &inMDNS->hostlabel.c[ 1 ] );
+}
+
+//===========================================================================================================================
+//     SetupInterfaceList
+//===========================================================================================================================
+
+mDNSlocal mStatus      SetupInterfaceList( mDNS * const inMDNS )
+{
+       mStatus                                         err;
+       struct ifaddrs *                        addrs;
+       struct ifaddrs *                        p;
+       uint32_t                                        flagMask;
+       uint32_t                                        flagTest;
+       MDNSInterfaceItem **            next;
+       MDNSInterfaceItem *                     item;
+       
+       addrs = NULL;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up interface list\n" );
+       check( inMDNS );
+       
+       // Tear down any existing interfaces that may be set up.
+       
+       TearDownInterfaceList( inMDNS );
+       inMDNS->p->interfaceList = NULL;
+       next = &inMDNS->p->interfaceList;
+       
+       // Set up each interface that is active, multicast-capable, and not the loopback interface or point-to-point.
+       
+       flagMask = IFF_UP | IFF_MULTICAST | IFF_LOOPBACK | IFF_POINTOPOINT;
+       flagTest = IFF_UP | IFF_MULTICAST;
+       
+       err = getifaddrs( &addrs );
+       require_noerr( err, exit );
+       
+       for( p = addrs; p; p = p->ifa_next )
+       {
+               if( ( p->ifa_flags & flagMask ) == flagTest )
+               {
+                       err = SetupInterface( inMDNS, p, &item );
+                       require_noerr( err, exit );
+                       
+                       *next = item;
+                       next = &item->next;
+               }
+       }
+       err = mStatus_NoError;
+       
+exit:
+       if( addrs )
+       {
+               freeifaddrs( addrs );
+       }
+       if( err )
+       {
+               TearDownInterfaceList( inMDNS );
+       }
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up interface list done (err=%ld)\n", err );
+       return( err );
+}
+
+//===========================================================================================================================
+//     TearDownInterfaceList
+//===========================================================================================================================
+
+mDNSlocal mStatus      TearDownInterfaceList( mDNS * const inMDNS )
+{
+       dlog( kDebugLevelVerbose, DEBUG_NAME "tearing down interface list\n" );
+       check( inMDNS );
+       
+       // Tear down all the interfaces.
+       
+       while( inMDNS->p->interfaceList )
+       {
+               MDNSInterfaceItem *             item;
+               
+               item = inMDNS->p->interfaceList;
+               inMDNS->p->interfaceList = item->next;
+               
+               TearDownInterface( inMDNS, item );
+       }
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "tearing down interface list done\n" );
+       return( mStatus_NoError );
+}
+
+//===========================================================================================================================
+//     SetupInterface
+//===========================================================================================================================
+
+mDNSlocal mStatus      SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inAddr, MDNSInterfaceItem **outItem )
+{
+       mStatus                                                 err;
+       MDNSInterfaceItem *                             item;
+       MDNSSocketRef                                   socketRef;
+       const struct sockaddr_in *              ipv4, *mask;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up interface (name=%s)\n", inAddr->ifa_name );
+       check( inMDNS );
+       check( inAddr );
+       check( inAddr->ifa_addr );
+       ipv4 = (const struct sockaddr_in *) inAddr->ifa_addr;
+       mask = (const struct sockaddr_in *) inAddr->ifa_netmask;
+       check( outItem );
+       
+       // Allocate memory for the info item.
+       
+       item = (MDNSInterfaceItem *) calloc( 1, sizeof( *item ) );
+       require_action( item, exit, err = mStatus_NoMemoryErr );
+       strcpy( item->name, inAddr->ifa_name );
+       item->multicastSocketRef        = kInvalidSocketRef;
+       item->sendingSocketRef          = kInvalidSocketRef;
+       
+       // Set up the multicast DNS (port 5353) socket for this interface.
+       
+       err = SetupSocket( inMDNS, inAddr, MulticastDNSPort, &socketRef );
+       require_noerr( err, exit );
+       item->multicastSocketRef = socketRef;
+               
+       // Set up the sending socket for this interface.
+       
+       err = SetupSocket( inMDNS, inAddr, zeroIPPort, &socketRef );
+       require_noerr( err, exit );
+       item->sendingSocketRef = socketRef;
+       
+       // Register this interface with mDNS.
+       
+       item->hostSet.InterfaceID             = (mDNSInterfaceID) item;
+       item->hostSet.ip  .type               = mDNSAddrType_IPv4;
+       item->hostSet.ip  .ip.v4.NotAnInteger = ipv4->sin_addr.s_addr;
+       item->hostSet.mask.type               = mDNSAddrType_IPv4;
+       item->hostSet.mask.ip.v4.NotAnInteger = mask->sin_addr.s_addr;
+       item->hostSet.ifname[0]               = 0;
+       item->hostSet.Advertise               = inMDNS->AdvertiseLocalAddresses;
+       item->hostSet.McastTxRx               = mDNStrue;
+
+       err = mDNS_RegisterInterface( inMDNS, &item->hostSet, 0 );
+       require_noerr( err, exit );
+       item->hostRegistered = mDNStrue;
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "Registered IP address: %u.%u.%u.%u\n", 
+                 item->hostSet.ip.ip.v4.b[ 0 ], item->hostSet.ip.ip.v4.b[ 1 ], 
+                 item->hostSet.ip.ip.v4.b[ 2 ], item->hostSet.ip.ip.v4.b[ 3 ] );
+       
+       // Success!
+       
+       *outItem = item;
+       item = NULL;
+       
+exit:
+       if( item )
+       {
+               TearDownInterface( inMDNS, item );
+       }
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up interface done (name=%s, err=%ld)\n", inAddr->ifa_name, err );
+       return( err );
+}
+
+//===========================================================================================================================
+//     TearDownInterface
+//===========================================================================================================================
+
+mDNSlocal mStatus      TearDownInterface( mDNS * const inMDNS, MDNSInterfaceItem *inItem )
+{
+       MDNSSocketRef           socketRef;
+       
+       check( inMDNS );
+       check( inItem );
+       
+       // Deregister this interface with mDNS.
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "Deregistering IP address: %u.%u.%u.%u\n", 
+                 inItem->hostSet.ip.ip.v4.b[ 0 ], inItem->hostSet.ip.ip.v4.b[ 1 ], 
+                 inItem->hostSet.ip.ip.v4.b[ 2 ], inItem->hostSet.ip.ip.v4.b[ 3 ] );
+       
+       if( inItem->hostRegistered )
+       {
+               inItem->hostRegistered = mDNSfalse;
+               mDNS_DeregisterInterface( inMDNS, &inItem->hostSet );
+       }
+       
+       // Close the multicast socket.
+       
+       socketRef = inItem->multicastSocketRef;
+       inItem->multicastSocketRef = kInvalidSocketRef;
+       if( socketRef != kInvalidSocketRef )
+       {
+               dlog( kDebugLevelVerbose, DEBUG_NAME "tearing down multicast socket %d\n", socketRef );
+               close( socketRef );
+       }
+               
+       // Close the sending socket.
+       
+       socketRef = inItem->sendingSocketRef;
+       inItem->sendingSocketRef = kInvalidSocketRef;
+       if( socketRef != kInvalidSocketRef )
+       {
+               dlog( kDebugLevelVerbose, DEBUG_NAME "tearing down sending socket %d\n", socketRef );
+               close( socketRef );
+       }
+       
+       // Free the memory used by the interface info.
+       
+       free( inItem ); 
+       return( mStatus_NoError );
+}
+
+//===========================================================================================================================
+//     SetupSocket
+//===========================================================================================================================
+
+mDNSlocal mStatus
+       SetupSocket( 
+               mDNS * const                    inMDNS, 
+               const struct ifaddrs *  inAddr, 
+               mDNSIPPort                              inPort, 
+               MDNSSocketRef *                 outSocketRef  )
+{
+       mStatus                                                 err;
+       MDNSSocketRef                                   socketRef;
+       int                                                             option;
+       unsigned char                                   optionByte;
+       struct ip_mreq                                  mreq;
+       const struct sockaddr_in *              ipv4;
+       struct sockaddr_in                              addr;
+       mDNSv4Addr                                              ip;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up socket done\n" );
+       check( inMDNS );
+       check( inAddr );
+       check( inAddr->ifa_addr );
+       ipv4 = (const struct sockaddr_in *) inAddr->ifa_addr;
+       check( outSocketRef );
+       
+       // Set up a UDP socket for multicast DNS. 
+       
+       socketRef = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+       require_errno_action( socketRef, errno, exit, err = mStatus_UnknownErr );
+               
+       // A port of zero means this socket is for sending and should be set up for sending. Otherwise, it is for receiving 
+       // and should be set up for receiving. The reason for separate sending vs receiving sockets is to workaround problems
+       // with VxWorks IP stack when using dynamic IP configuration such as DHCP (problems binding to wildcard IP when the
+       // IP address later changes). Since we have to bind the Multicast DNS address to workaround these issues we have to
+       // use a separate sending socket since it is illegal to send a packet with a multicast source address (RFC 1122).
+       
+       if( inPort.NotAnInteger != zeroIPPort.NotAnInteger )
+       {       
+               // Turn on reuse port option so multiple servers can listen for Multicast DNS packets.
+               
+               option = 1;
+               err = setsockopt( socketRef, SOL_SOCKET, SO_REUSEADDR, (char *) &option, sizeof( option ) );
+               check_errno( err, errno );
+               
+               // Join the all-DNS multicast group so we receive Multicast DNS packets.
+               
+               ip.NotAnInteger                         = ipv4->sin_addr.s_addr;
+               mreq.imr_multiaddr.s_addr       = AllDNSLinkGroupv4.NotAnInteger;
+               mreq.imr_interface.s_addr       = ip.NotAnInteger;
+               err = setsockopt( socketRef, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof( mreq ) );
+               check_errno( err, errno );
+               
+               // Bind to the multicast DNS address and port 5353.
+               
+               memset( &addr, 0, sizeof( addr ) );
+               addr.sin_family                 = AF_INET;
+               addr.sin_port                   = inPort.NotAnInteger;
+               addr.sin_addr.s_addr    = AllDNSLinkGroupv4.NotAnInteger;
+               err = bind( socketRef, (struct sockaddr *) &addr, sizeof( addr ) );
+               check_errno( err, errno );
+               
+               dlog( kDebugLevelVerbose, DEBUG_NAME "setting up socket done (%s, %u.%u.%u.%u:%u, %d)\n", 
+                         inAddr->ifa_name, ip.b[ 0 ], ip.b[ 1 ], ip.b[ 2 ], ip.b[ 3 ], ntohs( inPort.NotAnInteger ), socketRef );
+       }
+       else
+       {
+               // Bind to the interface address and multicast DNS port.
+               
+               ip.NotAnInteger                 = ipv4->sin_addr.s_addr;
+               memset( &addr, 0, sizeof( addr ) );
+               addr.sin_family                 = AF_INET;
+               addr.sin_port                   = MulticastDNSPort.NotAnInteger;
+               addr.sin_addr.s_addr    = ip.NotAnInteger;
+               err = bind( socketRef, (struct sockaddr *) &addr, sizeof( addr ) );
+               check_errno( err, errno );
+               
+               // Direct multicast packets to the specified interface.
+               
+               addr.sin_addr.s_addr = ip.NotAnInteger;
+               err = setsockopt( socketRef, IPPROTO_IP, IP_MULTICAST_IF, (char *) &addr.sin_addr, sizeof( addr.sin_addr ) );
+               check_errno( err, errno );
+               
+               // Set the TTL of outgoing unicast packets to 255 (helps against spoofing).
+               
+               option = 255;
+               err = setsockopt( socketRef, IPPROTO_IP, IP_TTL, (char *) &option, sizeof( option ) );
+               check_errno( err, errno );
+               
+               // Set the TTL of outgoing multicast packets to 255 (helps against spoofing).
+               
+               optionByte = 255;
+               err = setsockopt( socketRef, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &optionByte, sizeof( optionByte ) );
+               check_errno( err, errno );
+               
+               // WARNING: Setting this option causes unicast responses to be routed to the wrong interface so they are 
+               // WARNING: disabled. These options were only hints to improve 802.11 performance (and not implemented) anyway.
+               
+#if 0
+               // Mark packets as high-throughput/low-delay (i.e. lowest reliability) to maximize 802.11 multicast rate.
+               
+               option = IPTOS_LOWDELAY | IPTOS_THROUGHPUT;
+               err = setsockopt( socketRef, IPPROTO_IP, IP_TOS, (char *) &option, sizeof( option ) );
+               check_errno( err, errno );
+#endif
+       
+               dlog( kDebugLevelVerbose, DEBUG_NAME "setting up sending socket done (%s, %u.%u.%u.%u, %d)\n", 
+                         inAddr->ifa_name, ip.b[ 0 ], ip.b[ 1 ], ip.b[ 2 ], ip.b[ 3 ], socketRef );
+       }
+       
+       // Success!
+       
+       *outSocketRef = socketRef;
+       socketRef = kInvalidSocketRef;
+       err = mStatus_NoError;
+       
+exit:
+       if( socketRef != kInvalidSocketRef )
+       {
+               close( socketRef );
+       }
+       return( err );
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Commands ==
+#endif
+
+//===========================================================================================================================
+//     SetupCommandPipe
+//===========================================================================================================================
+
+mDNSlocal mStatus      SetupCommandPipe( mDNS * const inMDNS )
+{
+       mStatus         err;
+       
+       // Clean up any leftover command pipe.
+       
+       TearDownCommandPipe( inMDNS );
+       
+       // Create the pipe device and open it.
+       
+       pipeDevCreate( kMDNSPipeName, kMDNSPipeMessageQueueSize, kMDNSPipeMessageSize );
+       
+       inMDNS->p->commandPipe = open( kMDNSPipeName, O_RDWR, 0 );
+       require_errno_action( inMDNS->p->commandPipe, errno, exit, err = mStatus_UnsupportedErr );
+       
+       err = mStatus_NoError;
+       
+exit:
+       return( err );
+}
+
+//===========================================================================================================================
+//     TearDownCommandPipe
+//===========================================================================================================================
+
+mDNSlocal mStatus      TearDownCommandPipe( mDNS * const inMDNS )
+{
+       if( inMDNS->p->commandPipe != ERROR )
+       {
+               close( inMDNS->p->commandPipe );
+#ifdef _WRS_VXWORKS_5_X
+               // pipeDevDelete is not defined in older versions of VxWorks
+               pipeDevDelete( kMDNSPipeName, FALSE );
+#endif
+               inMDNS->p->commandPipe = ERROR;
+       }       
+       return( mStatus_NoError );
+}
+
+//===========================================================================================================================
+//     SendCommand
+//===========================================================================================================================
+
+mDNSlocal mStatus      SendCommand( const mDNS * const inMDNS, MDNSPipeCommandCode inCommandCode )
+{
+       mStatus         err;
+       
+       require_action( inMDNS->p->commandPipe != ERROR, exit, err = mStatus_NotInitializedErr );
+       
+       err = write( inMDNS->p->commandPipe, &inCommandCode, sizeof( inCommandCode ) );
+       require_errno( err, errno, exit );
+       
+       err = mStatus_NoError;
+       
+exit:
+       return( err );
+}
+
+//===========================================================================================================================
+//     ProcessCommand
+//===========================================================================================================================
+
+mDNSlocal mStatus      ProcessCommand( mDNS * const inMDNS )
+{
+       mStatus                                 err;
+       MDNSPipeCommandCode             commandCode;
+       
+       require_action( inMDNS->p->commandPipe != ERROR, exit, err = mStatus_NotInitializedErr );
+       
+       // Read the command code from the pipe and dispatch it.
+       
+       err = read( inMDNS->p->commandPipe, &commandCode, sizeof( commandCode ) );
+       require_errno( err, errno, exit );
+       
+       switch( commandCode )
+       {
+               case kMDNSPipeCommandCodeReschedule:
+                       
+                       // Reschedule event. Do nothing here, but this will cause mDNS_Execute to run before waiting again.
+                       
+                       dlog( kDebugLevelChatty, DEBUG_NAME "reschedule\n" );
+                       break;
+               
+               case kMDNSPipeCommandCodeReconfigure:
+                       ProcessCommandReconfigure( inMDNS );
+                       break;
+               
+               case kMDNSPipeCommandCodeQuit:
+               
+                       // Quit requested. Set quit flag and bump the config ID to let the thread exit normally.
+                       
+                       dlog( kDebugLevelVerbose, DEBUG_NAME "processing pipe quit command\n" );
+                       inMDNS->p->quit = mDNStrue;
+                       ++inMDNS->p->configID;
+                       break;
+                               
+               default:
+                       dlog( kDebugLevelError, DEBUG_NAME "unknown pipe command code (code=0x%08X)\n", commandCode );
+                       err = mStatus_BadParamErr;
+                       goto exit;
+                       break;
+       }
+       err = mStatus_NoError;
+
+exit:
+       return( err );
+}
+
+//===========================================================================================================================
+//     ProcessCommandReconfigure
+//===========================================================================================================================
+
+mDNSlocal void ProcessCommandReconfigure( mDNS *inMDNS )
+{
+       mStatus         err;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "processing pipe reconfigure command\n" );
+       
+       // Tear down the existing interfaces and set up new ones using the new IP info.
+       
+       mDNSPlatformLock( inMDNS );
+       
+       err = TearDownInterfaceList( inMDNS );
+       check_noerr( err );
+       
+       err = SetupInterfaceList( inMDNS );
+       check_noerr( err );
+       
+       mDNSPlatformUnlock( inMDNS );
+       
+       // Inform clients of the change.
+       
+       if( inMDNS->MainCallback )
+       {
+               inMDNS->MainCallback( inMDNS, mStatus_ConfigChanged );
+       }
+       
+       // Force mDNS to update.
+       
+       mDNSCoreMachineSleep( inMDNS, mDNSfalse );
+       
+       // Bump the config ID so the main processing loop detects the configuration change.
+       
+       ++inMDNS->p->configID;
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Threads ==
+#endif
+
+//===========================================================================================================================
+//     SetupTask
+//===========================================================================================================================
+
+mDNSlocal mStatus      SetupTask( mDNS * const inMDNS )
+{
+       mStatus         err;
+       int                     task;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up thread\n" );
+       check( inMDNS );
+       
+       // Create our main thread. Note: The task will save off its ID in the globals. We cannot do it here because the 
+       // task invokes code that needs it and the task may begin execution before taskSpawn returns the task ID.
+       // This also means code in this thread context cannot rely on the task ID until the task has fully initialized.
+       
+       task = taskSpawn( kMDNSTaskName, kMDNSTaskPriority, 0, kMDNSTaskStackSize, (FUNCPTR) Task, 
+                                         (int) inMDNS, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
+       require_action( task != ERROR, exit, err = mStatus_NoMemoryErr );
+       
+       err = mStatus_NoError;
+       
+exit:
+       dlog( kDebugLevelVerbose, DEBUG_NAME "setting up thread done (err=%ld, id=%d)\n", err, task );
+       return( err );
+}
+
+//===========================================================================================================================
+//     TearDownTask
+//===========================================================================================================================
+
+mDNSlocal mStatus      TearDownTask( mDNS * const inMDNS )
+{
+       mStatus         err;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "tearing down thread\n" );
+       check( inMDNS );
+       
+       // Send a quit command to cause the thread to exit.
+       
+       SendCommand( inMDNS, kMDNSPipeCommandCodeQuit );
+       
+       // Wait for the thread to signal it has exited. Timeout in 10 seconds to handle a hung thread.
+       
+       if( inMDNS->p->quitEvent )
+       {
+               err = semTake( inMDNS->p->quitEvent, sysClkRateGet() * 10 );
+               check_noerr( err );
+       }
+       err = mStatus_NoError;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "tearing down thread done (err=%ld)\n", err );
+       return( err );
+}
+
+//===========================================================================================================================
+//     Task
+//===========================================================================================================================
+
+mDNSlocal void Task( mDNS *inMDNS )
+{
+       mStatus                                 err;
+       fd_set                                  allReadSet;
+       MDNSInterfaceItem *             item;
+       int                                             maxSocket;
+       long                                    configID;
+       struct timeval                  timeout;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "task starting\n" );
+       check( inMDNS );
+       
+       // Set up everything up.
+       
+       err = TaskInit( inMDNS );
+       require_noerr( err, exit );
+       
+       // Main Processing Loop.
+       
+       while( !inMDNS->p->quit )
+       {
+               // Set up the read set here to avoid the overhead of setting it up each iteration of the main processing loop. 
+               // If the configuration changes, the server ID will be bumped, causing this code to set up the read set again.
+               
+               TaskSetupReadSet( inMDNS, &allReadSet, &maxSocket );
+               configID = inMDNS->p->configID;
+               dlog( kDebugLevelVerbose, DEBUG_NAME "task starting processing loop (configID=%ld)\n", configID );
+               
+               while( configID == inMDNS->p->configID )
+               {
+                       mDNSs32         nextTaskTime;
+                       fd_set          readSet;
+                       int                     n;
+                       
+                       // Give the mDNS core a chance to do its work. Reset the rescheduled flag before calling mDNS_Execute
+                       // so anything that needs processing during or after causes a re-schedule to wake up the thread. The
+                       // reschedule flag is set to 1 after processing a waking up to prevent redundant reschedules while
+                       // processing packets. This introduces a window for a race condition because the thread wake-up and
+                       // reschedule set are not atomic, but this would be benign. Even if the reschedule flag is "corrupted"
+                       // like this, it would only result in a redundant reschedule since it will loop back to mDNS_Execute.
+                       
+                       inMDNS->p->rescheduled = 0;
+                       nextTaskTime = mDNS_Execute( inMDNS );
+                       TaskSetupTimeout( inMDNS, nextTaskTime, &timeout );
+                       
+                       // Wait until something occurs (e.g. command, incoming packet, or timeout).
+                       
+                       readSet = allReadSet;
+                       n = select( maxSocket + 1, &readSet, NULL, NULL, &timeout );
+                       inMDNS->p->rescheduled = 1;
+                       check_errno( n, errno );
+                       dlog( kDebugLevelChatty - 1, DEBUG_NAME "task select result = %d\n", n );
+                       if( n == 0 )
+                       {
+                               // Next task timeout occurred. Loop back up to give mDNS core a chance to work.
+                               
+                               dlog( kDebugLevelChatty, DEBUG_NAME "next task timeout occurred (%ld)\n", mDNS_TimeNow(inMDNS) );
+                               continue;
+                       }
+                       
+                       // Scan the read set to determine if any sockets have something pending and process them.
+                       
+                       n = 0;
+                       for( item = inMDNS->p->interfaceList; item; item = item->next )
+                       {
+                               if( FD_ISSET( item->multicastSocketRef, &readSet ) )
+                               {
+                                       TaskProcessPacket( inMDNS, item, item->multicastSocketRef );
+                                       ++n;
+                               }
+                       }
+                       
+                       // Check for a pending command and process it.
+                       
+                       if( FD_ISSET( inMDNS->p->commandPipe, &readSet ) )
+                       {
+                               ProcessCommand( inMDNS );
+                               ++n;
+                       }
+                       check( n > 0 );
+               }
+       }
+
+exit:
+       // Signal we've quit.
+       
+       check( inMDNS->p->quitEvent );
+       semGive( inMDNS->p->quitEvent );
+       
+       dlog( kDebugLevelInfo, DEBUG_NAME "task ended\n" );
+}
+
+//===========================================================================================================================
+//     TaskInit
+//===========================================================================================================================
+
+mDNSlocal mStatus      TaskInit( mDNS *inMDNS )
+{
+       mStatus         err;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "task init\n" );
+       check( inMDNS->p->readyEvent );
+       
+       inMDNS->p->task = taskIdSelf();
+       
+       err = SetupCommandPipe( inMDNS );
+       require_noerr( err, exit );
+       
+       SetupNames( inMDNS );
+       
+       err = SetupInterfaceList( inMDNS );
+       require_noerr( err, exit );
+       
+exit:
+       // Signal the "ready" semaphore to indicate the task initialization code has completed (success or not).
+       
+       inMDNS->p->taskInitErr = err;
+       semGive( inMDNS->p->readyEvent );
+
+       dlog( kDebugLevelVerbose, DEBUG_NAME "task init done (err=%ld)\n", err );
+       return( err );
+}
+
+//===========================================================================================================================
+//     TaskSetupReadSet
+//===========================================================================================================================
+
+mDNSlocal void TaskSetupReadSet( mDNS *inMDNS, fd_set *outReadSet, int *outMaxSocket )
+{
+       MDNSInterfaceItem *             item;
+       int                                             maxSocket;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "task setting up read set\n" );
+       check( inMDNS );
+       check( outReadSet );
+       check( outMaxSocket );
+       
+       // Initialize the read set. Default the max socket to -1 so "maxSocket + 1" (as needed by select) is zero. This 
+       // should never happen since we should always have at least one interface, but it's just to be safe.
+       
+       FD_ZERO( outReadSet );
+       maxSocket = -1;
+       
+       // Add all the receiving sockets to the read set.
+       
+       for( item = inMDNS->p->interfaceList; item; item = item->next )
+       {
+               FD_SET( item->multicastSocketRef, outReadSet );
+               if( item->multicastSocketRef > maxSocket )
+               {
+                       maxSocket = item->multicastSocketRef;
+               }
+       }
+       
+       // Add the command pipe to the read set.
+       
+       FD_SET( inMDNS->p->commandPipe, outReadSet );
+       if( inMDNS->p->commandPipe > maxSocket )
+       {
+               maxSocket = inMDNS->p->commandPipe;
+       }
+       check( maxSocket > 0 );
+       *outMaxSocket = maxSocket;
+       
+       dlog( kDebugLevelVerbose, DEBUG_NAME "task setting up read set done (maxSocket=%d)\n", maxSocket );
+}
+
+//===========================================================================================================================
+//     TaskSetupTimeout
+//===========================================================================================================================
+
+mDNSlocal void TaskSetupTimeout( mDNS *inMDNS, mDNSs32 inNextTaskTime, struct timeval *outTimeout )
+{
+       mDNSs32         delta;
+       
+       // Calculate how long to wait before performing idle processing.
+       
+       delta = inNextTaskTime - mDNS_TimeNow(inMDNS);
+       if( delta <= 0 )
+       {
+               // The next task time is now or in the past. Set the timeout to fire immediately.
+               
+               outTimeout->tv_sec      = 0;
+               outTimeout->tv_usec     = 0;
+       }
+       else
+       {
+               // Calculate the seconds and microseconds until the timeout should occur. Add one to the ticks remainder 
+               // before multiplying to account for integer rounding error and avoid firing the timeout too early.
+               
+               outTimeout->tv_sec  = delta / mDNSPlatformOneSecond;
+               outTimeout->tv_usec = ( ( delta % mDNSPlatformOneSecond ) + 1 ) * gMDNSTicksToMicrosecondsMultiplier;
+               
+               // Check if the microseconds is more than 1 second. If so, bump the seconds instead.
+               
+               if( outTimeout->tv_usec >= 1000000L )
+               {
+                       outTimeout->tv_sec += 1;
+                       outTimeout->tv_usec = 0;
+               }
+       }
+       
+       dlog( kDebugLevelChatty, DEBUG_NAME "next task in %ld:%ld seconds (%ld)\n", 
+                 outTimeout->tv_sec, outTimeout->tv_usec, inNextTaskTime );
+}
+//===========================================================================================================================
+//     TaskProcessPacket
+//===========================================================================================================================
+
+mDNSlocal void TaskProcessPacket( mDNS *inMDNS, MDNSInterfaceItem *inItem, MDNSSocketRef inSocketRef )
+{
+       int                                             n;
+       DNSMessage                              packet;
+       struct sockaddr_in              addr;
+       int                                             addrSize;
+       mDNSu8 *                                packetEndPtr;
+       mDNSAddr                                srcAddr;
+       mDNSIPPort                              srcPort;
+       mDNSAddr                                dstAddr;
+       mDNSIPPort                              dstPort;
+               
+       // Receive the packet.
+       
+       addrSize = sizeof( addr );
+       n = recvfrom( inSocketRef, (char *) &packet, sizeof( packet ), 0, (struct sockaddr *) &addr, &addrSize );
+       check( n >= 0 );
+       if( n >= 0 )
+       {
+               // Set up the src/dst/interface info.
+               
+               srcAddr.type                            = mDNSAddrType_IPv4;
+               srcAddr.ip.v4.NotAnInteger      = addr.sin_addr.s_addr;
+               srcPort.NotAnInteger            = addr.sin_port;
+               dstAddr.type                            = mDNSAddrType_IPv4;
+               dstAddr.ip.v4                           = AllDNSLinkGroupv4;
+               dstPort                                         = MulticastDNSPort;
+               
+               dlog( kDebugLevelChatty, DEBUG_NAME "packet received\n" );
+               dlog( kDebugLevelChatty, DEBUG_NAME "    size      = %d\n", n );
+               dlog( kDebugLevelChatty, DEBUG_NAME "    src       = %u.%u.%u.%u:%hu\n", 
+                         srcAddr.ip.v4.b[ 0 ], srcAddr.ip.v4.b[ 1 ], srcAddr.ip.v4.b[ 2 ], srcAddr.ip.v4.b[ 3 ], 
+                         ntohs( srcPort.NotAnInteger ) );
+               dlog( kDebugLevelChatty, DEBUG_NAME "    dst       = %u.%u.%u.%u:%hu\n", 
+                         dstAddr.ip.v4.b[ 0 ], dstAddr.ip.v4.b[ 1 ], dstAddr.ip.v4.b[ 2 ], dstAddr.ip.v4.b[ 3 ], 
+                         ntohs( dstPort.NotAnInteger ) );
+               dlog( kDebugLevelChatty, DEBUG_NAME "    interface = 0x%08X\n", (int) inItem->hostSet.InterfaceID );
+               dlog( kDebugLevelChatty, DEBUG_NAME "--\n" );
+               
+               // Dispatch the packet to mDNS.
+               
+               packetEndPtr = ( (mDNSu8 *) &packet ) + n;
+               mDNSCoreReceive( inMDNS, &packet, packetEndPtr, &srcAddr, srcPort, &dstAddr, dstPort, inItem->hostSet.InterfaceID );
+       }
+       
+       // Update counters.
+       
+       inItem->recvCounter                     += 1;
+       inItem->recvErrorCounter        += ( n < 0 );
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Utilities ==
+#endif
+
+#if( TARGET_NON_APPLE )
+//===========================================================================================================================
+//     GenerateUniqueHostName
+//
+//     Non-Apple platform stub routine to generate a unique name for the device. Should be implemented to return a unique name.
+//===========================================================================================================================
+
+mDNSlocal void GenerateUniqueHostName( char *outName, long *ioSeed )
+{
+       DEBUG_UNUSED( ioSeed );
+       
+       // $$$ Non-Apple Platforms: Fill in appropriate name for device.
+       
+       mDNSPlatformStrCopy( kMDNSDefaultName, outName );
+}
+
+//===========================================================================================================================
+//     GenerateUniqueDNSName
+//
+//     Non-Apple platform stub routine to generate a unique RFC 1034-compatible DNS name for the device. Should be 
+//     implemented to return a unique name.
+//===========================================================================================================================
+
+mDNSlocal void GenerateUniqueDNSName( char *outName, long *ioSeed )
+{
+       DEBUG_UNUSED( ioSeed );
+       
+       // $$$ Non-Apple Platforms: Fill in appropriate DNS name for device.
+       
+       mDNSPlatformStrCopy( kMDNSDefaultName, outName );
+}
+#endif
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//     getifaddrs
+//===========================================================================================================================
+
+int    getifaddrs( struct ifaddrs **outAddrs )
+{
+       int                                             err;
+       struct ifaddrs *                head;
+       struct ifaddrs **               next;
+       struct ifaddrs *                ifa;
+       int                                             i;
+       struct ifnet *                  ifp;
+       char                                    ipString[ INET_ADDR_LEN ];
+       int                                             n;
+       
+       head = NULL;
+       next = &head;
+       
+       i = 1;
+       for( ;; )
+       {
+               ifp = ifIndexToIfp( i );
+               if( !ifp )
+               {
+                       break;
+               }
+               ++i;
+               
+               // Allocate and initialize the ifaddrs structure and attach it to the linked list.
+               
+               ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
+               require_action( ifa, exit, err = ENOMEM );
+               
+               *next = ifa;
+               next  = &ifa->ifa_next;
+               
+               // Fetch the name.
+               
+               ifa->ifa_name = (char *) malloc( 16 );
+               require_action( ifa->ifa_name, exit, err = ENOMEM );
+               
+               n = sprintf( ifa->ifa_name, "%s%d", ifp->if_name, ifp->if_unit );
+               require_action( n < 16, exit, err = ENOBUFS );
+               
+               // Fetch the address.
+               
+               ifa->ifa_addr = (struct sockaddr *) calloc( 1, sizeof( struct sockaddr_in ) );
+               require_action( ifa->ifa_addr, exit, err = ENOMEM );
+               
+               ipString[ 0 ] = '\0';
+               #if( TARGET_NON_APPLE )
+                       err = ifAddrGet( ifa->ifa_name, ipString );
+                       require_noerr( err, exit );
+               #else
+                       err = ifAddrGetNonAlias( ifa->ifa_name, ipString );
+                       require_noerr( err, exit );
+               #endif
+               
+               err = sock_pton( ipString, AF_INET, ifa->ifa_addr, 0, NULL );
+               require_noerr( err, exit );
+               
+               // Fetch flags.
+               
+               ifa->ifa_flags = ifp->if_flags;
+       }
+       
+       // Success!
+       
+       if( outAddrs )
+       {
+               *outAddrs = head;
+               head = NULL;
+       }
+       err = 0;
+
+exit:
+       if( head )
+       {
+               freeifaddrs( head );
+       }
+       return( err );
+}
+
+//===========================================================================================================================
+//     freeifaddrs
+//===========================================================================================================================
+
+void   freeifaddrs( struct ifaddrs *inAddrs )
+{
+       struct ifaddrs *                p;
+       struct ifaddrs *                q;
+       
+       // Free each piece of the structure. Set to null after freeing to handle macro-aliased fields.
+       
+       for( p = inAddrs; p; p = q )
+       {
+               q = p->ifa_next;
+               
+               if( p->ifa_name )
+               {
+                       free( p->ifa_name );
+                       p->ifa_name = NULL;
+               }
+               if( p->ifa_addr )
+               {
+                       free( p->ifa_addr );
+                       p->ifa_addr = NULL;
+               }
+               if( p->ifa_netmask )
+               {
+                       free( p->ifa_netmask );
+                       p->ifa_netmask = NULL;
+               }
+               if( p->ifa_dstaddr )
+               {
+                       free( p->ifa_dstaddr );
+                       p->ifa_dstaddr = NULL;
+               }
+               if( p->ifa_data )
+               {
+                       free( p->ifa_data );
+                       p->ifa_data = NULL;
+               }
+               free( p );
+       }
+}
+
+//===========================================================================================================================
+//     sock_pton
+//===========================================================================================================================
+
+int    sock_pton( const char *inString, int inFamily, void *outAddr, size_t inAddrSize, size_t *outAddrSize )
+{
+       int             err;
+       
+       if( inFamily == AF_INET )
+       {
+               struct sockaddr_in *            ipv4;
+               
+               if( inAddrSize == 0 )
+               {
+                       inAddrSize = sizeof( struct sockaddr_in );
+               }
+               if( inAddrSize < sizeof( struct sockaddr_in ) )
+               {
+                       err = EINVAL;
+                       goto exit;
+               }
+               
+               ipv4 = (struct sockaddr_in *) outAddr;
+               err = inet_aton( (char *) inString, &ipv4->sin_addr );
+               if( err == 0 )
+               {
+                       ipv4->sin_family = AF_INET;
+                       if( outAddrSize )
+                       {
+                               *outAddrSize = sizeof( struct sockaddr_in );
+                       }
+               }
+       }
+#if( defined( AF_INET6 ) )
+       else if( inFamily == AF_INET6 )         // $$$ TO DO: Add IPv6 support.
+       {
+               err = EAFNOSUPPORT;
+               goto exit;
+       }
+#endif
+       else
+       {
+               err = EAFNOSUPPORT;
+               goto exit;
+       }
+
+exit:
+       return( err );
+}
+
+//===========================================================================================================================
+//     sock_ntop
+//===========================================================================================================================
+
+char * sock_ntop( const void *inAddr, size_t inAddrSize, char *inBuffer, size_t inBufferSize )
+{
+       const struct sockaddr *         addr;
+       
+       addr = (const struct sockaddr *) inAddr;
+       if( addr->sa_family == AF_INET )
+       {
+               struct sockaddr_in *            ipv4;
+               
+               if( inAddrSize == 0 )
+               {
+                       inAddrSize = sizeof( struct sockaddr_in );
+               }
+               if( inAddrSize < sizeof( struct sockaddr_in ) )
+               {
+                       errno = EINVAL;
+                       inBuffer = NULL;
+                       goto exit;
+               }
+               if( inBufferSize < 16 )
+               {
+                       errno = ENOBUFS;
+                       inBuffer = NULL;
+                       goto exit;
+               }
+               
+               ipv4 = (struct sockaddr_in *) addr;
+               inet_ntoa_b( ipv4->sin_addr, inBuffer );
+       }
+#if( defined( AF_INET6 ) )
+       else if( addr->sa_family == AF_INET6 )  // $$$ TO DO: Add IPv6 support.
+       {               
+               errno = EAFNOSUPPORT;
+               inBuffer = NULL;
+               goto exit;
+       }
+#endif
+       else
+       {
+               errno = EAFNOSUPPORT;
+               inBuffer = NULL;
+               goto exit;
+       }
+       
+exit:
+       return( inBuffer );
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Debugging ==
+#endif
+
+#if( DEBUG )
+
+void   mDNSShow( BOOL inShowRecords );
+void   mDNSShowRecords( void );
+void   mDNSShowTXT( const void *inTXT, size_t inTXTSize );
+
+//===========================================================================================================================
+//     mDNSShow
+//===========================================================================================================================
+
+void   mDNSShow( BOOL inShowRecords )
+{
+       MDNSInterfaceItem *             item;
+       mDNSAddr                                ip;
+       int                                             n;
+       
+       if( !gMDNSPtr )
+       {
+               printf( "### mDNS not initialized\n" );
+               return;
+       }
+       
+       // Globals
+       
+       printf( "\n-- mDNS globals --\n" );
+       printf( "    sizeof( mDNS )                     = %d\n", (int) sizeof( mDNS ) );
+       printf( "    sizeof( ResourceRecord )           = %d\n", (int) sizeof( ResourceRecord ) );
+       printf( "    sizeof( AuthRecord )               = %d\n", (int) sizeof( AuthRecord ) );
+       printf( "    sizeof( CacheRecord )              = %d\n", (int) sizeof( CacheRecord ) );
+       printf( "    gMDNSPtr                           = 0x%08lX\n", (unsigned long) gMDNSPtr );
+       printf( "    gMDNSTicksToMicrosecondsMultiplier = %ld\n", gMDNSTicksToMicrosecondsMultiplier );
+       printf( "    lockID                             = 0x%08lX\n", (unsigned long) gMDNSPtr->p->lockID );
+       printf( "    readyEvent                         = 0x%08lX\n", (unsigned long) gMDNSPtr->p->readyEvent );
+       printf( "    taskInitErr                        = %ld\n", gMDNSPtr->p->taskInitErr );
+       printf( "    quitEvent                          = 0x%08lX\n", (unsigned long) gMDNSPtr->p->quitEvent );
+       printf( "    commandPipe                        = %d\n", gMDNSPtr->p->commandPipe );
+       printf( "    task                               = 0x%08lX\n", (unsigned long) gMDNSPtr->p->task );
+       printf( "    quit                               = %d\n", gMDNSPtr->p->quit );
+       printf( "    configID                           = %ld\n", gMDNSPtr->p->configID );
+       printf( "    rescheduled                        = %d\n", gMDNSPtr->p->rescheduled );
+       printf( "    nicelabel                          = \"%.*s\"\n", gMDNSPtr->nicelabel.c[ 0 ], (char *) &gMDNSPtr->nicelabel.c[ 1 ] );
+       printf( "    hostLabel                          = \"%.*s\"\n", gMDNSPtr->hostlabel.c[ 0 ], (char *) &gMDNSPtr->hostlabel.c[ 1 ] );
+       printf( "\n");
+       
+       // Interfaces
+       
+       printf( "\n-- mDNS interfaces --\n" );
+       n = 1;
+       for( item = gMDNSPtr->p->interfaceList; item; item = item->next )
+       {
+               printf( "    -- interface %u --\n", n );
+               printf( "        name                           = \"%s\"\n", item->name );
+               printf( "        multicastSocketRef             = %d\n", item->multicastSocketRef );
+               printf( "        sendingSocketRef               = %d\n", item->sendingSocketRef );
+               ip = item->hostSet.ip;
+               printf( "        hostSet.ip                     = %u.%u.%u.%u\n", ip.ip.v4.b[ 0 ], ip.ip.v4.b[ 1 ], 
+                                                                                                                                                 ip.ip.v4.b[ 2 ], ip.ip.v4.b[ 3 ] );
+               printf( "        hostSet.advertise              = %s\n", item->hostSet.Advertise ? "YES" : "NO" );
+               printf( "        hostRegistered                 = %s\n", item->hostRegistered ? "YES" : "NO" );
+               printf( "        --\n" );
+               printf( "        sendMulticastCounter           = %d\n", item->sendMulticastCounter );
+               printf( "        sendUnicastCounter             = %d\n", item->sendUnicastCounter );
+               printf( "        sendErrorCounter               = %d\n", item->sendErrorCounter );
+               printf( "        recvCounter                    = %d\n", item->recvCounter );
+               printf( "        recvErrorCounter               = %d\n", item->recvErrorCounter );
+               printf( "        recvLoopCounter                = %d\n", item->recvLoopCounter );
+               printf( "\n" );
+               ++n;
+       }
+       
+       // Resource Records
+       
+       if( inShowRecords )
+       {
+               mDNSShowRecords();
+       }
+}
+
+//===========================================================================================================================
+//     mDNSShowRecords
+//===========================================================================================================================
+
+void   mDNSShowRecords( void )
+{
+       MDNSInterfaceItem *             item;
+       int                                             n;
+       AuthRecord *                    record;
+       char                                    name[ MAX_ESCAPED_DOMAIN_NAME ];
+       
+       printf( "\n-- mDNS resource records --\n" );
+       n = 1;
+       for( record = gMDNSPtr->ResourceRecords; record; record = record->next )
+       {
+               item = (MDNSInterfaceItem *) record->resrec.InterfaceID;
+               ConvertDomainNameToCString( &record->resrec.name, name );
+               printf( "    -- record %d --\n", n );
+               printf( "        interface = 0x%08X (%s)\n", (int) item, item ? item->name : "<any>" );
+               printf( "        name      = \"%s\"\n", name );
+               printf( "\n" );
+               ++n;
+       }
+       printf( "\n");
+}
+
+//===========================================================================================================================
+//     mDNSShowTXT
+//===========================================================================================================================
+
+void   mDNSShowTXT( const void *inTXT, size_t inTXTSize )
+{
+       const mDNSu8 *          p;
+       const mDNSu8 *          end;
+       int                                     i;
+       mDNSu8                          size;
+       
+       printf( "\nTXT record (%u bytes):\n\n", inTXTSize );
+       
+       p       = (const mDNSu8 *) inTXT;
+       end = p + inTXTSize;
+       i       = 0;
+       
+       while( p < end )
+       {
+               size = *p++;
+               if( ( p + size ) > end )
+               {
+                       printf( "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
+                       break;
+               }
+               printf( "%2d (%3d bytes): \"%.*s\"\n", i, size, size, p );
+               p += size;
+               ++i;
+       }
+       printf( "\n" );
+}
+#endif // DEBUG
diff --git a/mDNSVxWorks/mDNSVxWorksIPv4Only.h b/mDNSVxWorks/mDNSVxWorksIPv4Only.h
new file mode 100644 (file)
index 0000000..3c3cdf5
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+       Contains:       mDNS platform plugin for VxWorks.
+
+       Copyright:  Copyright (C) 2002-2003 Apple Computer, Inc., All Rights Reserved.
+
+       Change History (most recent first):
+
+$Log: mDNSVxWorksIPv4Only.h,v $
+Revision 1.3  2004/09/17 01:08:57  cheshire
+Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
+  The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
+  declared in that file are ONLY appropriate to single-address-space embedded applications.
+  For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
+
+Revision 1.2  2003/08/12 19:56:27  cheshire
+Update to APSL 2.0
+
+Revision 1.1  2003/08/02 10:06:49  bradley
+mDNS platform plugin for VxWorks.
+
+*/
+
+#ifndef        __MDNS_VXWORKS__
+#define        __MDNS_VXWORKS__
+
+#include       "vxWorks.h"
+#include       "semLib.h"
+
+#include       "mDNSEmbeddedAPI.h"
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+// Forward Declarations
+
+typedef struct MDNSInterfaceItem       MDNSInterfaceItem;
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!    @struct         mDNS_PlatformSupport_struct
+
+       @abstract       Structure containing platform-specific data.
+*/
+
+struct mDNS_PlatformSupport_struct
+{
+       SEM_ID                                  lockID;
+       SEM_ID                                  readyEvent;
+       mStatus                                 taskInitErr;
+       SEM_ID                                  quitEvent;
+       MDNSInterfaceItem *             interfaceList;
+       int                                             commandPipe;
+       int                                             task;
+       mDNSBool                                quit;
+       long                                    configID;
+       int                                             rescheduled;
+};
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!    @function       mDNSReconfigure
+       
+       @abstract       Tell mDNS that the configuration has changed. Call when IP address changes, link goes up after being down, etc.
+       
+       @discussion
+       
+       VxWorks does not provide a generic mechanism for getting notified when network interfaces change so this routines
+       provides a way for BSP-specific code to signal mDNS that something has changed and it should re-build its interfaces.
+*/
+
+void   mDNSReconfigure( void );
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!    @struct         ifaddrs
+
+       @abstract       Interface information
+*/
+
+struct ifaddrs
+{
+       struct ifaddrs *        ifa_next;
+       char *                          ifa_name;
+       u_int                           ifa_flags;
+       struct sockaddr *       ifa_addr;
+       struct sockaddr *       ifa_netmask;
+       struct sockaddr *       ifa_dstaddr;
+       void *                          ifa_data;
+};
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!    @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 );
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!    @function       sock_pton
+
+       @abstract       Converts a 'p'resentation address string into a 'n'umeric sockaddr structure.
+       
+       @result         0 if successful or an error code on failure.
+*/
+
+int    sock_pton( const char *inString, int inFamily, void *outAddr, size_t inAddrSize, size_t *outAddrSize );
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!    @function       sock_ntop
+
+       @abstract       Converts a 'n'umeric sockaddr structure into a 'p'resentation address string.
+       
+       @result         Ptr to 'p'resentation address string buffer if successful or NULL on failure.
+*/
+
+char * sock_ntop( const void *inAddr, size_t inAddrSize, char *inBuffer, size_t inBufferSize );
+
+#ifdef __cplusplus
+       }
+#endif
+
+#endif // __MDNS_VXWORKS__
old mode 100755 (executable)
new mode 100644 (file)
index 868746b..2d361a8
@@ -1,62 +1,62 @@
-/*\r
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.\r
- *\r
- * @APPLE_LICENSE_HEADER_START@\r
- * \r
- * This file contains Original Code and/or Modifications of Original Code\r
- * as defined in and that are subject to the Apple Public Source License\r
- * Version 2.0 (the 'License'). You may not use this file except in\r
- * compliance with the License. Please obtain a copy of the License at\r
- * http://www.opensource.apple.com/apsl/ and read it before using this\r
- * file.\r
- * \r
- * The Original Code and all software distributed under the License are\r
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER\r
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\r
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\r
- * Please see the License for the specific language governing rights and\r
- * limitations under the License.\r
- * \r
- * @APPLE_LICENSE_HEADER_END@\r
-\r
-    Change History (most recent first):\r
-\r
+/*
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+    Change History (most recent first):
+
 $Log: ConfigDialog.h,v $
 Revision 1.2  2005/03/03 19:55:21  shersche
 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
-\r
-\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "stdafx.h"\r
-#include "resource.h"\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CConfigDialog\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-class CConfigDialog : public CDialog\r
-{\r
-public:\r
-\r
-       CConfigDialog();\r
-\r
-protected:\r
-\r
-       //{{AFX_DATA(CConfigDialog)\r
-       enum { IDD = IDR_APPLET };\r
-       //}}AFX_DATA\r
-\r
-       //{{AFX_VIRTUAL(CConfigDialog)\r
-       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support\r
-       //}}AFX_VIRTUAL\r
-\r
-       //{{AFX_MSG(CConfigDialog)\r
-       //}}AFX_MSG\r
-       DECLARE_MESSAGE_MAP()\r
-\r
-       DECLARE_DYNCREATE(CConfigDialog)\r
-};\r
+
+
+*/
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CConfigDialog
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CConfigDialog : public CDialog
+{
+public:
+
+       CConfigDialog();
+
+protected:
+
+       //{{AFX_DATA(CConfigDialog)
+       enum { IDD = IDR_APPLET };
+       //}}AFX_DATA
+
+       //{{AFX_VIRTUAL(CConfigDialog)
+       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+       //}}AFX_VIRTUAL
+
+       //{{AFX_MSG(CConfigDialog)
+       //}}AFX_MSG
+       DECLARE_MESSAGE_MAP()
+
+       DECLARE_DYNCREATE(CConfigDialog)
+};
old mode 100755 (executable)
new mode 100644 (file)
index ddae9e7..04491d0
@@ -1,35 +1,35 @@
-;\r
-; Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.\r
-;\r
-; @APPLE_LICENSE_HEADER_START@\r
-; \r
-; This file contains Original Code and/or Modifications of Original Code\r
-; as defined in and that are subject to the Apple Public Source License\r
-; Version 2.0 (the 'License'). You may not use this file except in\r
-; compliance with the License. Please obtain a copy of the License at\r
-; http://www.opensource.apple.com/apsl/ and read it before using this\r
-; file.\r
-; \r
-; The Original Code and all software distributed under the License are\r
-; distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER\r
-; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\r
-; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\r
-; FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\r
-; Please see the License for the specific language governing rights and\r
-; limitations under the License.\r
-; \r
-; @APPLE_LICENSE_HEADER_END@\r
-;\r
-;  Change History (most recent first):\r
-;\r
+;
+; Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+;
+; @APPLE_LICENSE_HEADER_START@
+; 
+; This file contains Original Code and/or Modifications of Original Code
+; as defined in and that are subject to the Apple Public Source License
+; Version 2.0 (the 'License'). You may not use this file except in
+; compliance with the License. Please obtain a copy of the License at
+; http://www.opensource.apple.com/apsl/ and read it before using this
+; file.
+; 
+; The Original Code and all software distributed under the License are
+; distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+; FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+; Please see the License for the specific language governing rights and
+; limitations under the License.
+; 
+; @APPLE_LICENSE_HEADER_END@
+;
+;  Change History (most recent first):
+;
 ;  $Log: ControlPanel.def,v $
 ;  Revision 1.3  2005/03/03 19:55:22  shersche
 ;  <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
-;\r
-;\r
-;\r
-    \r
-LIBRARY        "Bonjour"\r
-\r
-EXPORTS\r
-       CPlApplet\r
+;
+;
+;
+    
+LIBRARY        "Bonjour"
+
+EXPORTS
+       CPlApplet
old mode 100755 (executable)
new mode 100644 (file)
index 538fbf0..847639e
@@ -1,98 +1,98 @@
-/*\r
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.\r
- *\r
- * @APPLE_LICENSE_HEADER_START@\r
- * \r
- * This file contains Original Code and/or Modifications of Original Code\r
- * as defined in and that are subject to the Apple Public Source License\r
- * Version 2.0 (the 'License'). You may not use this file except in\r
- * compliance with the License. Please obtain a copy of the License at\r
- * http://www.opensource.apple.com/apsl/ and read it before using this\r
- * file.\r
- * \r
- * The Original Code and all software distributed under the License are\r
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER\r
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\r
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\r
- * Please see the License for the specific language governing rights and\r
- * limitations under the License.\r
- * \r
- * @APPLE_LICENSE_HEADER_END@\r
-\r
-    Change History (most recent first):\r
-\r
+/*
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+    Change History (most recent first):
+
 $Log: ControlPanel.h,v $
 Revision 1.2  2005/03/03 19:55:21  shersche
 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
-\r
-\r
-*/\r
-\r
-    \r
-#pragma once\r
-\r
-#include "stdafx.h"\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CCPApplet\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-class CCPApplet : public CCmdTarget\r
-{\r
-public:\r
-\r
-       CCPApplet( UINT nResourceID, UINT nDescriptionID, CRuntimeClass* pUIClass );\r
-\r
-       virtual ~CCPApplet();\r
-\r
-protected:\r
-\r
-       virtual LRESULT OnRun(CWnd* pParentWnd);\r
-       virtual LRESULT OnStartParms(CWnd* pParentWnd, LPCTSTR lpszExtra);\r
-       virtual LRESULT OnInquire(CPLINFO* pInfo);\r
-       virtual LRESULT OnNewInquire(NEWCPLINFO* pInfo);\r
-       virtual LRESULT OnSelect();\r
-       virtual LRESULT OnStop();\r
-\r
-       CRuntimeClass   *       m_uiClass;\r
-       UINT                            m_resourceId;\r
-       UINT                            m_descId;\r
-       CString                         m_name;\r
-       int                                     m_pageNumber;\r
-  \r
-       friend class CCPApp;\r
-\r
-       DECLARE_DYNAMIC(CCPApplet);\r
-};\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CCPApp\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-class CCPApp : public CWinApp\r
-{\r
-public:\r
-\r
-       CCPApp();\r
-       virtual ~CCPApp();\r
-\r
-       void AddApplet( CCPApplet* pApplet );\r
-\r
-protected:\r
-\r
-       CList<CCPApplet*, CCPApplet*&> m_applets;\r
-\r
-       friend LONG APIENTRY\r
-       CPlApplet(HWND hWndCPl, UINT uMsg, LONG lParam1, LONG lParam2);\r
-\r
-       virtual LRESULT OnCplMsg(HWND hWndCPl, UINT msg, LPARAM lp1, LPARAM lp2);\r
-       virtual LRESULT OnInit();\r
-       virtual LRESULT OnExit();\r
-\r
-       DECLARE_DYNAMIC(CCPApp);\r
-};\r
-\r
-\r
-CCPApp * GetControlPanelApp();\r
+
+
+*/
+
+    
+#pragma once
+
+#include "stdafx.h"
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CCPApplet
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CCPApplet : public CCmdTarget
+{
+public:
+
+       CCPApplet( UINT nResourceID, UINT nDescriptionID, CRuntimeClass* pUIClass );
+
+       virtual ~CCPApplet();
+
+protected:
+
+       virtual LRESULT OnRun(CWnd* pParentWnd);
+       virtual LRESULT OnStartParms(CWnd* pParentWnd, LPCTSTR lpszExtra);
+       virtual LRESULT OnInquire(CPLINFO* pInfo);
+       virtual LRESULT OnNewInquire(NEWCPLINFO* pInfo);
+       virtual LRESULT OnSelect();
+       virtual LRESULT OnStop();
+
+       CRuntimeClass   *       m_uiClass;
+       UINT                            m_resourceId;
+       UINT                            m_descId;
+       CString                         m_name;
+       int                                     m_pageNumber;
+  
+       friend class CCPApp;
+
+       DECLARE_DYNAMIC(CCPApplet);
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CCPApp
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CCPApp : public CWinApp
+{
+public:
+
+       CCPApp();
+       virtual ~CCPApp();
+
+       void AddApplet( CCPApplet* pApplet );
+
+protected:
+
+       CList<CCPApplet*, CCPApplet*&> m_applets;
+
+       friend LONG APIENTRY
+       CPlApplet(HWND hWndCPl, UINT uMsg, LONG lParam1, LONG lParam2);
+
+       virtual LRESULT OnCplMsg(HWND hWndCPl, UINT msg, LPARAM lp1, LPARAM lp2);
+       virtual LRESULT OnInit();
+       virtual LRESULT OnExit();
+
+       DECLARE_DYNAMIC(CCPApp);
+};
+
+
+CCPApp * GetControlPanelApp();
old mode 100755 (executable)
new mode 100644 (file)
index 51dbb77..c44dc20
-// 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 "afxres.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
-/////////////////////////////////////////////////////////////////////////////\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 "040904b0"\r
-        BEGIN\r
-            VALUE "CompanyName", "Apple Computer, Inc."\r
-            VALUE "FileDescription", "Bonjour Configuration Applet"\r
-            VALUE "FileVersion", MASTER_PROD_VERS_STR\r
-            VALUE "InternalName", "Bonjour.cpl"\r
-            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT\r
-            VALUE "OriginalFilename", "Bonjour.cpl"\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, 1200\r
-    END\r
-END\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 ""afxres.h""\r\n"\r
-    "\0"\r
-END\r
-\r
-3 TEXTINCLUDE \r
-BEGIN\r
-    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"\r
-    "#define _AFX_NO_OLE_RESOURCES\r\n"\r
-    "#define _AFX_NO_TRACKER_RESOURCES\r\n"\r
-    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"\r
-    "\r\n"\r
-    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"\r
-    "#ifdef _WIN32\r\n"\r
-    "LANGUAGE 9, 1\r\n"\r
-    "#pragma code_page(1252)\r\n"\r
-    "#endif\r\n"\r
-    "#include ""res\\ControlPanel.rc2""  // non-Microsoft Visual C++ edited resources\r\n"\r
-    "#include ""afxres.rc""         // Standard components\r\n"\r
-    "#endif\0"\r
-END\r
-\r
-#endif    // APSTUDIO_INVOKED\r
-\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Icon\r
-//\r
-\r
-// Icon with lowest ID value placed first to ensure application icon\r
-// remains consistent on all systems.\r
-IDR_APPLET              ICON                    "res\\controlpanel.ico"\r
-IDI_FAILURE             ICON                    "res\\failure.ico"\r
-IDI_SUCCESS             ICON                    "res\\success.ico"\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Dialog\r
-//\r
-\r
-IDR_APPLET_PAGE1 DIALOGEX 0, 0, 262, 140\r
-STYLE DS_SETFONT | WS_CHILD | WS_CAPTION\r
-CAPTION "Hostname"\r
-FONT 8, "MS Sans Serif", 0, 0, 0x0\r
-BEGIN\r
-    LTEXT           "Enter a hostname for this computer. Other computers on the Internet will be able to reach your computer using this hostname.",\r
-                    IDC_STATIC,10,19,245,28\r
-    LTEXT           "Hostname:",IDC_STATIC,13,55,35,8\r
-    EDITTEXT        IDC_EDIT1,55,53,184,14,ES_AUTOHSCROLL\r
-    PUSHBUTTON      "Password...",IDC_BUTTON1,55,72,65,14\r
-    ICON            IDI_FAILURE,IDC_FAILURE,240,50,20,20,SS_CENTERIMAGE | \r
-                    SS_REALSIZEIMAGE\r
-    ICON            IDI_SUCCESS,IDC_SUCCESS,240,50,20,20,SS_CENTERIMAGE | \r
-                    SS_REALSIZEIMAGE | NOT WS_VISIBLE\r
-END\r
-\r
-IDR_APPLET_PAGE2 DIALOGEX 0, 0, 262, 140\r
-STYLE DS_SETFONT | WS_CHILD | WS_CAPTION\r
-CAPTION "Registration"\r
-FONT 8, "MS Sans Serif", 0, 0, 0x0\r
-BEGIN\r
-    CONTROL         "Domain:",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | \r
-                    WS_TABSTOP,13,54,41,10\r
-    COMBOBOX        IDC_COMBO2,55,53,193,46,CBS_DROPDOWN | CBS_SORT | \r
-                    WS_DISABLED | WS_VSCROLL | WS_TABSTOP\r
-    PUSHBUTTON      "Password...",IDC_BUTTON1,55,72,65,14\r
-    LTEXT           "Check the box and enter a registration domain to enable Bonjour advertising beyond the local subnet. ",\r
-                    IDC_STATIC,10,19,233,23\r
-END\r
-\r
-IDR_SECRET DIALOGEX 0, 0, 251, 90\r
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | \r
-    WS_SYSMENU\r
-CAPTION "Password"\r
-FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
-BEGIN\r
-    DEFPUSHBUTTON   "OK",IDOK,139,69,50,14\r
-    PUSHBUTTON      "Cancel",IDCANCEL,194,69,50,14\r
-    LTEXT           "Name:",IDC_STATIC,9,28,22,8\r
-    EDITTEXT        IDC_KEY,36,26,208,14,ES_AUTOHSCROLL\r
-    LTEXT           "Secret:",IDC_STATIC,9,44,24,8\r
-    EDITTEXT        IDC_SECRET,36,42,208,14,ES_PASSWORD | ES_AUTOHSCROLL\r
-    LTEXT           "Enter a Password if your DNS server requires authentication.",\r
-                    IDC_STATIC,7,7,237,15\r
-END\r
-\r
-IDR_APPLET_PAGE3 DIALOGEX 0, 0, 262, 140\r
-STYLE DS_SETFONT | WS_CHILD | WS_CAPTION\r
-CAPTION "Browsing"\r
-FONT 8, "MS Sans Serif", 0, 0, 0x0\r
-BEGIN\r
-    LTEXT           "Choose which domains to browse using Wide-Area Bonjour",\r
-                    -1,7,16,248,12\r
-    CONTROL         "",IDC_BROWSE_LIST,"SysListView32",LVS_REPORT | \r
-                    LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | \r
-                    WS_TABSTOP,7,37,248,57\r
-    PUSHBUTTON      "Add",IDC_ADD_BROWSE_DOMAIN,152,100,50,14\r
-    PUSHBUTTON      "Remove",IDC_REMOVE_BROWSE_DOMAIN,205,100,50,14\r
-END\r
-\r
-IDR_ADD_BROWSE_DOMAIN DIALOGEX 0, 0, 230, 95\r
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | \r
-    WS_SYSMENU\r
-CAPTION "Add Browse Domain"\r
-FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
-BEGIN\r
-    DEFPUSHBUTTON   "OK",IDOK,117,74,50,14\r
-    PUSHBUTTON      "Cancel",IDCANCEL,173,74,50,14\r
-    COMBOBOX        IDC_COMBO1,35,42,188,100,CBS_DROPDOWN | CBS_SORT | \r
-                    WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Domain:",IDC_STATIC,7,43,27,8\r
-    LTEXT           "The following domain will be added to your list of Bonjour browse domains.",\r
-                    IDC_STATIC,7,15,216,16\r
-END\r
-\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// DESIGNINFO\r
-//\r
-\r
-#ifdef APSTUDIO_INVOKED\r
-GUIDELINES DESIGNINFO \r
-BEGIN\r
-    IDR_APPLET_PAGE1, DIALOG\r
-    BEGIN\r
-        LEFTMARGIN, 7\r
-        RIGHTMARGIN, 255\r
-        TOPMARGIN, 7\r
-        BOTTOMMARGIN, 133\r
-    END\r
-\r
-    IDR_APPLET_PAGE2, DIALOG\r
-    BEGIN\r
-        LEFTMARGIN, 7\r
-        RIGHTMARGIN, 255\r
-        TOPMARGIN, 7\r
-        BOTTOMMARGIN, 133\r
-    END\r
-\r
-    IDR_SECRET, DIALOG\r
-    BEGIN\r
-        LEFTMARGIN, 7\r
-        RIGHTMARGIN, 244\r
-        TOPMARGIN, 7\r
-        BOTTOMMARGIN, 83\r
-    END\r
-\r
-    IDR_APPLET_PAGE3, DIALOG\r
-    BEGIN\r
-        LEFTMARGIN, 7\r
-        RIGHTMARGIN, 255\r
-        TOPMARGIN, 7\r
-        BOTTOMMARGIN, 133\r
-    END\r
-\r
-    IDR_ADD_BROWSE_DOMAIN, DIALOG\r
-    BEGIN\r
-        LEFTMARGIN, 7\r
-        RIGHTMARGIN, 223\r
-        TOPMARGIN, 7\r
-        BOTTOMMARGIN, 88\r
-    END\r
-END\r
-#endif    // APSTUDIO_INVOKED\r
-\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-//\r
-// String Table\r
-//\r
-\r
-STRINGTABLE \r
-BEGIN\r
-    IDR_APPLET              "Bonjour"\r
-    IDS_APPLET_DESCRIPTION  "Wide-Area Bonjour Control Panel"\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
-#define _AFX_NO_SPLITTER_RESOURCES\r
-#define _AFX_NO_OLE_RESOURCES\r
-#define _AFX_NO_TRACKER_RESOURCES\r
-#define _AFX_NO_PROPERTY_RESOURCES\r
-\r
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
-#ifdef _WIN32\r
-LANGUAGE 9, 1\r
-#pragma code_page(1252)\r
-#endif\r
-#include "res\ControlPanel.rc2"  // non-Microsoft Visual C++ edited resources\r
-#include "afxres.rc"         // Standard components\r
-#endif\r
-/////////////////////////////////////////////////////////////////////////////\r
-#endif    // not APSTUDIO_INVOKED\r
-\r
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "WinVersRes.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MASTER_PROD_VERS
+ PRODUCTVERSION MASTER_PROD_VERS
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Apple Computer, Inc."
+            VALUE "FileDescription", "Bonjour Configuration Applet"
+            VALUE "FileVersion", MASTER_PROD_VERS_STR
+            VALUE "InternalName", "Bonjour.cpl"
+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "Bonjour.cpl"
+            VALUE "ProductName", MASTER_PROD_NAME
+            VALUE "ProductVersion", MASTER_PROD_VERS_STR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_OLE_RESOURCES\r\n"
+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+    "#ifdef _WIN32\r\n"
+    "LANGUAGE 9, 1\r\n"
+    "#pragma code_page(1252)\r\n"
+    "#endif\r\n"
+    "#include ""res\\ControlPanel.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
+    "#include ""afxres.rc""         // Standard components\r\n"
+    "#endif\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_APPLET              ICON                    "res\\controlpanel.ico"
+IDI_FAILURE             ICON                    "res\\failure.ico"
+IDI_SUCCESS             ICON                    "res\\success.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDR_APPLET_PAGE1 DIALOGEX 0, 0, 262, 140
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Hostname"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    LTEXT           "Enter a hostname for this computer. Other computers on the Internet will be able to reach your computer using this hostname.",
+                    IDC_STATIC,7,19,248,28
+    LTEXT           "Hostname:",IDC_STATIC,15,55,35,8
+    EDITTEXT        IDC_EDIT1,52,53,187,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "Password...",IDC_BUTTON1,52,72,67,14
+    ICON            IDI_FAILURE,IDC_FAILURE,240,50,21,20,SS_CENTERIMAGE | 
+                    SS_REALSIZEIMAGE
+    ICON            IDI_SUCCESS,IDC_SUCCESS,240,50,21,20,SS_CENTERIMAGE | 
+                    SS_REALSIZEIMAGE | NOT WS_VISIBLE
+END
+
+IDR_APPLET_PAGE2 DIALOGEX 0, 0, 262, 140
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Registration"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    CONTROL         "Domain:",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,13,54,42,10
+    COMBOBOX        IDC_COMBO2,59,53,189,46,CBS_DROPDOWN | CBS_SORT | 
+                    WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "Password...",IDC_BUTTON1,59,72,65,14
+    LTEXT           "Check the box and enter a registration domain to enable Bonjour advertising beyond the local subnet. ",
+                    IDC_STATIC,14,20,233,23
+END
+
+IDR_SECRET DIALOGEX 0, 0, 251, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "Password"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,139,69,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,194,69,50,14
+    LTEXT           "Name:",IDC_STATIC,9,28,22,8
+    EDITTEXT        IDC_SECRET_NAME,36,26,208,14,ES_AUTOHSCROLL
+    LTEXT           "Secret:",IDC_STATIC,9,44,24,8
+    EDITTEXT        IDC_SECRET,36,42,208,14,ES_PASSWORD | ES_AUTOHSCROLL
+    LTEXT           "Enter a Password if your DNS server requires authentication.",
+                    IDC_STATIC,7,7,237,15
+END
+
+IDR_APPLET_PAGE3 DIALOGEX 0, 0, 262, 140
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Browsing"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    LTEXT           "Choose which domains to browse using Wide-Area Bonjour",
+                    -1,7,16,248,12
+    CONTROL         "",IDC_BROWSE_LIST,"SysListView32",LVS_REPORT | 
+                    LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | 
+                    WS_TABSTOP,7,37,248,57
+    PUSHBUTTON      "Add",IDC_ADD_BROWSE_DOMAIN,152,100,50,14
+    PUSHBUTTON      "Remove",IDC_REMOVE_BROWSE_DOMAIN,205,100,50,14
+END
+
+IDR_ADD_BROWSE_DOMAIN DIALOGEX 0, 0, 230, 95
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
+    WS_SYSMENU
+CAPTION "Add Browse Domain"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,117,74,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,173,74,50,14
+    COMBOBOX        IDC_COMBO1,35,42,188,30,CBS_DROPDOWN | CBS_SORT | 
+                    WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Domain:",IDC_STATIC,7,43,27,8
+    LTEXT           "The following domain will be added to your list of Bonjour browse domains.",
+                    IDC_STATIC,7,15,216,16
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDR_APPLET_PAGE1, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 255
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 133
+    END
+
+    IDR_APPLET_PAGE2, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 255
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 133
+    END
+
+    IDR_SECRET, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 244
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 83
+    END
+
+    IDR_APPLET_PAGE3, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 255
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 133
+    END
+
+    IDR_ADD_BROWSE_DOMAIN, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 223
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 88
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDR_APPLET              "Bonjour"
+    IDS_APPLET_DESCRIPTION  "Wide-Area Bonjour Control Panel"
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif
+#include "res\ControlPanel.rc2"  // non-Microsoft Visual C++ edited resources
+#include "afxres.rc"         // Standard components
+#endif
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
index 48cf1ffa4f58c2ee7e4a76c543f8e7e0a15e9775..9dfe4017c8ec20a17e9f18cbf2012ba57d2b51ca 100755 (executable)
@@ -23,9 +23,6 @@
     Change History (most recent first):
 
 $Log: FirstPage.cpp,v $
-Revision 1.4  2005/04/05 03:52:14  shersche
-<rdar://problem/4066485> Registering with shared secret key doesn't work. Additionally, mDNSResponder wasn't dynamically re-reading it's DynDNS setup after setting a shared secret key.
-
 Revision 1.3  2005/03/07 18:27:42  shersche
 <rdar://problem/4037940> Fix problem when ControlPanel commits changes to the browse domain list
 
@@ -54,8 +51,7 @@ CFirstPage::CFirstPage()
 :
        CPropertyPage(CFirstPage::IDD),
        m_ignoreHostnameChange( false ),
-       m_statusKey( NULL ),
-       m_setupKey( NULL )
+       m_statusKey( NULL )
 {
        //{{AFX_DATA_INIT(CFirstPage)
        //}}AFX_DATA_INIT
@@ -132,33 +128,12 @@ void CFirstPage::OnBnClickedSharedSecret()
 
        CSharedSecret dlg;
 
-       dlg.m_key = name;
+       dlg.m_secretName = name;
 
        if ( dlg.DoModal() == IDOK )
        {
-               DWORD           wakeup = 0;
-               DWORD           dwSize = sizeof( DWORD );
-               OSStatus        err;
-
-               dlg.Commit( name );
-
-               // We have now updated the secret, however the system service
-               // doesn't know about it yet.  So we're going to update the
-               // registry with a dummy value which will cause the system
-               // service to re-initialize it's DynDNS setup
-               //
-
-               RegQueryValueEx( m_setupKey, L"Wakeup", NULL, NULL, (LPBYTE) &wakeup, &dwSize );      
-
-               wakeup++;
-               
-               err = RegSetValueEx( m_setupKey, L"Wakeup", 0, REG_DWORD, (LPBYTE) &wakeup, sizeof( DWORD ) );
-               require_noerr( err, exit );
+               dlg.Commit();
        }
-
-exit:
-
-       return;
 }
 
 
index b14c7697472ae4f0381401a76f33113d71076f09..a330e84f4287104110c2f806a2e4e7c840d9227b 100755 (executable)
     Change History (most recent first):
 
 $Log: SecondPage.cpp,v $
-Revision 1.5  2005/04/05 04:15:46  shersche
-RegQueryString was returning uninitialized strings if the registry key couldn't be found, so always initialize strings before checking the registry key.
-
-Revision 1.4  2005/04/05 03:52:14  shersche
-<rdar://problem/4066485> Registering with shared secret key doesn't work. Additionally, mDNSResponder wasn't dynamically re-reading it's DynDNS setup after setting a shared secret key.
-
 Revision 1.3  2005/03/03 19:55:22  shersche
 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
 
@@ -52,16 +46,10 @@ IMPLEMENT_DYNCREATE(CSecondPage, CPropertyPage)
 
 CSecondPage::CSecondPage()
 :
-       CPropertyPage(CSecondPage::IDD),
-       m_setupKey( NULL )
+       CPropertyPage(CSecondPage::IDD)
 {
        //{{AFX_DATA_INIT(CSecondPage)
        //}}AFX_DATA_INIT
-
-       OSStatus err;
-
-       err = RegCreateKey( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" kServiceName L"\\Parameters\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, &m_setupKey );
-       check_noerr( err );
 }
 
 
@@ -71,11 +59,6 @@ CSecondPage::CSecondPage()
 
 CSecondPage::~CSecondPage()
 {
-       if ( m_setupKey )
-       {
-               RegCloseKey( m_setupKey );
-               m_setupKey = NULL;
-       }
 }
 
 
@@ -126,6 +109,7 @@ BOOL
 CSecondPage::OnSetActive()
 {
        CConfigPropertySheet    *       psheet;
+       HKEY                                            key = NULL;
        DWORD                                           dwSize;
        DWORD                                           enabled;
        DWORD                                           err;
@@ -142,15 +126,20 @@ CSecondPage::OnSetActive()
 
        // Now populate the registration domain box
 
-       err = Populate( m_regDomainsBox, m_setupKey, psheet->m_regDomains );
+       err = RegCreateKey( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" kServiceName L"\\Parameters\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, &key );
+       require_noerr( err, exit );
+
+       err = Populate( m_regDomainsBox, key, psheet->m_regDomains );
        check_noerr( err );
 
        dwSize = sizeof( DWORD );
-       err = RegQueryValueEx( m_setupKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+       err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
        m_advertiseServicesButton.SetCheck( ( !err && enabled ) ? BST_CHECKED : BST_UNCHECKED );
        m_regDomainsBox.EnableWindow( ( !err && enabled ) );
        m_sharedSecretButton.EnableWindow( (!err && enabled ) );
 
+       RegCloseKey( key );
+
 exit:
 
        return b;
@@ -179,12 +168,20 @@ CSecondPage::OnOK()
 void
 CSecondPage::Commit()
 {
-       DWORD err;
+       HKEY            key = NULL;
+       DWORD           err;
 
-       if ( m_setupKey != NULL )
+       err = RegCreateKey( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" kServiceName L"\\Parameters\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, &key );
+       require_noerr( err, exit );
+
+       err = Commit( m_regDomainsBox, key, m_advertiseServicesButton.GetCheck() == BST_CHECKED );
+       check_noerr( err );
+       
+exit:
+
+       if ( key )
        {
-               err = Commit( m_regDomainsBox, m_setupKey, m_advertiseServicesButton.GetCheck() == BST_CHECKED );
-               check_noerr( err );
+               RegCloseKey( key );
        }
 }
 
@@ -247,39 +244,15 @@ CSecondPage::Commit( CComboBox & box, HKEY key, DWORD enabled )
 
 void CSecondPage::OnBnClickedSharedSecret()
 {
-       CString name;
+       CString string;
 
-       m_regDomainsBox.GetWindowText( name );
+       m_regDomainsBox.GetWindowText( string );
 
        CSharedSecret dlg;
 
-       dlg.m_key = name;
-
-       if ( dlg.DoModal() == IDOK )
-       {
-               DWORD           wakeup = 0;
-               DWORD           dwSize = sizeof( DWORD );
-               OSStatus        err;
-
-               dlg.Commit( name );
-
-               // We have now updated the secret, however the system service
-               // doesn't know about it yet.  So we're going to update the
-               // registry with a dummy value which will cause the system
-               // service to re-initialize it's DynDNS setup
-               //
-
-               RegQueryValueEx( m_setupKey, L"Wakeup", NULL, NULL, (LPBYTE) &wakeup, &dwSize );      
-
-               wakeup++;
-               
-               err = RegSetValueEx( m_setupKey, L"Wakeup", 0, REG_DWORD, (LPBYTE) &wakeup, sizeof( DWORD ) );
-               require_noerr( err, exit );
-       }
-
-exit:
+       dlg.m_secretName = string;
 
-       return;
+       dlg.DoModal();
 }
 
 
@@ -497,7 +470,6 @@ CSecondPage::RegQueryString( HKEY key, CString valueName, CString & value )
 
                string = (TCHAR*) malloc( stringLen );
                require_action( string, exit, err = kUnknownErr );
-               *string = '\0';
 
                err = RegQueryValueEx( key, valueName, 0, NULL, (LPBYTE) string, &stringLen );
 
index 917608edad7806ae6aec3b1c84fd8df12b4c9427..a8d1f09a0a866c63bd22eaed670bd1b1da312bf0 100755 (executable)
@@ -23,9 +23,6 @@
     Change History (most recent first):
 
 $Log: SecondPage.h,v $
-Revision 1.4  2005/04/05 03:52:14  shersche
-<rdar://problem/4066485> Registering with shared secret key doesn't work. Additionally, mDNSResponder wasn't dynamically re-reading it's DynDNS setup after setting a shared secret key.
-
 Revision 1.3  2005/03/03 19:55:21  shersche
 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
 
@@ -116,7 +113,6 @@ private:
        CButton                 m_advertiseServicesButton;
        CButton                 m_sharedSecretButton;
        BOOL                    m_modified;
-       HKEY                    m_setupKey;
 
 public:
        afx_msg void OnCbnSelChange();
old mode 100755 (executable)
new mode 100644 (file)
index 29636df..e690b49
-/*\r
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.\r
- *\r
- * @APPLE_LICENSE_HEADER_START@\r
- * \r
- * This file contains Original Code and/or Modifications of Original Code\r
- * as defined in and that are subject to the Apple Public Source License\r
- * Version 2.0 (the 'License'). You may not use this file except in\r
- * compliance with the License. Please obtain a copy of the License at\r
- * http://www.opensource.apple.com/apsl/ and read it before using this\r
- * file.\r
- * \r
- * The Original Code and all software distributed under the License are\r
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER\r
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\r
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\r
- * Please see the License for the specific language governing rights and\r
- * limitations under the License.\r
- * \r
- * @APPLE_LICENSE_HEADER_END@\r
-\r
-    Change History (most recent first):\r
-\r
-$Log: SharedSecret.cpp,v $
-Revision 1.3  2005/04/06 02:04:49  shersche
-<rdar://problem/4066485> Registering with shared secret doesn't work
+/*
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+    Change History (most recent first):
 
+$Log: SharedSecret.cpp,v $
 Revision 1.2  2005/03/03 19:55:22  shersche
 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
-\r
-\r
-*/\r
-\r
-    \r
-// SharedSecret.cpp : implementation file\r
-//\r
-\r
-#include "stdafx.h"\r
-#include "SharedSecret.h"\r
-\r
-#include <DebugServices.h>\r
-#include <ntsecapi.h>\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     Private declarations\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-static BOOL\r
-InitLsaString\r
-                       (\r
-                       PLSA_UNICODE_STRING     pLsaString,\r
-                       LPCWSTR                         pwszString\r
-                       );\r
-\r
-// SharedSecret dialog\r
-\r
-IMPLEMENT_DYNAMIC(CSharedSecret, CDialog)\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CSharedSecret::CSharedSecret\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-CSharedSecret::CSharedSecret(CWnd* pParent /*=NULL*/)\r
-       : CDialog(CSharedSecret::IDD, pParent)\r
-       , m_key(_T(""))\r
-       , m_secret(_T(""))\r
-{\r
-}\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CSharedSecret::~CSharedSecret\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-CSharedSecret::~CSharedSecret()\r
-{\r
-}\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CSharedSecret::DoDataExchange\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-void CSharedSecret::DoDataExchange(CDataExchange* pDX)\r
-{\r
-       CDialog::DoDataExchange(pDX);\r
-       DDX_Text(pDX, IDC_KEY, m_key );\r
-       DDX_Text(pDX, IDC_SECRET, m_secret );\r
-}\r
-\r
-\r
-BEGIN_MESSAGE_MAP(CSharedSecret, CDialog)\r
-END_MESSAGE_MAP()\r
-\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CSharedSecret::Commit\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-void\r
-CSharedSecret::Commit( CString zone )\r
-{\r
-       LSA_OBJECT_ATTRIBUTES   attrs;\r
-       LSA_HANDLE                              handle = NULL;\r
-       NTSTATUS                                res;\r
-       LSA_UNICODE_STRING              lucZoneName;\r
-       LSA_UNICODE_STRING              lucKeyName;\r
-       LSA_UNICODE_STRING              lucSecretName;\r
-       BOOL                                    ok;\r
-       OSStatus                                err;\r
-\r
-       // If there isn't a trailing dot, add one because the mDNSResponder\r
-       // presents names with the trailing dot.\r
-\r
-       if ( zone.ReverseFind( '.' ) != zone.GetLength() )\r
-       {\r
-               zone += '.';\r
-       }\r
-\r
-       if ( m_key.ReverseFind( '.' ) != m_key.GetLength() )\r
-       {\r
-               m_key += '.';\r
-       }\r
-\r
-       // attrs are reserved, so initialize to zeroes.\r
-\r
-       ZeroMemory( &attrs, sizeof( attrs ) );\r
-\r
-       // Get a handle to the Policy object on the local system\r
-\r
-       res = LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle );\r
-       err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );\r
-       require_noerr( err, exit );\r
-\r
-       // Intializing PLSA_UNICODE_STRING structures\r
-\r
-       ok = InitLsaString( &lucZoneName, zone );\r
-       err = translate_errno( ok, errno_compat(), kUnknownErr );\r
-       require_noerr( err, exit );\r
\r
-       ok = InitLsaString( &lucKeyName, m_key );\r
-       err = translate_errno( ok, errno_compat(), kUnknownErr );\r
-       require_noerr( err, exit );\r
-\r
-       ok = InitLsaString( &lucSecretName, m_secret );\r
-       err = translate_errno( ok, errno_compat(), kUnknownErr );\r
-       require_noerr( err, exit );\r
-\r
-       // Store the private data.\r
-\r
-       res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName );\r
-       err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );\r
-       require_noerr( err, exit );\r
-\r
-       res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName );\r
-       err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );\r
-       require_noerr( err, exit );\r
-\r
-exit:\r
-\r
-       if ( handle )\r
-       {\r
-               LsaClose( handle );\r
-               handle = NULL;\r
-       }\r
-\r
-       return;\r
-}\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     InitLsaString\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-static BOOL\r
-InitLsaString\r
-               (\r
-               PLSA_UNICODE_STRING     pLsaString,\r
-               LPCWSTR                         pwszString\r
-               )\r
-{\r
-       size_t  dwLen   = 0;\r
-       BOOL    ret             = FALSE;\r
-       \r
-       if ( pLsaString == NULL )\r
-       {\r
-               goto exit;\r
-       }\r
-\r
-       if ( pwszString != NULL ) \r
-       {\r
-               dwLen = wcslen(pwszString);\r
-\r
-               // String is too large\r
-               if (dwLen > 0x7ffe)\r
-               {\r
-                       goto exit;\r
-               }\r
-       }\r
-\r
-       // Store the string.\r
-  \r
-       pLsaString->Buffer                      = (WCHAR *) pwszString;\r
-       pLsaString->Length                      = (USHORT) dwLen * sizeof(WCHAR);\r
-       pLsaString->MaximumLength       = (USHORT)(dwLen+1) * sizeof(WCHAR);\r
-\r
-       ret = TRUE;\r
-\r
-exit:\r
-\r
-       return ret;\r
-}\r
+
+
+*/
+
+    
+// SharedSecret.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "SharedSecret.h"
+
+#include <DebugServices.h>
+#include <ntsecapi.h>
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     Private declarations
+//---------------------------------------------------------------------------------------------------------------------------
+
+static BOOL
+InitLsaString
+                       (
+                       PLSA_UNICODE_STRING     pLsaString,
+                       LPCWSTR                         pwszString
+                       );
+
+// SharedSecret dialog
+
+IMPLEMENT_DYNAMIC(CSharedSecret, CDialog)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CSharedSecret::CSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+CSharedSecret::CSharedSecret(CWnd* pParent /*=NULL*/)
+       : CDialog(CSharedSecret::IDD, pParent)
+       , m_secret(_T(""))
+       , m_secretName(_T(""))
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CSharedSecret::~CSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+CSharedSecret::~CSharedSecret()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CSharedSecret::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSharedSecret::DoDataExchange(CDataExchange* pDX)
+{
+       CDialog::DoDataExchange(pDX);
+       DDX_Text(pDX, IDC_SECRET, m_secret);
+       DDX_Text(pDX, IDC_SECRET_NAME, m_secretName);
+}
+
+
+BEGIN_MESSAGE_MAP(CSharedSecret, CDialog)
+END_MESSAGE_MAP()
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CSharedSecret::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSharedSecret::Commit()
+{
+       LSA_OBJECT_ATTRIBUTES   attrs;
+       LSA_HANDLE                              handle = NULL;
+       NTSTATUS                                res;
+       LSA_UNICODE_STRING              lucKeyName;
+       LSA_UNICODE_STRING              lucPrivateData;
+       BOOL                                    ok;
+       OSStatus                                err;
+
+       // If there isn't a trailing dot, add one because the mDNSResponder
+       // presents names with the trailing dot.
+
+       if ( m_secretName.ReverseFind( '.' ) != m_secretName.GetLength() )
+       {
+               m_secretName += '.';
+       }
+
+       // 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( &lucKeyName, m_secretName );
+       err = translate_errno( ok, errno_compat(), kUnknownErr );
+       require_noerr( err, exit );
+
+       ok = InitLsaString( &lucPrivateData, m_secret );
+       err = translate_errno( ok, errno_compat(), kUnknownErr );
+       require_noerr( err, exit );
+
+       // Store the private data.
+
+       res = LsaStorePrivateData( handle, &lucKeyName, &lucPrivateData );
+       err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+       require_noerr( err, exit );
+
+exit:
+
+       if ( handle )
+       {
+               LsaClose( handle );
+               handle = NULL;
+       }
+
+       return;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     InitLsaString
+//---------------------------------------------------------------------------------------------------------------------------
+
+static BOOL
+InitLsaString
+               (
+               PLSA_UNICODE_STRING     pLsaString,
+               LPCWSTR                         pwszString
+               )
+{
+       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;
+
+exit:
+
+       return ret;
+}
old mode 100755 (executable)
new mode 100644 (file)
index 804f6b4..9982d78
@@ -1,68 +1,64 @@
-/*\r
- * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.\r
- *\r
- * @APPLE_LICENSE_HEADER_START@\r
- * \r
- * This file contains Original Code and/or Modifications of Original Code\r
- * as defined in and that are subject to the Apple Public Source License\r
- * Version 2.0 (the 'License'). You may not use this file except in\r
- * compliance with the License. Please obtain a copy of the License at\r
- * http://www.opensource.apple.com/apsl/ and read it before using this\r
- * file.\r
- * \r
- * The Original Code and all software distributed under the License are\r
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER\r
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\r
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\r
- * Please see the License for the specific language governing rights and\r
- * limitations under the License.\r
- * \r
- * @APPLE_LICENSE_HEADER_END@\r
-\r
-    Change History (most recent first):\r
-\r
-$Log: SharedSecret.h,v $
-Revision 1.3  2005/04/06 02:04:49  shersche
-<rdar://problem/4066485> Registering with shared secret doesn't work
+/*
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+    Change History (most recent first):
 
+$Log: SharedSecret.h,v $
 Revision 1.2  2005/03/03 19:55:21  shersche
 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
-\r
-\r
-*/\r
-\r
-    \r
-#pragma once\r
-\r
-#include "resource.h"\r
-\r
-\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-//     CSharedSecret\r
-//---------------------------------------------------------------------------------------------------------------------------\r
-\r
-class CSharedSecret : public CDialog\r
-{\r
-       DECLARE_DYNAMIC(CSharedSecret)\r
-\r
-public:\r
-       CSharedSecret(CWnd* pParent = NULL);   // standard constructor\r
-       virtual ~CSharedSecret();\r
-\r
-// Dialog Data\r
-       enum { IDD = IDR_SECRET };\r
-\r
-       void\r
-       Commit( CString zone );\r
-\r
-protected:\r
-       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support\r
-\r
-       DECLARE_MESSAGE_MAP()\r
-\r
-public:\r
-\r
-       CString m_key;\r
-       CString m_secret;\r
-};\r
+
+
+*/
+
+    
+#pragma once
+
+#include "resource.h"
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//     CSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CSharedSecret : public CDialog
+{
+       DECLARE_DYNAMIC(CSharedSecret)
+
+public:
+       CSharedSecret(CWnd* pParent = NULL);   // standard constructor
+       virtual ~CSharedSecret();
+
+// Dialog Data
+       enum { IDD = IDR_SECRET };
+
+       void
+       Commit();
+
+protected:
+       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+       DECLARE_MESSAGE_MAP()
+
+public:
+       CString m_secret;
+       CString m_secretName;
+};
old mode 100755 (executable)
new mode 100644 (file)
index a4e4014..9baf23c
@@ -1,43 +1,41 @@
-//{{NO_DEPENDENCIES}}\r
-// Microsoft Visual C++ generated include file.\r
-// Used by ControlPanel.rc\r
-//\r
-#define IDR_APPLET                      131\r
-#define IDR_APPLET_PAGE1                131\r
-#define IDS_APPLET_DESCRIPTION          132\r
-#define IDR_APPLET_PAGE2                132\r
-#define IDR_SECRET                      133\r
-#define IDR_APPLET_PAGE3                134\r
-#define IDI_FAILURE                     140\r
-#define IDI_SUCCESS                     141\r
-#define IDD_ADD_BROWSE_DOMAIN           142\r
-#define IDR_ADD_BROWSE_DOMAIN           142\r
-#define IDC_EDIT1                       1000\r
-#define IDC_BUTTON1                     1001\r
-#define IDC_COMBO1                      1002\r
-#define IDC_CHECK1                      1003\r
-#define IDC_COMBO2                      1004\r
-#define IDC_EDIT2                       1005\r
-#define IDC_SECRET                      1005\r
-#define IDC_COMBO3                      1007\r
-#define IDC_FAILURE                     1008\r
-#define IDC_SUCCESS                     1009\r
-#define IDC_SECRET_NAME                 1010\r
-#define IDC_NAME                        1010\r
-#define IDC_KEY                         1010\r
-#define IDC_LIST1                       1011\r
-#define IDC_BROWSE_LIST                 1011\r
-#define IDC_BUTTON2                     1012\r
-#define IDC_REMOVE_BROWSE_DOMAIN        1012\r
-#define IDC_ADD_BROWSE_DOMAIN           1013\r
-\r
-// Next default values for new objects\r
-// \r
-#ifdef APSTUDIO_INVOKED\r
-#ifndef APSTUDIO_READONLY_SYMBOLS\r
-#define _APS_NEXT_RESOURCE_VALUE        143\r
-#define _APS_NEXT_COMMAND_VALUE         32771\r
-#define _APS_NEXT_CONTROL_VALUE         1014\r
-#define _APS_NEXT_SYMED_VALUE           101\r
-#endif\r
-#endif\r
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ControlPanel.rc
+//
+#define IDR_APPLET                      131
+#define IDR_APPLET_PAGE1                131
+#define IDS_APPLET_DESCRIPTION          132
+#define IDR_APPLET_PAGE2                132
+#define IDR_SECRET                      133
+#define IDR_APPLET_PAGE3                134
+#define IDI_FAILURE                     140
+#define IDI_SUCCESS                     141
+#define IDD_ADD_BROWSE_DOMAIN           142
+#define IDR_ADD_BROWSE_DOMAIN           142
+#define IDC_EDIT1                       1000
+#define IDC_BUTTON1                     1001
+#define IDC_COMBO1                      1002
+#define IDC_CHECK1                      1003
+#define IDC_COMBO2                      1004
+#define IDC_EDIT2                       1005
+#define IDC_SECRET                      1005
+#define IDC_COMBO3                      1007
+#define IDC_FAILURE                     1008
+#define IDC_SUCCESS                     1009
+#define IDC_SECRET_NAME                 1010
+#define IDC_LIST1                       1011
+#define IDC_BROWSE_LIST                 1011
+#define IDC_BUTTON2                     1012
+#define IDC_REMOVE_BROWSE_DOMAIN        1012
+#define IDC_ADD_BROWSE_DOMAIN           1013
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#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_SYMED_VALUE           101
+#endif
+#endif
index e048c02d99700157036ef84dcf41d5cae74916b1..39750483b70ec739f0b909c6de49b10890c6e080 100644 (file)
@@ -33,8 +33,7 @@
                                Detect64BitPortabilityProblems="TRUE"\r
                                DebugInformationFormat="4"\r
                                CallingConvention="2"\r
-                               CompileAs="0"\r
-                               DisableSpecificWarnings="4127;4204"/>\r
+                               CompileAs="0"/>\r
                        <Tool\r
                                Name="VCCustomBuildTool"/>\r
                        <Tool\r
@@ -80,8 +79,7 @@
                                Detect64BitPortabilityProblems="TRUE"\r
                                DebugInformationFormat="3"\r
                                CallingConvention="2"\r
-                               CompileAs="0"\r
-                               DisableSpecificWarnings="4127;4204"/>\r
+                               CompileAs="0"/>\r
                        <Tool\r
                                Name="VCCustomBuildTool"/>\r
                        <Tool\r
diff --git a/mDNSWindows/Installer/Main.ism b/mDNSWindows/Installer/Main.ism
new file mode 100644 (file)
index 0000000..c430d40
Binary files /dev/null and b/mDNSWindows/Installer/Main.ism differ
diff --git a/mDNSWindows/Installer/SDK.ism b/mDNSWindows/Installer/SDK.ism
new file mode 100644 (file)
index 0000000..e63bde7
Binary files /dev/null and b/mDNSWindows/Installer/SDK.ism differ
index 0ab2dbf14d730a8b829894af9d2e5c24bc4994ad..451c239ce0b7b8b2eb348eeef9445d348d9b7727 100644 (file)
     Change History (most recent first):
     
 $Log: Service.c,v $
-Revision 1.34  2005/04/22 07:34:23  shersche
-Check an interface's address and make sure it's valid before using it to set link-local routes.
-
-Revision 1.33  2005/04/13 17:48:23  shersche
-<rdar://problem/4079667> Make sure there is only one default route for link-local addresses.
-
-Revision 1.32  2005/04/06 01:32:05  shersche
-Remove default route for link-local addressing when another interface comes up with a routable IPv4 address
-
-Revision 1.31  2005/04/06 01:00:11  shersche
-<rdar://problem/4080127> GetFullPathName() should be passed the number of TCHARs in the path buffer, not the size in bytes of the path buffer.
-
-Revision 1.30  2005/04/06 00:52:43  shersche
-<rdar://problem/4079667> Only add default route if there are no other routable IPv4 addresses on any of the other interfaces. More work needs to be done to correctly configure the routing table when multiple interfaces are extant and none of them have routable IPv4 addresses.
-
 Revision 1.29  2005/03/06 05:21:56  shersche
 <rdar://problem/4037635> Fix corrupt UTF-8 name when non-ASCII system name used, enabled unicode support
 
@@ -272,9 +257,8 @@ static mDNSs32              udsIdle(mDNS * const inMDNS, mDNSs32 interval);
 static void                    CoreCallback(mDNS * const inMDNS, mStatus result);
 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                    IsValidAddress( const char * addr );
+static bool                    HaveLLRoute(PMIB_IPFORWARDROW rowExtant);
+static OSStatus                SetLLRoute();
 
 #if defined(UNICODE)
 #      define StrLen(X)        wcslen(X)
@@ -494,7 +478,7 @@ static OSStatus     InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR i
        
        // Get a full path to the executable since a relative path may have been specified.
        
-       size = GetFullPathName( inPath, MAX_PATH, fullPath, &namePtr );
+       size = GetFullPathName( inPath, sizeof( fullPath ), fullPath, &namePtr );
        err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
        require_noerr( err, exit );
        
@@ -1178,7 +1162,7 @@ static OSStatus   ServiceSpecificInitialize( int argc, LPTSTR argv[] )
        //
        if (gServiceManageLLRouting == true)
        {
-               SetLLRoute( &gMDNSRecord );
+               SetLLRoute();
        }
 
 exit:
@@ -1262,11 +1246,13 @@ static void     ServiceSpecificFinalize( int argc, LPTSTR argv[] )
 static void
 CoreCallback(mDNS * const inMDNS, mStatus status)
 {
+       DEBUG_UNUSED( inMDNS );
+
        if (status == mStatus_ConfigChanged)
        {
                if (gServiceManageLLRouting == true)
                {
-                       SetLLRoute( inMDNS );
+                       SetLLRoute();
                }
        }
 }
@@ -1672,11 +1658,11 @@ EventSourceUnlock()
 
 
 //===========================================================================================================================
-//     HaveRoute
+//     HaveLLRoute
 //===========================================================================================================================
 
 static bool
-HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr )
+HaveLLRoute(PMIB_IPFORWARDROW rowExtant)
 {
        PMIB_IPFORWARDTABLE     pIpForwardTable = NULL;
        DWORD                           dwSize                  = 0;
@@ -1708,7 +1694,7 @@ HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr )
        //
        for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
        {
-               if ( pIpForwardTable->table[i].dwForwardDest == addr )
+               if (pIpForwardTable->table[i].dwForwardDest == inet_addr(kLLNetworkAddr))
                {
                        memcpy( rowExtant, &(pIpForwardTable->table[i]), sizeof(*rowExtant) );
                        found = true;
@@ -1727,23 +1713,12 @@ exit:
 }
 
 
-//===========================================================================================================================
-//     IsValidAddress
-//===========================================================================================================================
-
-static bool
-IsValidAddress( const char * addr )
-{
-       return ( addr && ( strcmp( addr, "0.0.0.0" ) != 0 ) ) ? true : false;
-}      
-
-
 //===========================================================================================================================
 //     SetLLRoute
 //===========================================================================================================================
 
 static OSStatus
-SetLLRoute( mDNS * const inMDNS )
+SetLLRoute()
 {
        DWORD                           ifIndex;
        MIB_IPFORWARDROW        rowExtant;
@@ -1773,7 +1748,7 @@ SetLLRoute( mDNS * const inMDNS )
        //
        // check to make sure we don't already have a route
        //
-       if ( HaveRoute( &rowExtant, inet_addr( kLLNetworkAddr ) ) )
+       if (HaveLLRoute(&rowExtant))
        {
                //
                // set the age to 0 so that we can do a memcmp.
@@ -1807,32 +1782,13 @@ SetLLRoute( mDNS * const 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:
+       // see if this address is a link local address
        //
-       // 1. This interface has a link-local address
-       // 2. This is the only IPv4 interface
-       //
-
-       if ( ( row.dwForwardNextHop & 0xFFFF ) == row.dwForwardDest )
+       if ((row.dwForwardNextHop & 0xFFFF) == row.dwForwardDest)
        {
-               mDNSInterfaceData       *       ifd;
-               int                                             numLinkLocalInterfaces  = 0;
-               int                                             numInterfaces                   = 0;
-       
-               for ( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
-               {
-                       if ( ifd->defaultAddr.type == mDNSAddrType_IPv4 )
-                       {
-                               numInterfaces++;
-
-                               if ( ( ifd->interfaceInfo.ip.ip.v4.b[0] == 169 ) && ( ifd->interfaceInfo.ip.ip.v4.b[1] == 254 ) )
-                               {
-                                       numLinkLocalInterfaces++;
-                               }
-                       }
-               }
-
+               //
+               // if so, set up a route to ARP everything
+               //
                row.dwForwardDest               = 0;
                row.dwForwardIfIndex    = ifIndex;
                row.dwForwardMask               = 0;
@@ -1840,26 +1796,16 @@ SetLLRoute( mDNS * const inMDNS )
                row.dwForwardProto              = MIB_IPPROTO_NETMGMT;
                row.dwForwardAge                = 0;
                row.dwForwardPolicy             = 0;
-               row.dwForwardMetric1    = 20;
+               row.dwForwardMetric1    = 1;
                row.dwForwardMetric2    = (DWORD) - 1;
                row.dwForwardMetric3    = (DWORD) - 1;
                row.dwForwardMetric4    = (DWORD) - 1;
                row.dwForwardMetric5    = (DWORD) - 1;
-               
-               if ( numInterfaces == numLinkLocalInterfaces )
-               {
-                       if ( !HaveRoute( &row, 0 ) )
-                       {
-                               err = CreateIpForwardEntry(&row);
-                               require_noerr( err, exit );
-                       }
-               }
-               else
-               {
-                       DeleteIpForwardEntry( &row );
-               }
-       }
 
+               err = CreateIpForwardEntry(&row);
+
+               require_noerr( err, exit );
+       }
 exit:
 
        return ( err );
@@ -1877,7 +1823,6 @@ GetRouteDestination(DWORD * ifIndex, DWORD * address)
        IP_ADAPTER_INFO *       pAdapterInfo    =       NULL;
        IP_ADAPTER_INFO *       pAdapter                =       NULL;
        ULONG                           bufLen;
-       mDNSBool                        done                    =       mDNSfalse;
        OSStatus                        err;
 
        //
@@ -1937,41 +1882,24 @@ GetRouteDestination(DWORD * ifIndex, DWORD * address)
                pAdapter = pAdapter->Next;
        }
 
-       while ( !done )
-       {
-               pAdapter        =       pAdapterInfo;
-               err                     =       kUnknownErr;
-
-               while (pAdapter)
-               {
-                       // If we don't have an interface selected, choose the first one that is of type ethernet and
-                       // has a valid IP Address
-
-                       if ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) && ( IsValidAddress( pAdapter->IpAddressList.IpAddress.String ) ) && (!(*ifIndex) || (pAdapter->Index == (*ifIndex))))
-                       {
-                               *address =      inet_addr( pAdapter->IpAddressList.IpAddress.String );
-                               *ifIndex =  pAdapter->Index;
-                               err              =      kNoErr;
-                               break;
-                       }
-               
-                       pAdapter = pAdapter->Next;
-               }
-
-               // If we found the right interface, or we weren't trying to find a specific interface then we're done
-
-               if ( !err || !( *ifIndex) )
-               {
-                       done = mDNStrue;
-               }
-
-               // Otherwise, try again by wildcarding the interface
+       pAdapter        =       pAdapterInfo;
+       err                     =       kUnknownErr;
 
-               else
+       while (pAdapter)
+       {
+               //
+               // if we don't have an interface selected, choose the first one
+               //
+               if ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) && (!(*ifIndex) || (pAdapter->Index == (*ifIndex))))
                {
-                       *ifIndex = 0;
+                       *address =      inet_addr( pAdapter->IpAddressList.IpAddress.String );
+                       *ifIndex =  pAdapter->Index;
+                       err              =      kNoErr;
+                       break;
                }
-       } 
+       
+               pAdapter = pAdapter->Next;
+       }
 
 exit:
 
@@ -1982,3 +1910,4 @@ exit:
 
        return( err );
 }
+
diff --git a/mDNSWindows/SystemServiceTest/Prefix.h b/mDNSWindows/SystemServiceTest/Prefix.h
new file mode 100644 (file)
index 0000000..53fb893
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+    Change History (most recent first):
+
+$Log: Prefix.h,v $
+Revision 1.1  2004/06/18 04:17:43  rpantos
+Move up one level.
+
+Revision 1.1  2004/01/30 02:58:57  bradley
+Test tool for the mDNSResponder Windows service.
+                                       
+*/
+
+#ifndef __PREFIX__
+#define __PREFIX__
+
+#if( defined( _DEBUG ) )
+       #define DEBUG                                   1
+       #define MDNS_DEBUGMSGS                  1
+#else
+       #define DEBUG                                   0
+#endif
+
+#define        DNS_SD_DIRECT_ENABLED           0
+#define        DNS_SD_CLIENT_ENABLED           1
+
+#endif // __PREFIX__
diff --git a/mDNSWindows/SystemServiceTest/Tool.c b/mDNSWindows/SystemServiceTest/Tool.c
new file mode 100644 (file)
index 0000000..f4d675a
--- /dev/null
@@ -0,0 +1,851 @@
+/*
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+
+    Change History (most recent first):
+       
+$Log: Tool.c,v $
+Revision 1.2  2004/07/13 21:24:28  rpantos
+Fix for <rdar://problem/3701120>.
+
+Revision 1.1  2004/06/18 04:17:43  rpantos
+Move up one level.
+
+Revision 1.3  2004/04/09 21:03:15  bradley
+Changed port numbers to use network byte order for consistency with other platforms.
+
+Revision 1.2  2004/04/08 09:43:43  bradley
+Changed callback calling conventions to __stdcall so they can be used with C# delegates.
+
+Revision 1.1  2004/01/30 02:58:57  bradley
+Test tool for the mDNSResponder Windows service.
+
+*/
+
+#include       <stdio.h>
+#include       <stdlib.h>
+
+#include       "CommonServices.h"
+#include       "DebugServices.h"
+#include       "DNSSD.h"
+
+//===========================================================================================================================
+//     Structures
+//===========================================================================================================================
+
+#define MAX_DOMAIN_LABEL 63
+#define MAX_DOMAIN_NAME 255
+
+typedef union { unsigned char b[2]; unsigned short NotAnInteger; } Opaque16;
+
+typedef struct { u_char c[ 64]; } domainlabel;
+typedef struct { u_char c[256]; } domainname;
+
+typedef struct 
+    { 
+    uint16_t priority; 
+    uint16_t weight; 
+    uint16_t port; 
+    domainname target;
+    } srv_rdata;
+
+//===========================================================================================================================
+//     Prototypes
+//===========================================================================================================================
+
+int                            main( int argc, char* argv[] );
+static void                    Usage( void );
+static int                     ProcessArgs( int argc, char* argv[] );
+
+#if( defined( WINVER ) )
+       static BOOL WINAPI      ConsoleControlHandler( DWORD inControlEvent );
+#endif
+
+static void CALLBACK_COMPAT
+       EnumerateDomainsCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               uint32_t                        inInterfaceIndex,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inDomain,  
+               void *                          inContext );
+
+static void CALLBACK_COMPAT
+       BrowseCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               uint32_t                        inInterfaceIndex,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inName,  
+               const char *            inType,  
+               const char *            inDomain,  
+               void *                          inContext );
+
+static void CALLBACK_COMPAT
+       ResolveCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               uint32_t                        inInterfaceIndex,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inFullName,  
+               const char *            inHostName,  
+               uint16_t                        inPort, 
+               uint16_t                        inTXTSize, 
+               const char *            inTXT, 
+               void *                          inContext );
+
+static void CALLBACK_COMPAT
+       RegisterCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inName,  
+               const char *            inType,  
+               const char *            inDomain,  
+               void *                          inContext );
+
+static void CALLBACK_COMPAT
+       RecordCallBack( 
+               DNSServiceRef                   inRef, 
+               DNSRecordRef                    inRecordRef, 
+               DNSServiceFlags                 inFlags, 
+               DNSServiceErrorType     inErrorCode, 
+               void *                                  inContext );
+
+static void CALLBACK_COMPAT
+       QueryCallBack( 
+               const DNSServiceRef             inRef, 
+               const DNSServiceFlags           inFlags, 
+               const uint32_t                          inInterfaceIndex, 
+               const DNSServiceErrorType       inErrorCode, 
+               const char *                            inName, 
+               const uint16_t                          inRRType, 
+               const uint16_t                          inRRClass, 
+               const uint16_t                          inRDataSize, 
+               const void *                            inRData, 
+               const uint32_t                          inTTL, 
+               void *                                          inContext );
+
+static void    PrintRData( uint16_t inRRType, size_t inRDataSize, const uint8_t *inRData );
+
+static char *ConvertDomainLabelToCString_withescape(const domainlabel *const label, char *ptr, char esc);
+static char *ConvertDomainNameToCString_withescape(const domainname *const name, char *ptr, char esc);
+
+//===========================================================================================================================
+//     Globals
+//===========================================================================================================================
+
+#if( defined( WINVER ) )
+       static volatile int             gQuit = 0;
+#endif
+
+//===========================================================================================================================
+//     main
+//===========================================================================================================================
+
+int main( int argc, char *argv[] )
+{
+       OSStatus                err;
+       
+       debug_initialize( kDebugOutputTypeMetaConsole );
+       debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelTrace );
+
+       SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
+       err = ProcessArgs( argc, argv );
+       return( (int) err );
+}
+
+//===========================================================================================================================
+//     Usage
+//===========================================================================================================================
+
+static void    Usage( void )
+{
+       fprintf( stderr, "\n" );
+       fprintf( stderr, "DNSServiceTest 1.0d1\n" );
+       fprintf( stderr, "\n" );
+       fprintf( stderr, "  -server <IP>                                      Set Remote Server\n" );
+       fprintf( stderr, "  -cv                                               Check Version\n" );
+       fprintf( stderr, "  -bd                                               Browse for Browse Domains\n" );
+       fprintf( stderr, "  -bs <type> <domain>                               Browse for Services\n" );
+       fprintf( stderr, "  -rsi <name> <type> <domain>                       Resolve Service Instance\n" );
+       fprintf( stderr, "  -rs <name> <type> <domain> <host> <port> <txt>    Register Service\n" );
+       fprintf( stderr, "  -rr                                               Register Records\n" );
+       fprintf( stderr, "  -qr <name> <type> <domain> <rrType>               Query Record\n" );
+       fprintf( stderr, "  -cr <name> <type> <domain> <rrType>               Reconfirm Record\n" );
+       fprintf( stderr, "  -cp <code>                                        Copy Property\n" );
+       fprintf( stderr, "  -h[elp]                                           Help\n" );
+       fprintf( stderr, "\n" );
+}
+
+DEBUG_LOCAL DNSServiceRef              gRef            = NULL;
+DEBUG_LOCAL DNSRecordRef               gRecordRef      = NULL;
+DEBUG_LOCAL const char *               gServer         = NULL;
+
+//===========================================================================================================================
+//     ProcessArgs
+//===========================================================================================================================
+
+static int ProcessArgs( int argc, char* argv[] )
+{      
+       OSStatus                        err;
+       int                                     i;
+       const char *            name;
+       const char *            type;
+       const char *            domain;
+       uint16_t                        port;
+       const char *            host;
+       const char *            txt;
+       uint16_t                        txtSize;
+       uint8_t                         txtStorage[ 256 ];
+       uint32_t                        ipv4;
+       char                            s[ 256 ];
+       DNSRecordRef            records[ 10 ];
+       char                            fullName[ kDNSServiceMaxDomainName ];
+       uint16_t                        rrType;
+       
+       err = DNSServiceInitialize( kDNSServiceInitializeFlagsNoServerCheck, 0 );
+       require_noerr( err, exit );
+       
+       // Parse the command line arguments (ignore first argument since it's just the program name).
+       
+       if( argc <= 1 )
+       {
+               Usage();
+               err = 0;
+               goto exit;
+       }
+       for( i = 1; i < argc; ++i )
+       {
+               if( strcmp( argv[ i ], "-server" ) == 0 )
+               {
+                       require_action( argc > ( i + 1 ), exit, err = kParamErr );
+                       gServer = argv[ ++i ];
+                       
+                       printf( "Server set to \"%s\"\n", gServer );
+               }
+               else if( strcmp( argv[ i ], "-cv" ) == 0 )
+               {
+                       // Check Version
+                                               
+                       err = DNSServiceCheckVersion();
+                       printf( "CheckVersion: %ld\n", err );
+                       err = kNoErr;
+                       goto exit;
+               }
+               else if( strcmp( argv[ i ], "-bd" ) == 0 )
+               {
+                       err = DNSServiceEnumerateDomains( &gRef, kDNSServiceFlagsBrowseDomains, 0, 
+                               EnumerateDomainsCallBack, NULL );
+                       require_noerr( err, exit );
+               }
+               else if( strcmp( argv[ i ], "-bs" ) == 0 )
+               {
+                       // Browse service <type> <domain>
+                                               
+                       if( argc > ( i + 2 ) )
+                       {
+                               type    = argv[ ++i ];
+                               domain  = argv[ ++i ];
+                       }
+                       else
+                       {
+                               type    = "_http._tcp";
+                               domain  = "";
+                       }
+                       if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+                       {
+                               domain = "local.";
+                       }
+                       
+                       err = DNSServiceBrowse( &gRef, 0, 0, type, domain, BrowseCallBack, NULL );
+                       require_noerr( err, exit );
+               }
+               else if( strcmp( argv[ i ], "-rsi" ) == 0 )
+               {
+                       // Resolve Service Instance <name> <type> <domain>
+                                               
+                       if( argc > ( i + 3 ) )
+                       {
+                               name    = argv[ ++i ];
+                               type    = argv[ ++i ];
+                               domain  = argv[ ++i ];
+                       }
+                       else
+                       {
+                               name    = "test service";
+                               type    = "_http._tcp";
+                               domain  = "";
+                       }
+                       if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+                       {
+                               domain = "local.";
+                       }
+                       
+                       err = DNSServiceResolve( &gRef, 0, 0, name, type, domain, ResolveCallBack, NULL );
+                       require_noerr( err, exit );
+               }
+               else if( strcmp( argv[ i ], "-rs" ) == 0 )
+               {
+                       // Register Service <name> <type> <domain> <host> <port> <txt>
+                       
+                       if( argc > ( i + 6 ) )
+                       {
+                               name    = argv[ ++i ];
+                               type    = argv[ ++i ];
+                               domain  = argv[ ++i ];
+                               host    = argv[ ++i ];
+                               port    = (uint16_t) atoi( argv[ ++i ] );
+                               txt     = argv[ ++i ];
+                       }
+                       else
+                       {
+                               name    = "test service";
+                               type    = "_http._tcp";
+                               domain  = "";
+                               host    = "";
+                               port    = 80;
+                               txt             = "My TXT Record";
+                       }
+                       if( *txt != '\0' )
+                       {
+                               txtStorage[ 0 ] = (uint8_t) strlen( txt );
+                               memcpy( &txtStorage[ 1 ], txt, txtStorage[ 0 ] );
+                               txtSize = (uint16_t)( 1 + txtStorage[ 0 ] );
+                               txt = (const char *) txtStorage;
+                       }
+                       else
+                       {
+                               txt = NULL;
+                               txtSize = 0;
+                       }
+                       if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+                       {
+                               domain = "local.";
+                       }
+                       
+                       err = DNSServiceRegister( &gRef, 0, 0, name, type, domain, host, htons( port ), txtSize, txt, 
+                               RegisterCallBack, NULL );
+                       require_noerr( err, exit );
+                       
+                       #if( TEST_SERVICE_RECORDS )
+                               ipv4 = 0x11223344;
+                               err = DNSServiceAddRecord( gRef, &gRecordRef, 0, kDNSServiceDNSType_A, kDNSServiceDNSClass_IN, &ipv4, 60 );
+                               require_noerr( err, exit );
+                               
+                               Sleep( 10000 );
+                               
+                               ipv4 = 0x22334455;
+                               err = DNSServiceUpdateRecord( gRef, gRecordRef, 0, 4, &ipv4, 60 );
+                               require_noerr( err, exit );
+                               
+                               Sleep( 10000 );
+                               
+                               err = DNSServiceRemoveRecord( gRef, gRecordRef, 0 );
+                               require_noerr( err, exit );
+                               gRecordRef = NULL;
+                               
+                               Sleep( 10000 );
+                       #endif
+               }
+               else if( strcmp( argv[ i ], "-rr" ) == 0 )
+               {
+                       // Register Records
+                       
+                       err = DNSServiceCreateConnection( &gRef );
+                       require_noerr( err, exit );
+                                               
+                       printf( "registering 10 address records...\n" );
+                       ipv4 = 0x11223310;
+                       for( i = 0; i < 10; ++i )
+                       {
+                               sprintf( s, "testhost-%d.local.", i );
+                               ++ipv4;
+                               err = DNSServiceRegisterRecord( gRef, &records[ i ], kDNSServiceFlagsUnique, 0, s, 
+                                       kDNSServiceDNSType_A, kDNSServiceDNSClass_IN, 4, &ipv4, 60, RecordCallBack, NULL );
+                               check_noerr( err );
+                       }
+                       Sleep( 10000 );
+                       
+                       printf( "deregistering half of the records\n" );
+                       for( i = 0; i < 10; ++i )
+                       {
+                               if( i % 2 )
+                               {
+                                       err = DNSServiceRemoveRecord( gRef, records[ i ], 0 );
+                                       check_noerr( err );
+                                       records[ i ] = NULL;
+                               }
+                       }
+                       Sleep( 10000 );
+                       
+                       printf( "updating the remaining records\n" );
+                       for( i = 0; i < 10; ++i )
+                       {
+                               if( records[ i ] )
+                               {
+                                       ++ipv4;
+                                       err = DNSServiceUpdateRecord( gRef, records[ i ], 0, 4, &ipv4, 60 );
+                                       check_noerr( err );
+                               }
+                       }
+                       Sleep( 10000 );
+                       
+                       printf( "deregistering all remaining records\n" );
+               DNSServiceRefDeallocate( gRef );
+               
+               Sleep( 5000 );
+               }
+               else if( strcmp( argv[ i ], "-qr" ) == 0 )
+               {
+                       // Query Record <name> <type> <domain> <rrType>
+                                               
+                       if( argc > ( i + 4 ) )
+                       {
+                               name    = argv[ ++i ];
+                               type    = argv[ ++i ];
+                               domain  = argv[ ++i ];
+                               rrType  = (uint16_t) atoi( argv[ ++i ] );
+                       }
+                       else
+                       {
+                               name    = "test";
+                               type    = "";
+                               domain  = "";
+                               rrType  = 1;    // Address
+                       }
+                       if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+                       {
+                               domain = "local.";
+                       }
+                       err = DNSServiceConstructFullName( fullName, name, type, domain );
+                       require_noerr( err, exit );
+                       
+                       printf( "resolving fullname %s type %d\n", fullName, rrType );
+                       err = DNSServiceQueryRecord( &gRef, 0, 0, fullName, rrType, kDNSServiceDNSClass_IN, QueryCallBack, NULL );
+                       require_noerr( err, exit );
+               }
+               else if( strcmp( argv[ i ], "-cr" ) == 0 )
+               {
+                       // Reconfirm Record <name> <type> <domain> <rrType>
+                       
+                       if( argc > ( i + 4 ) )
+                       {
+                               name    = argv[ ++i ];
+                               type    = argv[ ++i ];
+                               domain  = argv[ ++i ];
+                               rrType  = (uint16_t) atoi( argv[ ++i ] );
+                       }
+                       else
+                       {
+                               name    = "test";
+                               type    = "";
+                               domain  = "";
+                               rrType  = 1;    // Address
+                       }
+                       if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+                       {
+                               domain = "local.";
+                       }
+                       err = DNSServiceConstructFullName( fullName, name, type, domain );
+                       require_noerr( err, exit );
+                       
+                       printf( "reconfirming record fullname %s type %d\n", fullName, rrType );
+                       ipv4 = 0x11223310;
+                       DNSServiceReconfirmRecord( 0, 0, fullName, rrType, kDNSServiceDNSClass_IN, 4, &ipv4 );
+               }
+               else if( strcmp( argv[ i ], "-cp" ) == 0 )
+               {
+                       DNSPropertyCode         code;
+                       DNSPropertyData         data;
+                       
+                       // Copy Property <code>
+                                               
+                       if( argc > ( i + 1 ) )
+                       {
+                               name = argv[ ++i ];
+                               require_action( strlen( name ) == 4, exit, err = kParamErr );
+                               
+                               code  = (DNSPropertyCode)( name[ 0 ] << 24 );
+                               code |= (DNSPropertyCode)( name[ 1 ] << 16 );
+                               code |= (DNSPropertyCode)( name[ 2 ] <<  8 );
+                               code |= (DNSPropertyCode)  name[ 3 ];
+                       }
+                       else
+                       {
+                               code = kDNSPropertyCodeVersion;
+                               name = "vers";
+                       }
+                       
+                       err = DNSServiceCopyProperty( code, &data );
+                       require_noerr( err, exit );
+                       
+                       printf( "'%s' property:\n", name );
+                       if( code == kDNSPropertyCodeVersion )
+                       {
+                               printf( "    clientCurrentVersion:      0x%08X\n", data.u.version.clientCurrentVersion );
+                               printf( "    clientOldestServerVersion: 0x%08X\n", data.u.version.clientOldestServerVersion );
+                               printf( "    serverCurrentVersion:      0x%08X\n", data.u.version.serverCurrentVersion );
+                               printf( "    serverOldestClientVersion: 0x%08X\n", data.u.version.serverOldestClientVersion );
+                       }
+               }
+               else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || ( strcmp( argv[ i ], "-h" ) == 0 ) )
+               {
+                       // Help
+                       
+                       Usage();
+                       err = 0;
+                       goto exit;
+               }
+               else
+               {
+                       // Unknown parameter.
+                       
+                       dlog( kDebugLevelError, "unknown parameter (%s)\n", argv[ i ] );
+                       err = kParamErr;
+                       goto exit;
+               }
+       }
+       
+       // Run until control-C'd.
+       
+       while( !gQuit )
+       {
+               Sleep( 100 );
+       }
+       err = kNoErr;
+       
+exit:
+       DNSServiceFinalize();
+       if( err )
+       {
+               Usage();
+       }
+       return( err );
+}
+
+//===========================================================================================================================
+//     ConsoleControlHandler
+//===========================================================================================================================
+
+static BOOL WINAPI     ConsoleControlHandler( DWORD inControlEvent )
+{
+       BOOL            handled;
+       
+       handled = 0;
+       switch( inControlEvent )
+       {
+               case CTRL_C_EVENT:
+               case CTRL_BREAK_EVENT:
+               case CTRL_CLOSE_EVENT:
+               case CTRL_LOGOFF_EVENT:
+               case CTRL_SHUTDOWN_EVENT:
+                       gQuit = 1;
+                       handled = 1;
+                       break;
+               
+               default:
+                       break;
+       }
+       return( handled );
+}
+
+//===========================================================================================================================
+//     EnumerateDomainsCallBack
+//===========================================================================================================================
+
+static void CALLBACK_COMPAT
+       EnumerateDomainsCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               uint32_t                        inInterfaceIndex,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inDomain,  
+               void *                          inContext )
+{
+       printf( "inRef:            0x%08X\n", (uintptr_t) inRef );
+       printf( "inFlags:          0x%08X\n", (int) inFlags );
+       printf( "inInterfaceIndex: 0x%08X\n", (int) inInterfaceIndex );
+       printf( "inErrorCode:      %ld\n", inErrorCode );
+       printf( "inDomain:         \"%s\"\n", inDomain ? inDomain : "<null>" );
+       printf( "inContext:        0x%08X\n", (uintptr_t) inContext );
+       printf( "\n" );
+}
+
+//===========================================================================================================================
+//     BrowseCallBack
+//===========================================================================================================================
+
+static void CALLBACK_COMPAT
+       BrowseCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               uint32_t                        inInterfaceIndex,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inName,  
+               const char *            inType,  
+               const char *            inDomain,  
+               void *                          inContext )
+{
+       printf( "inRef:            0x%08X\n", (uintptr_t) inRef );
+       printf( "inFlags:          0x%08X\n", (int) inFlags );
+       printf( "inInterfaceIndex: 0x%08X\n", (int) inInterfaceIndex );
+       printf( "inErrorCode:      %ld\n", inErrorCode );
+       printf( "inName:           \"%s\"\n", inName ? inName : "<null>" );
+       printf( "inType:           \"%s\"\n", inType ? inType : "<null>" );
+       printf( "inDomain:         \"%s\"\n", inDomain ? inDomain : "<null>" );
+       printf( "inContext:        0x%08X\n", (uintptr_t) inContext );
+       printf( "\n" );
+}
+
+//===========================================================================================================================
+//     ResolveCallBack
+//===========================================================================================================================
+
+static void CALLBACK_COMPAT
+       ResolveCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               uint32_t                        inInterfaceIndex,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inFullName,  
+               const char *            inHostName,  
+               uint16_t                        inPort, 
+               uint16_t                        inTXTSize, 
+               const char *            inTXT, 
+               void *                          inContext )
+{
+       printf( "inRef:            0x%08X\n", (uintptr_t) inRef );
+       printf( "inFlags:          0x%08X\n", (int) inFlags );
+       printf( "inInterfaceIndex: 0x%08X\n", (int) inInterfaceIndex );
+       printf( "inErrorCode:      %ld\n", inErrorCode );
+       printf( "inFullName:       \"%s\"\n", inFullName ? inFullName : "<null>" );
+       printf( "inHostName:       \"%s\"\n", inHostName ? inHostName : "<null>" );
+       printf( "inPort:           %d\n", ntohs( inPort ) );
+       printf( "inTXTSize:        %ld\n", inTXTSize );
+       printf( "inTXT:            0x%08X\n", (uintptr_t) inTXT );
+       printf( "inContext:        0x%08X\n", (uintptr_t) inContext );
+       printf( "\n" );
+}
+
+//===========================================================================================================================
+//     RegisterCallBack
+//===========================================================================================================================
+
+static void CALLBACK_COMPAT
+       RegisterCallBack(
+               DNSServiceRef           inRef,
+               DNSServiceFlags         inFlags,
+               DNSServiceErrorType     inErrorCode,
+               const char *            inName,  
+               const char *            inType,  
+               const char *            inDomain,  
+               void *                          inContext )
+{
+       printf( "inRef:            0x%08X\n", (uintptr_t) inRef );
+       printf( "inFlags:          0x%08X\n", (int) inFlags );
+       printf( "inErrorCode:      %ld\n", inErrorCode );
+       printf( "inName:           \"%s\"\n", inName ? inName : "<null>" );
+       printf( "inType:           \"%s\"\n", inType ? inType : "<null>" );
+       printf( "inDomain:         \"%s\"\n", inDomain ? inDomain : "<null>" );
+       printf( "inContext:        0x%08X\n", (uintptr_t) inContext );
+       printf( "\n" );
+}
+
+//===========================================================================================================================
+//     RecordCallBack
+//===========================================================================================================================
+
+static void CALLBACK_COMPAT
+       RecordCallBack( 
+               DNSServiceRef                   inRef, 
+               DNSRecordRef                    inRecordRef, 
+               DNSServiceFlags                 inFlags, 
+               DNSServiceErrorType     inErrorCode, 
+               void *                                  inContext )
+{
+       DEBUG_UNUSED( inRef );
+       DEBUG_UNUSED( inRecordRef );
+       DEBUG_UNUSED( inFlags );
+       DEBUG_UNUSED( inContext );
+       
+       if( inErrorCode == kDNSServiceErr_NoError )
+       {
+               printf( "RecordCallBack: no errors\n" );
+       }
+       else
+       {
+               printf( "RecordCallBack: %ld error\n", inErrorCode );
+       }
+}
+
+//===========================================================================================================================
+//     QueryCallBack
+//===========================================================================================================================
+
+static void CALLBACK_COMPAT
+       QueryCallBack( 
+               const DNSServiceRef             inRef, 
+               const DNSServiceFlags           inFlags, 
+               const uint32_t                          inInterfaceIndex, 
+               const DNSServiceErrorType       inErrorCode, 
+               const char *                            inName, 
+               const uint16_t                          inRRType, 
+               const uint16_t                          inRRClass, 
+               const uint16_t                          inRDataSize, 
+               const void *                            inRData, 
+               const uint32_t                          inTTL, 
+               void *                                          inContext )
+{
+       DEBUG_UNUSED( inRef );
+       DEBUG_UNUSED( inRRClass );
+       DEBUG_UNUSED( inTTL );
+       DEBUG_UNUSED( inContext );
+       
+       if( inErrorCode == kDNSServiceErr_NoError )
+       {
+               if( inFlags & kDNSServiceFlagsAdd )
+               {
+                       printf( "Add" );
+               }
+               else
+               {
+                       printf( "Rmv" );
+               }
+               if( inFlags & kDNSServiceFlagsMoreComing )
+               {
+                       printf( "+" );
+               }
+               else
+               {
+                       printf( " " );
+               }
+               printf(" 0x%04X %d %s rdata ", inFlags, inInterfaceIndex, inName );
+               PrintRData( inRRType, (size_t) inRDataSize, (const uint8_t *) inRData );
+       }
+       else
+       {
+               printf( "QueryCallback: %ld error\n", inErrorCode );
+       }
+}
+
+//===========================================================================================================================
+//     PrintRData
+//===========================================================================================================================
+
+static void    PrintRData( uint16_t inRRType, size_t inRDataSize, const uint8_t *inRData )
+{
+       size_t                          i;
+       srv_rdata *                     srv;
+       char                            s[ 1005 ];
+       struct in_addr          in;
+       
+       switch( inRRType )
+       {
+               case kDNSServiceDNSType_TXT:
+                       
+                       // Print all the alphanumeric and punctuation characters
+                       
+                       for( i = 0; i < inRDataSize; ++i )
+                       {
+                               if( ( inRData[ i ] >= 32 ) && ( inRData[ i ] <= 127 ) )
+                               {
+                                       printf( "%c", inRData[ i ] );
+                               }
+                       }
+                       printf( "\n" );
+                       break;
+                       
+               case kDNSServiceDNSType_SRV:
+                       srv = (srv_rdata *)inRData;
+                       ConvertDomainNameToCString_withescape(&srv->target, s, 0);
+                       printf("pri=%d, w=%d, port=%d, target=%s\n", srv->priority, srv->weight, srv->port, s);
+                       break;
+                       
+               case kDNSServiceDNSType_A:
+                       check( inRDataSize == 4 );
+                       memcpy( &in, inRData, sizeof( in ) );
+                       printf( "%s\n", inet_ntoa( in ) );
+                       break;
+                       
+               case kDNSServiceDNSType_PTR:
+                       ConvertDomainNameToCString_withescape( (domainname *) inRData, s, 0 );
+                       break;
+               
+               case kDNSServiceDNSType_AAAA:
+                       check( inRDataSize == 16 );
+                       printf( "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X\n",
+                                       inRData[0], inRData[1], inRData[2], inRData[3], inRData[4], inRData[5], inRData[6], inRData[7], inRData[8], 
+                                       inRData[9], inRData[10], inRData[11], inRData[12], inRData[13], inRData[14], inRData[15] );
+                       break;
+               
+               default:
+                       printf( "ERROR: I dont know how to print inRData of type %d\n", inRRType );
+                       return;
+       }
+}
+
+static char *ConvertDomainLabelToCString_withescape(const domainlabel *const label, char *ptr, char esc)
+    {
+    const unsigned char *      src = label->c;                         // Domain label we're reading
+    const unsigned char        len = *src++;                           // Read length of this (non-null) label
+    const unsigned char *const end = src + len;                        // Work out where the label ends
+    if (len > 63) return(NULL);           // If illegal label, abort
+    while (src < end)                                           // While we have characters in the label
+        {
+        unsigned char c = *src++;
+        if (esc)
+            {
+            if (c == '.')                                       // If character is a dot,
+                *ptr++ = esc;                                   // Output escape character
+            else if (c <= ' ')                                  // If non-printing ascii,
+                {                                                   // Output decimal escape sequence
+                *ptr++ = esc;
+                *ptr++ = (char)  ('0' + (c / 100)     );
+                *ptr++ = (char)  ('0' + (c /  10) % 10);
+                c      = (unsigned char)('0' + (c      ) % 10);
+                }
+            }
+        *ptr++ = (char)c;                                       // Copy the character
+        }
+    *ptr = 0;                                                   // Null-terminate the string
+    return(ptr);                                                // and return
+    }
+
+static char *ConvertDomainNameToCString_withescape(const domainname *const name, char *ptr, char esc)
+    {
+    const unsigned char *src         = name->c;                        // Domain name we're reading
+    const unsigned char *const max   = name->c + MAX_DOMAIN_NAME;      // Maximum that's valid
+
+    if (*src == 0) *ptr++ = '.';                                // Special case: For root, just write a dot
+
+    while (*src)                                                                                                        // While more characters in the domain name
+        {
+        if (src + 1 + *src >= max) return(NULL);
+        ptr = ConvertDomainLabelToCString_withescape((const domainlabel *)src, ptr, esc);
+        if (!ptr) return(NULL);
+        src += 1 + *src;
+        *ptr++ = '.';                                           // Write the dot after the label
+        }
+
+    *ptr++ = 0;                                                 // Null-terminate the string
+    return(ptr);                                                // and return
+    }
diff --git a/mDNSWindows/SystemServiceTest/Tool.mcp b/mDNSWindows/SystemServiceTest/Tool.mcp
new file mode 100644 (file)
index 0000000..2f38283
Binary files /dev/null and b/mDNSWindows/SystemServiceTest/Tool.mcp differ
diff --git a/mDNSWindows/SystemServiceTest/Tool2002.vcproj b/mDNSWindows/SystemServiceTest/Tool2002.vcproj
new file mode 100644 (file)
index 0000000..0afc4b3
--- /dev/null
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="7.00"
+       Name="mDNSResponderTest"
+       ProjectGUID="{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
+       Keyword="Win32Proj">
+       <Platforms>
+               <Platform
+                       Name="Win32"/>
+       </Platforms>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="Debug"
+                       IntermediateDirectory="Debug"
+                       ConfigurationType="1"
+                       CharacterSet="2">
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DEBUG=1"
+                               StringPooling="TRUE"
+                               MinimalRebuild="TRUE"
+                               ExceptionHandling="FALSE"
+                               BasicRuntimeChecks="3"
+                               SmallerTypeCheck="FALSE"
+                               RuntimeLibrary="1"
+                               BufferSecurityCheck="TRUE"
+                               ForceConformanceInForLoopScope="TRUE"
+                               UsePrecompiledHeader="2"
+                               BrowseInformation="1"
+                               WarningLevel="4"
+                               WarnAsError="TRUE"
+                               Detect64BitPortabilityProblems="TRUE"
+                               DebugInformationFormat="3"/>
+                       <Tool
+                               Name="VCCustomBuildTool"/>
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="ws2_32.lib"
+                               OutputFile="$(ProjectName)Debug.exe"
+                               LinkIncremental="1"
+                               SuppressStartupBanner="TRUE"
+                               GenerateDebugInformation="TRUE"
+                               SubSystem="1"
+                               TargetMachine="1"/>
+                       <Tool
+                               Name="VCMIDLTool"/>
+                       <Tool
+                               Name="VCPostBuildEventTool"/>
+                       <Tool
+                               Name="VCPreBuildEventTool"/>
+                       <Tool
+                               Name="VCPreLinkEventTool"/>
+                       <Tool
+                               Name="VCResourceCompilerTool"/>
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"/>
+                       <Tool
+                               Name="VCWebDeploymentTool"/>
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="Release"
+                       IntermediateDirectory="Release"
+                       ConfigurationType="1"
+                       CharacterSet="2"
+                       WholeProgramOptimization="FALSE">
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               InlineFunctionExpansion="2"
+                               FavorSizeOrSpeed="2"
+                               OmitFramePointers="TRUE"
+                               AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+                               StringPooling="TRUE"
+                               ExceptionHandling="FALSE"
+                               RuntimeLibrary="0"
+                               BufferSecurityCheck="FALSE"
+                               EnableFunctionLevelLinking="FALSE"
+                               DisableLanguageExtensions="FALSE"
+                               ForceConformanceInForLoopScope="TRUE"
+                               UsePrecompiledHeader="2"
+                               WarningLevel="4"
+                               WarnAsError="TRUE"
+                               Detect64BitPortabilityProblems="TRUE"
+                               DebugInformationFormat="3"
+                               CompileAs="1"/>
+                       <Tool
+                               Name="VCCustomBuildTool"/>
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="ws2_32.lib"
+                               OutputFile="$(ProjectName).exe"
+                               LinkIncremental="1"
+                               SuppressStartupBanner="TRUE"
+                               GenerateDebugInformation="TRUE"
+                               SubSystem="1"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"/>
+                       <Tool
+                               Name="VCMIDLTool"/>
+                       <Tool
+                               Name="VCPostBuildEventTool"/>
+                       <Tool
+                               Name="VCPreBuildEventTool"/>
+                       <Tool
+                               Name="VCPreLinkEventTool"/>
+                       <Tool
+                               Name="VCResourceCompilerTool"/>
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"/>
+                       <Tool
+                               Name="VCWebDeploymentTool"/>
+               </Configuration>
+       </Configurations>
+       <Files>
+               <File
+                       RelativePath="..\..\CommonServices.h">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\DNSCommon.c">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\DNSCommon.h">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\DNSDigest.c">
+               </File>
+               <File
+                       RelativePath="..\..\DNSSD.c">
+               </File>
+               <File
+                       RelativePath="..\..\DNSSD.h">
+               </File>
+               <File
+                       RelativePath="..\..\DNSSDDirect.c">
+               </File>
+               <File
+                       RelativePath="..\..\DNSSDDirect.h">
+               </File>
+               <File
+                       RelativePath="..\..\DebugServices.c">
+               </File>
+               <File
+                       RelativePath="..\..\DebugServices.h">
+               </File>
+               <File
+                       RelativePath="..\..\RMxClient.c">
+               </File>
+               <File
+                       RelativePath="..\..\RMxClient.h">
+               </File>
+               <File
+                       RelativePath="..\..\RMxCommon.c">
+               </File>
+               <File
+                       RelativePath="..\..\RMxCommon.h">
+               </File>
+               <File
+                       RelativePath="Tool.c">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\mDNS.c">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\mDNSClientAPI.h">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\mDNSDebug.h">
+               </File>
+               <File
+                       RelativePath="..\..\mDNSWin32.c">
+               </File>
+               <File
+                       RelativePath="..\..\mDNSWin32.h">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\uDNS.c">
+               </File>
+               <File
+                       RelativePath="..\..\..\mDNSCore\uDNS.h">
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
index a115258eb8f4bb242419585cd7663f6de51a9250..884d661f10b7956767aa35e4367e4be7ef466cbe 100644 (file)
     Change History (most recent first):
 
 $Log: WinVersRes.h,v $
-Revision 1.38  2005/04/25 21:59:42  shersche
-Bump to 1.0.0.66
-
-Revision 1.37  2005/04/22 07:39:48  shersche
-Bump to 1.0.0.65
-
-Revision 1.36  2005/04/19 07:25:56  shersche
-Bump version to 1.0.0.64
-
-Revision 1.35  2005/04/13 17:48:58  shersche
-Bump to 1.0.0.63
-
-Revision 1.34  2005/04/06 01:00:55  shersche
-Bump to 1.0.0.62
-
-Revision 1.33  2005/03/30 07:37:41  shersche
-Bump to 1.0.0.61
-
-Revision 1.32  2005/03/23 00:39:46  shersche
-Bump to version 1.0.0.60
-
-Revision 1.31  2005/03/16 03:52:06  shersche
-Bump to 1.0.0.59
-
 Revision 1.30  2005/03/07 19:18:18  shersche
 <rdar://problem/4039831> Update Windows build to 1.0.0.58
 
@@ -145,10 +121,10 @@ First checked in.
 #define MASTER_PROD_NAME       "Bonjour"
 
 // Define the product version for mDNSResponder on Windows
-#define MASTER_PROD_VERS               1,0,0,66
-#define MASTER_PROD_VERS_STR   "1,0,0,66"
-#define MASTER_PROD_VERS_STR2  "1.0.0.66"
-#define MASTER_PROD_VERS_STR3 "Explorer Plugin 1.0.0.66"
+#define MASTER_PROD_VERS               1,0,0,58
+#define MASTER_PROD_VERS_STR   "1,0,0,58"
+#define MASTER_PROD_VERS_STR2  "1.0.0.58"
+#define MASTER_PROD_VERS_STR3 "Explorer Plugin 1.0.0.58"
 
 // Define the legal copyright
 #define MASTER_LEGAL_COPYRIGHT "Copyright (C) 2003-2005 Apple Computer, Inc."
index 850a2d45e66b06ba113dd1c79bc7b38ede60197e..08cbc886949ddb99b82645964fa04d83c8ca413a 100755 (executable)
 
     Change History (most recent first):
 
-$Log: dDNS.c,v $
-Revision 1.6  2005/03/23 05:54:48  cheshire
-<rdar://problem/4021486> Fix build warnings
-Fix %s where it should be %##s in debugf & LogMsg calls
-
 */
 
 #include "dDNS.h"
 #include "DNSCommon.h"
-#include "uds_daemon.h"
 #include <winsock2.h>
 #include <iphlpapi.h>
 #include <ws2tcpip.h>
@@ -172,7 +166,7 @@ mDNSlocal void FoundDomain(mDNS *const m, DNSQuestion *question, const ResourceR
                        {
                        if (SameDomainName(&ptr->ar.resrec.rdata->u.name, &answer->rdata->u.name))
                                {
-                               debugf("Deregistering PTR %##s -> %##s", ptr->ar.resrec.name->c, ptr->ar.resrec.rdata->u.name.c);
+                               debugf("Deregistering PTR %s -> %s", ptr->ar.resrec.name->c, ptr->ar.resrec.rdata->u.name.c);
                 dereg = &ptr->ar;
                                if (prev) prev->next = ptr->next;
                                else slElem->AuthRecs = ptr->next;
@@ -277,7 +271,7 @@ mDNSlocal void FoundDefBrowseDomain(mDNS *const m, DNSQuestion *question, const
                        prev = ptr;
                        ptr = ptr->next;
                        }
-               LogMsg("FoundDefBrowseDomain: Got remove event for domain %##s not in list", answer->rdata->u.name.c);
+               LogMsg("FoundDefBrowseDomain: Got remove event for domain %s not in list", answer->rdata->u.name.c);
                }
        }
 
@@ -365,7 +359,7 @@ mDNSlocal mStatus RegisterSearchDomains( mDNS *const m )
                                {
                                AuthRecord *dereg = &arList->ar;
                                arList = arList->next;
-                               debugf("Deregistering PTR %##s -> %##s", dereg->resrec.name->c, dereg->resrec.rdata->u.name.c);
+                               debugf("Deregistering PTR %s -> %s", dereg->resrec.name->c, dereg->resrec.rdata->u.name.c);
                                err = mDNS_Deregister(m, dereg);
                                if (err) LogMsg("ERROR: RegisterSearchDomains mDNS_Deregister returned %d", err);
                                }
@@ -477,7 +471,7 @@ mDNSlocal void SetSCPrefsBrowseDomains(mDNS *m, DNameListElem * browseDomains, m
                {
                        if ( !browseDomain->name.c[0] )
                                {
-                               LogMsg("SetSCPrefsBrowseDomains bad DDNS browse domain: %##s", browseDomain->name.c[0] ? (char*) browseDomain->name.c : "(unknown)");
+                               LogMsg("SetSCPrefsBrowseDomains bad DDNS browse domain: %s", browseDomain->name.c[0] ? browseDomain->name.c : "(unknown)");
                                }
                        else
                                {
@@ -614,28 +608,14 @@ mStatus dDNS_Setup( mDNS *const m )
 mStatus dDNS_InitDNSConfig(mDNS *const m)
        {
        mStatus err;
-       static AuthRecord LocalRegPTR;
 
        // start query for domains to be used in default (empty string domain) browses
        err = mDNS_GetDomains(m, &LegacyBrowseDomainQ, mDNS_DomainTypeBrowseLegacy, NULL, mDNSInterface_LocalOnly, FoundDefBrowseDomain, NULL);
 
        // provide .local automatically
        SetSCPrefsBrowseDomain(m, &localdomain, mDNStrue);
-
-       // <rdar://problem/4055653> dns-sd -E does not return "local."
-       // register registration domain "local"
-       mDNS_SetupResourceRecord(&LocalRegPTR, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, NULL, NULL);
-       MakeDomainNameFromDNSNameString(LocalRegPTR.resrec.name, mDNS_DomainTypeNames[mDNS_DomainTypeRegistration]);
-       AppendDNSNameString            (LocalRegPTR.resrec.name, "local");
-       AssignDomainName(&LocalRegPTR.resrec.rdata->u.name, &localdomain);
-       err = mDNS_Register(m, &LocalRegPTR);
-       if (err)
-               {
-               LogMsg("ERROR: dDNS_InitDNSConfig - mDNS_Register returned error %d", err);
-               }
-
     return mStatus_NoError;
-       }
+}
 
 void
 dDNS_FreeIPAddrList(IPAddrListElem * list)
index 12c56da3930761ca9d9cdb509ab5d36a124b2e9b..e1b148e5d8569ce916c27a060c2bcf4702f20807 100755 (executable)
 #pragma mark - DynDNS structures
 #endif
 
-#if WIN32
-// named type definition in parentheses \r
-#      pragma warning( disable: 4115 ) \r
-#endif\r
-
 typedef struct IPAddrListElem
        {
        mDNSAddr addr;
index 7084d16b2a0dc1e86bc27e534a2d78c5d405cbfe..7a90e66bca5cc4fac1b12cbe2da4efa632d938f2 100755 (executable)
@@ -72,7 +72,7 @@ static int _getISOCode(LANGID wLangID, char *isoLangCode, int codeLen) {
                int startIndex = i * MODULO_ISOCODES;
                
                langCode = (ISOCODES[startIndex] << 8);
-               langCode = langCode + ( (unsigned short) (ISOCODES[startIndex + 1]) );
+               langCode += ( (unsigned short) (ISOCODES[startIndex + 1]) );
 
                if (langCode == wLangID) {
                        char *langStr = (char *)&(ISOCODES[startIndex+2]);
@@ -118,7 +118,6 @@ int PathForResourceA ( HMODULE module, const char *name, char *locFile, int locF
        if ( !strcmp( appPathNameA, "" ) )
        {
                char   folder[MAX_PATH];
-               char * ext;
                char * app;
 
                GetModuleFileNameA( module, folder, MAX_PATH );
@@ -127,16 +126,10 @@ int PathForResourceA ( HMODULE module, const char *name, char *locFile, int locF
                
                app = strrchr( folder, '\\' );
                require_action( app, exit, ret = 0 );
-               *app++ = '\0';
-
-               // Strip the extension
 
-               if ( ( ( ext = strstr( app, ".exe" ) ) != NULL ) || ( ( ext = strstr( app, ".dll" ) ) != NULL ) )
-               {
-                       *ext = '\0';
-               }
+               *app++ = '\0';
 
-               snprintf( appPathNameA, MAX_PATH, "%s\\%s", folder, app );
+               snprintf( appPathNameA, MAX_PATH, "%s\\Resources\\%s", folder, app );
        }
 
        ret = PathForResourceWithPathA (appPathNameA, name, locFile, locFileLen);
@@ -156,7 +149,6 @@ int PathForResourceW ( HMODULE module, const wchar_t *name, wchar_t *locFile, in
        {
                wchar_t   folder[MAX_PATH];
                wchar_t * app;
-               wchar_t * ext;
 
                GetModuleFileNameW( module, folder, MAX_PATH);
 
@@ -164,16 +156,10 @@ int PathForResourceW ( HMODULE module, const wchar_t *name, wchar_t *locFile, in
                
                app = wcsrchr( folder, '\\' );
                require_action( app, exit, ret = 0 );
-               *app++ = '\0';
-
-               // Strip the extension
 
-               if ( ( ( ext = wcsstr( app, L".exe" ) ) != NULL ) || ( ( ext = wcsstr( app, L".dll" ) ) != NULL ) )
-               {
-                       *ext = '\0';
-               }
+               *app++ = '\0';
 
-               swprintf( appPathNameW, MAX_PATH, L"%ls\\%ls", folder, app );
+               swprintf( appPathNameW, MAX_PATH, L"%ls\\Resources\\%ls", folder, app );
        }
 
        ret = PathForResourceWithPathW (appPathNameW, name, locFile, locFileLen);
index 656b6e581a824477e002e0f1a62a7c1df4928329..6e7bb361389c072d68ab8155142b0994c62bd8d5 100755 (executable)
     Change History (most recent first):
     
 $Log: mDNSWin32.c,v $
-Revision 1.91  2005/04/25 21:34:28  shersche
-<rdar://problem/4096465> Wide-Area services don't disappear when interface goes away
-
-Revision 1.90  2005/04/25 21:18:08  shersche
-<rdar://problem/4097314> mDNSResponder crash when interface goes away.  This error seems to be caused by the Windows platform code not returning mStatus_TransientErr when there is a problem with a udp unicast send.
-
-Revision 1.89  2005/04/22 07:32:24  shersche
-<rdar://problem/4092108> PPP connection disables Bonjour .local lookups
-<rdar://problem/4093944> mDNSResponder ignores Point-to-Point interfaces
-
-Revision 1.88  2005/04/05 03:53:03  shersche
-<rdar://problem/4066485> Registering with shared secret key doesn't work.
-
-Revision 1.87  2005/04/03 08:03:12  shersche
-<rdar://problem/4076478> mDNSResponder won't start on Windows 2000.
-
-Revision 1.86  2005/03/30 07:37:14  shersche
-Use prefix to compute IPv4 subnet mask, falling back to calling AddressToIndexAndMask only if prefix is zero.
-
-Revision 1.85  2005/03/30 07:34:52  shersche
-<rdar://problem/4045657> Interface index being returned is 512
-
-Revision 1.84  2005/03/29 19:19:47  shersche
-<rdar://problem/4055599> Windows is not accepting unicast responses.  This bug was a result of an error in obtaining the subnet mask for IPv4 interfaces.
-
 Revision 1.83  2005/03/07 18:27:42  shersche
 <rdar://problem/4037940> Fix problem when ControlPanel commits changes to the browse domain list
 
@@ -406,8 +381,6 @@ Multicast DNS platform plugin for Win32
        static GUID                                                                             kWSARecvMsgGUID = WSAID_WSARECVMSG;
 #endif
 
-#define kIPv6IfIndexBase                                                       (10000000L)
-
 
 #if 0
 #pragma mark == Prototypes ==
@@ -473,16 +446,6 @@ mDNSexport mStatus mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInter
 
 // Utilities
 
-typedef struct PolyString PolyString;
-
-struct PolyString
-{
-       domainname                      m_dname;
-       char                            m_utf8[256];
-       PLSA_UNICODE_STRING     m_lsa;
-};
-
-
 #if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
        mDNSlocal int   getifaddrs_ipv6( struct ifaddrs **outAddrs );
 #endif
@@ -495,18 +458,15 @@ struct PolyString
        mDNSlocal int   getifaddrs_ce( struct ifaddrs **outAddrs );
 #endif
 
-mDNSlocal DWORD                                GetPrimaryInterface();
-mDNSlocal mStatus                      AddressToIndexAndMask( struct sockaddr * address, uint32_t * index, struct sockaddr * mask );
-mDNSlocal mDNSBool                     CanReceiveUnicast( void );
-mDNSlocal mDNSBool                     IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr );
+mDNSlocal mDNSBool     CanReceiveUnicast( void );
 
 mDNSlocal mStatus                      StringToAddress( mDNSAddr * ip, LPSTR string );
 mDNSlocal mStatus                      RegQueryString( HKEY key, LPCSTR param, LPSTR * string, DWORD * stringLen, DWORD * enabled );
 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 OSStatus                     ConvertUTF8ToLsaString( const char * input, PLSA_UNICODE_STRING output );
+mDNSlocal OSStatus                     ConvertLsaStringToUTF8( PLSA_UNICODE_STRING input, char ** output );
 mDNSlocal void                         FreeTCPConnectionData( mDNSTCPConnectionData * data );
 
 #ifdef __cplusplus
@@ -833,20 +793,7 @@ mStatus
        {
                n = sendto( sendingsocket, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
                err = translate_errno( n > 0, errno_compat(), kWriteErr );
-
-               if ( err )
-               {
-                       // 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 );
-                       }
-               }
+               require_noerr( err, exit );
        }
        
 exit:
@@ -1013,7 +960,7 @@ mDNSs32    mDNSPlatformRawTime( void )
 
 mDNSexport mDNSs32     mDNSPlatformUTC( void )
 {
-       return ( mDNSs32 ) time( NULL );
+       return( -1 );
 }
 
 //===========================================================================================================================
@@ -1515,38 +1462,36 @@ exit:
 //===========================================================================================================================
 
 void
-dDNSPlatformSetSecretForDomain( mDNS *m, const domainname * inDomain )
+dDNSPlatformSetSecretForDomain( mDNS *m, const domainname * domain )
 {
-       PolyString                              domain;
-       PolyString                              key;
-       PolyString                              secret;
+       char                                    dstring[MAX_ESCAPED_DOMAIN_NAME];
+       domainname                      *       d;
+       domainname                              canon;
        size_t                                  i;
        size_t                                  dlen;
        LSA_OBJECT_ATTRIBUTES   attrs;
        LSA_HANDLE                              handle = NULL;
+       LSA_UNICODE_STRING              keyName = { 0, 0, NULL };
+       LSA_UNICODE_STRING      *       secret = NULL;
+       char                            *       converted = 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++ )
+       ConvertDomainNameToCString(domain, dstring);
+       dlen = strlen(dstring);
+       for (i = 0; i < dlen; i++)
        {
-               domain.m_utf8[i] = (char) tolower( domain.m_utf8[i] );  // canonicalize -> lower case
+               dstring[i] = (char) tolower(dstring[i]);  // canonicalize -> lower case
        }
 
-       MakeDomainNameFromDNSNameString( &domain.m_dname, domain.m_utf8 );
+       MakeDomainNameFromDNSNameString(&canon, dstring);
+       d = &canon;
 
        // attrs are reserved, so initialize to zeroes.
 
-       ZeroMemory( &attrs, sizeof( attrs ) );
+       ZeroMemory(&attrs, sizeof( attrs ) );
 
        // Get a handle to the Policy object on the local system
 
@@ -1556,59 +1501,38 @@ dDNSPlatformSetSecretForDomain( mDNS *m, const domainname * inDomain )
 
        // 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 );
+       err = ConvertUTF8ToLsaString( dstring, &keyName );
        require_noerr( err, exit );
 
-       // Retrieve the key
-
-       res = LsaRetrievePrivateData( handle, domain.m_lsa, &key.m_lsa );
+       res = LsaRetrievePrivateData( handle, &keyName, &secret );
        err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
        require_noerr_quiet( err, exit );
 
-       // Convert the key to a domainname
+       // Convert the unicode to string to 8 bit
 
-       err = MakeUTF8StringFromLsaString( key.m_utf8, sizeof( key.m_utf8 ), key.m_lsa );
+       err = ConvertLsaStringToUTF8( secret, &converted );
        require_noerr( err, exit );
-       MakeDomainNameFromDNSNameString( &key.m_dname, key.m_utf8 );
 
-       // 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 );
-       
-       // 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_SetSecretForZone( m, &domain.m_dname, &key.m_dname, secret.m_utf8 );
+       mDNS_SetSecretForZone( m, d, d, converted );
 
 exit:
 
-       if ( domain.m_lsa != NULL )
+       if ( converted )
        {
-               if ( domain.m_lsa->Buffer != NULL )
-               {
-                       free( domain.m_lsa->Buffer );
-               }
-
-               free( domain.m_lsa );
+               free( converted );
+               converted = NULL;
        }
 
-       if ( key.m_lsa != NULL )
+       if ( secret )
        {
-               LsaFreeMemory( key.m_lsa );
+               LsaFreeMemory( secret );
+               secret = NULL;
        }
 
-       if ( secret.m_lsa != NULL )
+       if ( keyName.Buffer )
        {
-               LsaFreeMemory( secret.m_lsa );
+               free( keyName.Buffer );
+               keyName.Buffer = NULL;
        }
 
        if ( handle )
@@ -1756,64 +1680,35 @@ exit:
 IPAddrListElem*
 dDNSPlatformGetDNSServers( void )
 {
-       PIP_PER_ADAPTER_INFO    pAdapterInfo    =       NULL;
-       FIXED_INFO                      *       fixedInfo       = NULL;
-       ULONG                                   bufLen          = 0;    
-       IP_ADDR_STRING          *       dnsServerList;
-       IP_ADDR_STRING          *       ipAddr;
-       IPAddrListElem          *       head            = NULL;
-       IPAddrListElem          *       current         = NULL;
-       DWORD                                   index;
+       FIXED_INFO              *       fixedInfo       = NULL;
+       ULONG                           bufLen          = sizeof( FIXED_INFO ); 
+       IP_ADDR_STRING  *       ipAddr;
+       IPAddrListElem  *       head            = NULL;
+       IPAddrListElem  *       current         = NULL;
        int                                     i                       = 0;
        mStatus                         err;
 
-       // Get the primary interface.
-
-       index = GetPrimaryInterface();
-
-       // This should have the interface index of the primary index.  Fall back in cases where
-       // it can't be determined.
-
-       if ( index )
+       while ( 1 )
        {
-               bufLen = 0;
-
-               while ( GetPerAdapterInfo( index, pAdapterInfo, &bufLen ) == ERROR_BUFFER_OVERFLOW )
+               if ( fixedInfo )
                {
-                       pAdapterInfo = (PIP_PER_ADAPTER_INFO) realloc( pAdapterInfo, bufLen );
-                       require_action( pAdapterInfo, exit, err = mStatus_NoMemoryErr );
+                       GlobalFree( fixedInfo );
+                       fixedInfo = NULL;
                }
 
-               dnsServerList = &pAdapterInfo->DnsServerList;
-       }
-       else
-       {
-               bufLen = sizeof( FIXED_INFO );
+               fixedInfo = (FIXED_INFO*) GlobalAlloc( GPTR, bufLen );
+   
+               err = GetNetworkParams( fixedInfo, &bufLen );
 
-               while ( 1 )
+               if ( ( err != ERROR_BUFFER_OVERFLOW ) || ( i++ == 100 ) )
                {
-                       if ( fixedInfo )
-                       {
-                               GlobalFree( fixedInfo );
-                               fixedInfo = NULL;
-                       }
-
-                       fixedInfo = (FIXED_INFO*) GlobalAlloc( GPTR, bufLen );
-          
-                       err = GetNetworkParams( fixedInfo, &bufLen );
-
-                       if ( ( err != ERROR_BUFFER_OVERFLOW ) || ( i++ == 100 ) )
-                       {
-                               break;
-                       }
+                       break;
                }
-
-               require_noerr( err, exit );
-
-               dnsServerList = &fixedInfo->DnsServerList;
        }
 
-       for ( ipAddr = dnsServerList; ipAddr; ipAddr = ipAddr->Next )
+       require_noerr( err, exit );
+
+       for ( ipAddr = &fixedInfo->DnsServerList; ipAddr; ipAddr = ipAddr->Next )
        {
                mDNSAddr                        addr;
                IPAddrListElem  *       last = current;
@@ -1844,11 +1739,6 @@ dDNSPlatformGetDNSServers( void )
 
 exit:
 
-       if ( pAdapterInfo )
-       {
-               free( pAdapterInfo );
-       }
-
        if ( fixedInfo )
        {
                GlobalFree( fixedInfo );
@@ -1945,7 +1835,6 @@ dDNSPlatformGetPrimaryInterface( mDNS * m, mDNSAddr * primary, mDNSAddr * router
        DWORD                           bufLen          = sizeof( IP_ADAPTER_INFO );
        int                                     i;
        BOOL                            found;
-       DWORD                           index;
        mStatus                         err = mStatus_NoError;
 
        DEBUG_UNUSED( m );
@@ -1972,7 +1861,10 @@ dDNSPlatformGetPrimaryInterface( mDNS * m, mDNSAddr * primary, mDNSAddr * router
                }
        }
 
-       index = GetPrimaryInterface();
+       // Windows doesn't really have a concept of a primary adapter,
+       // so we're just going to iterate through all the adapters and
+       // pick the first one that has an IP address assigned and
+       // a gateway assigned
 
        for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
        {
@@ -1981,8 +1873,7 @@ dDNSPlatformGetPrimaryInterface( mDNS * m, mDNSAddr * primary, mDNSAddr * router
                     pAdapter->GatewayList.IpAddress.String &&
                     pAdapter->GatewayList.IpAddress.String[0] &&
                     ( StringToAddress( primary, pAdapter->IpAddressList.IpAddress.String ) == mStatus_NoError ) &&
-                    ( StringToAddress( router, pAdapter->GatewayList.IpAddress.String ) == mStatus_NoError ) &&
-                    ( !index || ( pAdapter->Index == index ) ) )
+                    ( StringToAddress( router, pAdapter->GatewayList.IpAddress.String ) == mStatus_NoError ) )
                {
                        // Found one that will work
 
@@ -1991,6 +1882,16 @@ dDNSPlatformGetPrimaryInterface( mDNS * m, mDNSAddr * primary, mDNSAddr * router
                }
        }
 
+       if ( !found )
+       {
+               // If we couldn't find one, then let's try the first one in the list
+
+               err = StringToAddress( primary, pAdapter->IpAddressList.IpAddress.String );
+               require_noerr( err, exit );
+
+               found = TRUE;
+       }
+
 exit:
 
        if ( pAdapterInfo )
@@ -2331,24 +2232,19 @@ mDNSlocal mStatus       SetupInterfaceList( mDNS * const inMDNS )
        mDNSInterfaceData *                     ifd;
        struct ifaddrs *                        addrs;
        struct ifaddrs *                        p;
-       struct ifaddrs *                        loopbackv4;
-       struct ifaddrs *                        loopbackv6;
+       struct ifaddrs *                        loopback;
        u_int                                           flagMask;
        u_int                                           flagTest;
-       mDNSBool                                        foundv4;
-       mDNSBool                                        foundv6;
-       mDNSBool                                        foundUnicastSock4DestAddr;
-       mDNSBool                                        foundUnicastSock6DestAddr;
+       BOOL                                            foundUnicastSock4DestAddr;
+       BOOL                                            foundUnicastSock6DestAddr;
        
        dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list\n" );
        check( inMDNS );
        check( inMDNS->p );
        
        addrs                                           = NULL;
-       foundv4                                         = mDNSfalse;
-       foundv6                                         = mDNSfalse;
-       foundUnicastSock4DestAddr       = mDNSfalse;
-       foundUnicastSock6DestAddr       = mDNSfalse;
+       foundUnicastSock4DestAddr       = FALSE;
+       foundUnicastSock6DestAddr       = FALSE;
        
        // Tear down any existing interfaces that may be set up.
        
@@ -2370,11 +2266,10 @@ mDNSlocal mStatus       SetupInterfaceList( mDNS * const inMDNS )
        err = getifaddrs( &addrs );
        require_noerr( err, exit );
        
-       loopbackv4      = NULL;
-       loopbackv6      = NULL;
+       loopback        = NULL;
        next            = &inMDNS->p->interfaceList;
-
-       flagMask = IFF_UP | IFF_MULTICAST;
+       
+       flagMask = IFF_UP | IFF_MULTICAST | IFF_POINTTOPOINT;
        flagTest = IFF_UP | IFF_MULTICAST;
        
 #if( MDNS_WINDOWS_ENABLE_IPV4 )
@@ -2386,9 +2281,9 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS )
                }
                if( p->ifa_flags & IFF_LOOPBACK )
                {
-                       if( !loopbackv4 )
+                       if( !loopback )
                        {
-                               loopbackv4 = p;
+                               loopback = p;
                        }
                        continue;
                }
@@ -2397,16 +2292,7 @@ mDNSlocal mStatus        SetupInterfaceList( mDNS * const inMDNS )
                
                err = SetupInterface( inMDNS, p, &ifd );
                require_noerr( err, exit );
-
-               // If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
-               // register him, but we also want to note that we haven't found a v4 interface
-               // so that we register loopback so same host operations work
-               
-               if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
-               {
-                       foundv4 = mDNStrue;
-               }
-
+               
                // If we're on a platform that doesn't have WSARecvMsg(), there's no way
                // of determing the destination address of a packet that is sent to us.
                // For multicast packets, that's easy to determine.  But for the unicast
@@ -2422,6 +2308,8 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS )
                *next = ifd;
                next  = &ifd->next;
                ++inMDNS->p->interfaceCount;
+
+               
        }
 #endif
        
@@ -2436,9 +2324,9 @@ mDNSlocal mStatus SetupInterfaceList( mDNS * const inMDNS )
                }
                if( p->ifa_flags & IFF_LOOPBACK )
                {
-                       if( !loopbackv6 )
+                       if( !loopback )
                        {
-                               loopbackv6 = p;
+                               loopback = p;
                        }
                        continue;
                }
@@ -2448,15 +2336,6 @@ mDNSlocal mStatus        SetupInterfaceList( mDNS * const inMDNS )
                err = SetupInterface( inMDNS, p, &ifd );
                require_noerr( err, exit );
                                
-               // If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
-               // register him, but we also want to note that we haven't found a v4 interface
-               // so that we register loopback so same host operations work
-               
-               if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
-               {
-                       foundv6 = mDNStrue;
-               }
-
                // If we're on a platform that doesn't have WSARecvMsg(), there's no way
                // of determing the destination address of a packet that is sent to us.
                // For multicast packets, that's easy to determine.  But for the unicast
@@ -2492,19 +2371,18 @@ mDNSlocal mStatus       SetupInterfaceList( mDNS * const inMDNS )
                {
                        continue;
                }
-               
-               v4loopback = p;
+               loopback = p;
                break;
        }
        
 #endif
        
-       if ( !foundv4 && loopbackv4 )
+       if( !inMDNS->p->interfaceList && loopback )
        {
                dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", 
-                       loopbackv4->ifa_name ? loopbackv4->ifa_name : "<null>", loopbackv4->ifa_extra.index, loopbackv4->ifa_addr );
+                       loopback->ifa_name ? loopback->ifa_name : "<null>", loopback->ifa_extra.index, loopback->ifa_addr );
                
-               err = SetupInterface( inMDNS, loopbackv4, &ifd );
+               err = SetupInterface( inMDNS, loopback, &ifd );
                require_noerr( err, exit );
                
 #if( MDNS_WINDOWS_ENABLE_IPV4 )
@@ -2619,6 +2497,7 @@ mDNSlocal mStatus SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inI
        ifd->sock               = kInvalidSocketRef;
        ifd->index              = inIFA->ifa_extra.index;
        ifd->scopeID    = inIFA->ifa_extra.index;
+       
        check( strlen( inIFA->ifa_name ) < sizeof( ifd->name ) );
        strncpy( ifd->name, inIFA->ifa_name, sizeof( ifd->name ) - 1 );
        ifd->name[ sizeof( ifd->name ) - 1 ] = '\0';
@@ -2633,7 +2512,7 @@ mDNSlocal mStatus SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inI
        // but we cut the packet rate in half. At this time, reducing the packet rate is more important than v6-only 
        // devices on a large configured network, so we are willing to make that sacrifice.
        
-       ifd->interfaceInfo.McastTxRx   = ( ( inIFA->ifa_flags & IFF_MULTICAST ) && !( inIFA->ifa_flags & IFF_POINTTOPOINT ) ) ? mDNStrue : mDNSfalse;
+       ifd->interfaceInfo.McastTxRx   = mDNStrue;
        ifd->interfaceInfo.InterfaceID = NULL;
 
        for( p = inMDNS->p->interfaceList; p; p = p->next )
@@ -2642,6 +2521,7 @@ mDNSlocal mStatus SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inI
                {
                        if (!ifd->interfaceInfo.InterfaceID)
                        {
+                               p->scopeID                                              = ifd->scopeID;
                                ifd->interfaceInfo.InterfaceID  = (mDNSInterfaceID) p;
                        }
 
@@ -3616,7 +3496,7 @@ mDNSlocal void    ProcessingThreadProcessPacket( mDNS *inMDNS, mDNSInterfaceData *i
 
                                if ( inIFD )
                                {
-                                       require_action( ipv4PacketInfo->ipi_ifindex == inIFD->index, exit, err = kMismatchErr );
+                                       require_action( ipv4PacketInfo->ipi_ifindex == ( inIFD->index >> 8 ), exit, err = kMismatchErr );
                                }
 
                                dstAddr.type                            = mDNSAddrType_IPv4;
@@ -3630,7 +3510,7 @@ mDNSlocal void    ProcessingThreadProcessPacket( mDNS *inMDNS, mDNSInterfaceData *i
 
                                if ( inIFD )
                                {
-                                       require_action( ipv6PacketInfo->ipi6_ifindex == ( inIFD->index - kIPv6IfIndexBase), exit, err = kMismatchErr );
+                                       require_action( ipv6PacketInfo->ipi6_ifindex == inIFD->index, exit, err = kMismatchErr );
                                }
 
                                dstAddr.type    = mDNSAddrType_IPv6;
@@ -3697,13 +3577,6 @@ mDNSlocal void   ProcessingThreadInterfaceListChanged( mDNS *inMDNS )
        err = SetupInterfaceList( inMDNS );
        check_noerr( err );
                
-       err = dDNS_Setup( inMDNS );
-       check_noerr( err );
-
-       // so that LLQs are restarted against the up to date name servers
-
-       mDNS_UpdateLLQs( inMDNS );
-
        mDNSPlatformUnlock( inMDNS );
        
        // Inform clients of the change.
@@ -3765,10 +3638,6 @@ mDNSlocal void ProcessingThreadTCPIPConfigChanged( mDNS * inMDNS )
        err = dDNS_Setup( inMDNS );
        check_noerr( err );
 
-       // so that LLQs are restarted against the up to date name servers
-
-       mDNS_UpdateLLQs( inMDNS );
-
        // and reset the event handler
 
        if ( ( inMDNS->p->tcpipKey != NULL ) && ( inMDNS->p->tcpipChangedEvent ) )
@@ -3796,10 +3665,6 @@ mDNSlocal void   ProcessingThreadDynDNSConfigChanged( mDNS *inMDNS )
        err = dDNS_Setup( inMDNS );
        check_noerr( err );
 
-       // so that LLQs are restarted against the up to date name servers
-
-       mDNS_UpdateLLQs( inMDNS );
-
        // and reset the event handler
 
        if ((inMDNS->p->ddnsKey != NULL) && (inMDNS->p->ddnsChangedEvent))
@@ -3905,7 +3770,7 @@ mDNSlocal int     getifaddrs_ipv6( struct ifaddrs **outAddrs )
        // This loops to handle the case where the interface changes in the window after getting the size, but before the
        // second call completes. A limit of 100 retries is enforced to prevent infinite loops if something else is wrong.
        
-       flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
+       flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
        i = 0;
        for( ;; )
        {
@@ -4003,27 +3868,16 @@ mDNSlocal int   getifaddrs_ipv6( struct ifaddrs **outAddrs )
                        ifa->ifa_flags = 0;
                        if( iaa->OperStatus == IfOperStatusUp )                 ifa->ifa_flags |= IFF_UP;
                        if( iaa->IfType == IF_TYPE_SOFTWARE_LOOPBACK )  ifa->ifa_flags |= IFF_LOOPBACK;
-                       else if ( IsPointToPoint( addr ) )                              ifa->ifa_flags |= IFF_POINTTOPOINT;
                        if( !( iaa->Flags & IP_ADAPTER_NO_MULTICAST ) ) ifa->ifa_flags |= IFF_MULTICAST;
-
                        
-                       // <rdar://problem/4045657> Interface index being returned is 512
-                       //
-                       // Windows does not have a uniform scheme for IPv4 and IPv6 interface indexes.
-                       // This code used to shift the IPv4 index up to ensure uniqueness between
-                       // it and IPv6 indexes.  Although this worked, it was somewhat confusing to developers, who
-                       // then see interface indexes passed back that don't correspond to anything
-                       // that is seen in Win32 APIs or command line tools like "route".  As a relatively
-                       // small percentage of developers are actively using IPv6, it seems to 
-                       // make sense to make our use of IPv4 as confusion free as possible.
-                       // So now, IPv6 interface indexes will be shifted up by a
-                       // constant value which will serve to uniquely identify them, and we will
-                       // leave IPv4 interface indexes unmodified.
+                       // Get the interface index. Windows does not have a uniform scheme for IPv4 and IPv6 interface indexes
+                       // so the following is a hack to put IPv4 interface indexes in the upper 24-bits and IPv6 interface indexes
+                       // in the lower 8-bits. This allows the IPv6 interface index to be usable as an IPv6 scope ID directly.
                        
                        switch( family )
                        {
-                               case AF_INET:  ifa->ifa_extra.index = iaa->IfIndex; break;
-                               case AF_INET6: ifa->ifa_extra.index = ipv6IfIndex + kIPv6IfIndexBase;    break;
+                               case AF_INET:  ifa->ifa_extra.index = iaa->IfIndex << 8; break;
+                               case AF_INET6: ifa->ifa_extra.index = ipv6IfIndex;       break;
                                default: break;
                        }
                        
@@ -4059,7 +3913,7 @@ mDNSlocal int     getifaddrs_ipv6( struct ifaddrs **outAddrs )
                        {
                                case AF_INET:
                                {
-                                       struct sockaddr_in * sa4;
+                                       struct sockaddr_in *            sa4;
                                        
                                        require_action( prefixLength <= 32, exit, err = ERROR_INVALID_DATA );
                                        
@@ -4067,21 +3921,12 @@ mDNSlocal int   getifaddrs_ipv6( struct ifaddrs **outAddrs )
                                        require_action( sa4, exit, err = WSAENOBUFS );
                                        
                                        sa4->sin_family = AF_INET;
-                                       
-                                       if ( prefixLength != 0 )
-                                       {
-                                               sa4->sin_addr.s_addr = htonl( 0xFFFFFFFFU << ( 32 - prefixLength ) );
-                                       }
-                                       else
+                                       if( prefixLength == 0 )
                                        {
-                                               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 );
+                                               dlog( kDebugLevelWarning, DEBUG_NAME "%s: IPv4 netmask 0, defaulting to 255.255.255.255\n", __ROUTINE__ );
+                                               prefixLength = 32;
                                        }
-
-                                       dlog( kDebugLevelInfo, DEBUG_NAME "%s: IPv4 mask = %s\n", __ROUTINE__, inet_ntoa( sa4->sin_addr ) );
+                                       sa4->sin_addr.s_addr = htonl( 0xFFFFFFFFU << ( 32 - prefixLength ) );
                                        ifa->ifa_netmask = (struct sockaddr *) sa4;
                                        break;
                                }
@@ -4228,31 +4073,32 @@ mDNSlocal int   getifaddrs_ipv4( struct ifaddrs **outAddrs )
                
                // Get addresses.
                
-               if ( ifInfo->iiAddress.Address.sa_family == AF_INET )
+               switch( ifInfo->iiAddress.Address.sa_family )
                {
-                       struct sockaddr_in *            sa4;
-                       
-                       sa4 = &ifInfo->iiAddress.AddressIn;
-                       ifa->ifa_addr = (struct sockaddr *) calloc( 1, sizeof( *sa4 ) );
-                       require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
-                       memcpy( ifa->ifa_addr, sa4, sizeof( *sa4 ) );
-
-                       ifa->ifa_netmask = (struct sockaddr*) calloc(1, sizeof( *sa4 ) );
+                       case AF_INET:
+                       {
+                               struct sockaddr_in *            sa4;
+                               
+                               sa4 = &ifInfo->iiAddress.AddressIn;
+                               ifa->ifa_addr = (struct sockaddr *) calloc( 1, sizeof( *sa4 ) );
+                               require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
+                               memcpy( ifa->ifa_addr, sa4, sizeof( *sa4 ) );
 
-                       // <rdar://problem/4076478> Service won't start on Win2K. The address
-                       // family field was not being initialized.
+                               sa4 = &ifInfo->iiNetmask.AddressIn;
+                               ifa->ifa_netmask = (struct sockaddr*) calloc(1, sizeof( *sa4 ) );
+                               require_action( ifa->ifa_netmask, exit, err = WSAENOBUFS );
+                               memcpy( ifa->ifa_netmask, sa4, sizeof( *sa4 ) );
 
-                       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 );
+                               break;
+                       }
+                       
+                       default:
+                               break;
                }
-               else
-               {
-                       // Emulate an interface index.
                
-                       ifa->ifa_extra.index = (uint32_t)( i + 1 );
-               }
+               // Emulate an interface index.
+               
+               ifa->ifa_extra.index = (uint32_t)( i + 1 );
        }
        
        // Success!
@@ -4451,118 +4297,6 @@ void    freeifaddrs( struct ifaddrs *inIFAs )
        }
 }
 
-
-//===========================================================================================================================
-//     GetPrimaryInterface
-//===========================================================================================================================
-
-mDNSlocal DWORD
-GetPrimaryInterface()
-{
-       PMIB_IPFORWARDTABLE     pIpForwardTable = NULL;
-       DWORD                           dwSize                  = 0;
-       BOOL                            bOrder                  = FALSE;
-       OSStatus                        err;
-       DWORD                           index                   = 0;
-       DWORD                           metric                  = 0;
-       unsigned long int       i;
-
-       // Find out how big our buffer needs to be.
-
-       err = GetIpForwardTable(NULL, &dwSize, bOrder);
-       require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
-
-       // Allocate the memory for the table
-
-       pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
-       require_action( pIpForwardTable, exit, err = kNoMemoryErr );
-  
-       // Now get the table.
-
-       err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
-       require_noerr( err, exit );
-
-
-       // Search for the row in the table we want.
-
-       for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
-       {
-               // Look for a default route
-
-               if ( pIpForwardTable->table[i].dwForwardDest == 0 )
-               {
-                       if ( index && ( pIpForwardTable->table[i].dwForwardMetric1 >= metric ) )
-                       {
-                               continue;
-                       }
-
-                       index   = pIpForwardTable->table[i].dwForwardIfIndex;
-                       metric  = pIpForwardTable->table[i].dwForwardMetric1;
-               }
-       }
-
-exit:
-
-       if ( pIpForwardTable != NULL )
-       {
-               free( pIpForwardTable );
-       }
-
-       return index;
-}
-
-
-//===========================================================================================================================
-//     AddressToIndexAndMask
-//===========================================================================================================================
-
-mDNSlocal mStatus
-AddressToIndexAndMask( struct sockaddr * addr, uint32_t * ifIndex, struct sockaddr * mask  )
-{
-       // Before calling AddIPAddress we use GetIpAddrTable to get
-       // an adapter to which we can add the IP.
-       
-       PMIB_IPADDRTABLE        pIPAddrTable    = NULL;
-       DWORD                           dwSize                  = 0;
-       mStatus                         err                             = mStatus_UnknownErr;
-       DWORD                           i;
-
-       // For now, this is only for IPv4 addresses.  That is why we can safely cast
-       // addr's to sockaddr_in.
-
-       require_action( addr->sa_family == AF_INET, exit, err = mStatus_UnknownErr );
-
-       // Make an initial call to GetIpAddrTable to get the
-       // necessary size into the dwSize variable
-
-       while ( GetIpAddrTable( pIPAddrTable, &dwSize, 0 ) == ERROR_INSUFFICIENT_BUFFER )
-       {
-               pIPAddrTable = (MIB_IPADDRTABLE *) realloc( pIPAddrTable, dwSize );
-               require_action( pIPAddrTable, exit, err = WSAENOBUFS );
-       }
-
-       for ( i = 0; i < pIPAddrTable->dwNumEntries; i++ )
-       {
-               if ( ( ( struct sockaddr_in* ) addr )->sin_addr.s_addr == pIPAddrTable->table[i].dwAddr )
-               {
-                       *ifIndex                                                                                        = pIPAddrTable->table[i].dwIndex;
-                       ( ( struct sockaddr_in*) mask )->sin_addr.s_addr        = pIPAddrTable->table[i].dwMask;
-                       err                                                                                                     = mStatus_NoError;
-                       break;
-               }
-       }
-
-exit:
-
-       if ( pIPAddrTable )
-       {
-               free( pIPAddrTable );
-       }
-
-       return err;
-}
-
-
 //===========================================================================================================================
 //     CanReceiveUnicast
 //===========================================================================================================================
@@ -4593,49 +4327,6 @@ mDNSlocal mDNSBool       CanReceiveUnicast( void )
        return( ok );
 }
 
-
-//===========================================================================================================================
-//     IsPointToPoint
-//===========================================================================================================================
-
-mDNSlocal mDNSBool IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr )
-{
-       struct ifaddrs  *       addrs   =       NULL;
-       struct ifaddrs  *       p               =       NULL;
-       OSStatus                        err;
-       mDNSBool                        ret             =       mDNSfalse;
-
-       // For now, only works for IPv4 interfaces
-
-       if ( addr->Address.lpSockaddr->sa_family == AF_INET )
-       {
-               // The getifaddrs_ipv4 call will give us correct information regarding IFF_POINTTOPOINT flags.
-
-               err = getifaddrs_ipv4( &addrs );
-               require_noerr( err, exit );
-
-               for ( p = addrs; p; p = p->ifa_next )
-               {
-                       if ( ( addr->Address.lpSockaddr->sa_family == p->ifa_addr->sa_family ) &&
-                            ( ( ( struct sockaddr_in* ) addr->Address.lpSockaddr )->sin_addr.s_addr == ( ( struct sockaddr_in* ) p->ifa_addr )->sin_addr.s_addr ) )
-                       {
-                               ret = ( p->ifa_flags & IFF_POINTTOPOINT ) ? mDNStrue : mDNSfalse;
-                               break;
-                       }
-               }
-       }
-
-exit:
-
-       if ( addrs )
-       {
-               freeifaddrs( addrs );
-       }
-
-       return ret;
-}
-
-
 //===========================================================================================================================
 //     GetWindowsVersionString
 //===========================================================================================================================
@@ -4813,7 +4504,6 @@ static mStatus StringToAddress( mDNSAddr * ip, LPSTR string )
                dwSize = sizeof( sa4 );
 
                err = WSAStringToAddressA( string, AF_INET, NULL, (struct sockaddr*) &sa4, &dwSize );
-               err = translate_errno( err == 0, WSAGetLastError(), kUnknownErr );
                require_noerr( err, exit );
                        
                err = dDNS_SetupAddr( ip, (struct sockaddr*) &sa4 );
@@ -4916,7 +4606,7 @@ exit:
 //===========================================================================================================================
 
 mDNSlocal OSStatus
-MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input )
+ConvertUTF8ToLsaString( const char * input, PLSA_UNICODE_STRING output )
 {
        int                     size;
        OSStatus        err;
@@ -4960,36 +4650,41 @@ exit:
 //===========================================================================================================================
 
 static OSStatus
-MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input )
+ConvertLsaStringToUTF8( PLSA_UNICODE_STRING input, char ** output )
 {
-       size_t          size;
+       int                     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);
+       size = 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 );
+       // Add one for trailing '\0'
 
-       // Convert the string
+       *output = (char*) malloc( size + 1 );
+       require_action( *output, exit, err = mStatus_NoMemoryErr );
 
-       size = (size_t) WideCharToMultiByte( CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), output, (int) size, NULL, NULL); 
+       size = WideCharToMultiByte(CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), *output, 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';
+       (*output)[size] = '\0';
 
 exit:
 
+       if ( err && *output )
+       {
+               free( *output );
+               *output = NULL;
+       }
+
        return err;
 }
 
index d19254395cfb163b637b7eb554ab037be06b1f52..c690459adcf8b1f708ae50ae0230e0c97849471f 100644 (file)
     Change History (most recent first):
     
 $Log: mdnsNSP.c,v $
-Revision 1.14  2005/03/29 20:35:28  shersche
-<rdar://problem/4053899> Remove reverse lookup implementation due to NSP framework limitation
-
-Revision 1.13  2005/03/29 19:42:47  shersche
-Do label check before checking etc/hosts file
-
-Revision 1.12  2005/03/21 00:42:45  shersche
-<rdar://problem/4021486> Fix build warnings on Win32 platform
-
-Revision 1.11  2005/03/16 03:04:51  shersche
-<rdar://problem/4050633> Don't issue multicast query multilabel dot-local names
-
 Revision 1.10  2005/02/23 22:16:07  shersche
 Unregister the NSP before registering to workaround an installer problem during upgrade installs
 
@@ -239,11 +227,6 @@ DEBUG_LOCAL OSStatus       HostsFileOpen( HostsFile ** self, const char * fname );
 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] );
-
-#ifdef ENABLE_REVERSE_LOOKUP
-DEBUG_LOCAL OSStatus   IsReverseLookup( LPCWSTR name, size_t size );
-#endif
 
 
 #if 0
@@ -562,49 +545,70 @@ DEBUG_LOCAL int WSPAPI
                ( ( p[ 4 ] != 'A' ) && ( p[ 4 ] != 'a' ) )      ||
                ( ( p[ 5 ] != 'L' ) && ( p[ 5 ] != 'l' ) ) ) )
        {
-#ifdef ENABLE_REVERSE_LOOKUP
-
-               err = IsReverseLookup( name, size );
-
-#else
-
-               err = WSASERVICE_NOT_FOUND;
-
-#endif
-
-               require_noerr( err, exit );
+               require_action_quiet( size > sizeof_string( ".0.8.e.f.ip6.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
+               p = name + ( size - 1 );
+               p = ( *p == '.' ) ? ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) : ( ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) + 1 );
+       
+               if      ( ( ( p[ 0 ] != '.' )                                                   ||
+                       ( ( p[ 1 ] != '0' ) )                                                   ||
+                       ( ( p[ 2 ] != '.' ) )                                                   ||
+                       ( ( p[ 3 ] != '8' ) )                                                   ||
+                       ( ( p[ 4 ] != '.' ) )                                                   ||
+                       ( ( p[ 5 ] != 'E' ) && ( p[ 5 ] != 'e' ) )              ||
+                       ( ( p[ 6 ] != '.' ) )                                                   ||
+                       ( ( p[ 7 ] != 'F' ) && ( p[ 7 ] != 'f' ) )              ||
+                       ( ( p[ 8 ] != '.' ) )                                                   ||
+                       ( ( p[ 9 ] != 'I' ) && ( p[ 9 ] != 'i' ) )              ||
+                       ( ( p[ 10 ] != 'P' ) && ( p[ 10 ] != 'p' ) )    ||      
+                       ( ( p[ 11 ] != '6' ) )                                                  ||
+                       ( ( p[ 12 ] != '.' ) )                                                  ||
+                       ( ( p[ 13 ] != 'A' ) && ( p[ 13 ] != 'a' ) )    ||
+                       ( ( p[ 14 ] != 'R' ) && ( p[ 14 ] != 'r' ) )    ||
+                       ( ( p[ 15 ] != 'P' ) && ( p[ 15 ] != 'p' ) )    ||
+                       ( ( p[ 16 ] != 'A' ) && ( p[ 16 ] != 'a' ) ) ) )
+               {
+                       require_action_quiet( size > sizeof_string( ".254.169.in-addr.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
+                       p = name + ( size - 1 );
+                       p = ( *p == '.' ) ? ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) : ( ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) + 1 );
+       
+       require_action_quiet( ( ( p[ 0 ] == '.' )                                                &&
+                                                                       ( ( p[ 1 ] == '2' ) )                                                   &&
+                                                                       ( ( p[ 2 ] == '5' ) )                                                   &&
+                                                                       ( ( p[ 3 ] == '4' ) )                                                   &&
+                                                                       ( ( p[ 4 ] == '.' ) )                                                   &&
+                                                                       ( ( p[ 5 ] == '1' ) )                                                   &&
+                                                                       ( ( p[ 6 ] == '6' ) )                                                   &&
+                                                                       ( ( p[ 7 ] == '9' ) )                                                   &&
+                                                                       ( ( p[ 8 ] == '.' ) )                                                   &&
+                                                                       ( ( p[ 9 ] == 'I' ) || ( p[ 9 ] == 'i' ) )              &&
+                                                                       ( ( p[ 10 ] == 'N' ) || ( p[ 10 ] == 'n' ) )    &&      
+                                                                       ( ( p[ 11 ] == '-' ) )                                                  &&
+                                                                       ( ( p[ 12 ] == 'A' ) || ( p[ 12 ] == 'a' ) )    &&
+                                                                       ( ( p[ 13 ] == 'D' ) || ( p[ 13 ] == 'd' ) )    &&
+                                                                       ( ( p[ 14 ] == 'D' ) || ( p[ 14 ] == 'd' ) )    &&
+                                                                       ( ( p[ 15 ] == 'R' ) || ( p[ 15 ] == 'r' ) )    &&
+                                                                       ( ( p[ 16 ] == '.' ) )                                                  &&
+                                                                       ( ( p[ 17 ] == 'A' ) || ( p[ 17 ] == 'a' ) )    &&
+                                                                       ( ( p[ 18 ] == 'R' ) || ( p[ 18 ] == 'r' ) )    &&
+                                                                       ( ( p[ 19 ] == 'P' ) || ( p[ 19 ] == 'p' ) )    &&
+                                                                       ( ( p[ 20 ] == 'A' ) || ( p[ 20 ] == 'a' ) ) ),
+                                                                       exit, err = WSASERVICE_NOT_FOUND );
+               }
        }
        else
        {
-               const char      *       replyDomain;
-               char                    translated[ kDNSServiceMaxDomainName ];
-               int                             n;
-               int                             labels          = 0;
-               const char      *       label[128];
-               char                    text[64];
-
-               n = WideCharToMultiByte( CP_UTF8, 0, name, -1, translated, sizeof( translated ), NULL, NULL );
-               require_action( n > 0, exit, err = WSASERVICE_NOT_FOUND );
-
-               // <rdar://problem/4050633>
-
-               // Don't resolve multi-label name
-
-               replyDomain = translated;
-
-               while ( *replyDomain )
-               {
-                       label[labels++] = replyDomain;
-                       replyDomain             = GetNextLabel(replyDomain, text);
-               }
-
-               require_action( labels == 2, exit, err = WSASERVICE_NOT_FOUND );
-
                // <rdar://problem/3936771>
                //
                // Check to see if the name of this host is in the hosts table. If so,
                // don't try and resolve it
                
+               char    translated[ kDNSServiceMaxDomainName ];
+               int             n;
+
+               n = WideCharToMultiByte( CP_UTF8, 0, name, -1, translated, sizeof( translated ), NULL, NULL );
+               require_action( n > 0, exit, err = WSASERVICE_NOT_FOUND );
                require_action( InHostsTable( translated ) == FALSE, exit, err = WSASERVICE_NOT_FOUND );
        }
 
@@ -1980,108 +1984,3 @@ exit:
 
        return err;
 }
-
-
-//===========================================================================================================================
-//     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
-//===========================================================================================================================
-
-DEBUG_LOCAL OSStatus
-IsReverseLookup( LPCWSTR name, size_t size )
-{
-       LPCWSTR         p;
-       OSStatus        err = kNoErr;
-
-       require_action_quiet( size > sizeof_string( ".0.8.e.f.ip6.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
-       p = name + ( size - 1 );
-       p = ( *p == '.' ) ? ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) : ( ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) + 1 );
-       
-       if      ( ( ( p[ 0 ] != '.' )                                                   ||
-               ( ( p[ 1 ] != '0' ) )                                                   ||
-               ( ( p[ 2 ] != '.' ) )                                                   ||
-               ( ( p[ 3 ] != '8' ) )                                                   ||
-               ( ( p[ 4 ] != '.' ) )                                                   ||
-               ( ( p[ 5 ] != 'E' ) && ( p[ 5 ] != 'e' ) )              ||
-               ( ( p[ 6 ] != '.' ) )                                                   ||
-               ( ( p[ 7 ] != 'F' ) && ( p[ 7 ] != 'f' ) )              ||
-               ( ( p[ 8 ] != '.' ) )                                                   ||
-               ( ( p[ 9 ] != 'I' ) && ( p[ 9 ] != 'i' ) )              ||
-               ( ( p[ 10 ] != 'P' ) && ( p[ 10 ] != 'p' ) )    ||      
-               ( ( p[ 11 ] != '6' ) )                                                  ||
-               ( ( p[ 12 ] != '.' ) )                                                  ||
-               ( ( p[ 13 ] != 'A' ) && ( p[ 13 ] != 'a' ) )    ||
-               ( ( p[ 14 ] != 'R' ) && ( p[ 14 ] != 'r' ) )    ||
-               ( ( p[ 15 ] != 'P' ) && ( p[ 15 ] != 'p' ) )    ||
-               ( ( p[ 16 ] != 'A' ) && ( p[ 16 ] != 'a' ) ) ) )
-       {
-               require_action_quiet( size > sizeof_string( ".254.169.in-addr.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
-               p = name + ( size - 1 );
-               p = ( *p == '.' ) ? ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) : ( ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) + 1 );
-       
-               require_action_quiet( ( ( p[ 0 ] == '.' )                                                &&
-                                                               ( ( p[ 1 ] == '2' ) )                                                   &&
-                                                               ( ( p[ 2 ] == '5' ) )                                                   &&
-                                                               ( ( p[ 3 ] == '4' ) )                                                   &&
-                                                               ( ( p[ 4 ] == '.' ) )                                                   &&
-                                                               ( ( p[ 5 ] == '1' ) )                                                   &&
-                                                               ( ( p[ 6 ] == '6' ) )                                                   &&
-                                                               ( ( p[ 7 ] == '9' ) )                                                   &&
-                                                               ( ( p[ 8 ] == '.' ) )                                                   &&
-                                                               ( ( p[ 9 ] == 'I' ) || ( p[ 9 ] == 'i' ) )              &&
-                                                               ( ( p[ 10 ] == 'N' ) || ( p[ 10 ] == 'n' ) )    &&      
-                                                               ( ( p[ 11 ] == '-' ) )                                                  &&
-                                                               ( ( p[ 12 ] == 'A' ) || ( p[ 12 ] == 'a' ) )    &&
-                                                               ( ( p[ 13 ] == 'D' ) || ( p[ 13 ] == 'd' ) )    &&
-                                                               ( ( p[ 14 ] == 'D' ) || ( p[ 14 ] == 'd' ) )    &&
-                                                               ( ( p[ 15 ] == 'R' ) || ( p[ 15 ] == 'r' ) )    &&
-                                                               ( ( p[ 16 ] == '.' ) )                                                  &&
-                                                               ( ( p[ 17 ] == 'A' ) || ( p[ 17 ] == 'a' ) )    &&
-                                                               ( ( p[ 18 ] == 'R' ) || ( p[ 18 ] == 'r' ) )    &&
-                                                               ( ( p[ 19 ] == 'P' ) || ( p[ 19 ] == 'p' ) )    &&
-                                                               ( ( p[ 20 ] == 'A' ) || ( p[ 20 ] == 'a' ) ) ),
-                                                               exit, err = WSASERVICE_NOT_FOUND );
-       }
-
-       // It's a reverse lookup
-
-       check( err == kNoErr );
-
-exit:
-
-       return err;
-}
-#endif