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
#define kTXTRecordKeyPath "path"
-// IE Icon resource
-
-#define kIEIconResource 32529
-
#if 0
#pragma mark == Prototypes ==
{
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
- HINSTANCE module = NULL;
OSStatus err;
CRect rect;
CBitmap bitmap;
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 );
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 )
{
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
<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
<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
</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
CommandLine="if not exist Release\Root mkdir Release\Root\r
if not exist "Release\Root\Program Files" mkdir "Release\Root\Program Files"\r
if not exist "Release\Root\Program Files\Bonjour" mkdir "Release\Root\Program Files\Bonjour"\r
-if not exist "Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources" mkdir "Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources"\r
-if not exist "Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources\en.lproj" mkdir "Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources\en.lproj""/>\r
+if not exist "Release\Root\Program Files\Bonjour\Resources" mkdir "Release\Root\Program Files\Bonjour\Resources"\r
+if not exist "Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources" mkdir "Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources"\r
+if not exist "Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources\en.lproj" mkdir "Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources\en.lproj""/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
\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
<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
<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
</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 "Release\Root\Program Files" mkdir "Release\Root\Program Files"\r
if not exist "Release\Root\Program Files\Bonjour" mkdir "Release\Root\Program Files\Bonjour"\r
-if not exist "Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources" mkdir "Release\Root\Program Files\Bonjour\ExplorerPlugin.Resources""/>\r
+if not exist "Release\Root\Program Files\Bonjour\Resources" mkdir "Release\Root\Program Files\Bonjour\Resources"\r
+if not exist "Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources" mkdir "Release\Root\Program Files\Bonjour\Resources\ExplorerPlugin.dll.Resources""/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
#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
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
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);
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
// 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 );
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
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
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
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
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
\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
<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
<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
</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
CommandLine="if not exist Release\Root mkdir Release\Root\r
if not exist "Release\Root\Program Files" mkdir "Release\Root\Program Files"\r
if not exist "Release\Root\Program Files\Bonjour" mkdir "Release\Root\Program Files\Bonjour"\r
-if not exist "Release\Root\Program Files\Bonjour\PrinterWizard.Resources" mkdir "Release\Root\Program Files\Bonjour\PrinterWizard.Resources"\r
-if not exist "Release\Root\Program Files\Bonjour\PrinterWizard.Resources\en.lproj" mkdir "Release\Root\Program Files\Bonjour\PrinterWizard.Resources\en.lproj""/>\r
+if not exist "Release\Root\Program Files\Bonjour\Resources" mkdir "Release\Root\Program Files\Bonjour\Resources"\r
+if not exist "Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources" mkdir "Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources"\r
+if not exist "Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources\en.lproj" mkdir "Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources\en.lproj""/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
<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
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
<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
</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
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 "Release\Root\Program Files" mkdir "Release\Root\Program Files"\r
if not exist "Release\Root\Program Files\Bonjour" mkdir "Release\Root\Program Files\Bonjour"\r
-if not exist "Release\Root\Program Files\Bonjour\PrinterWizard.Resources" mkdir "Release\Root\Program Files\Bonjour\PrinterWizard.Resources""/>\r
+if not exist "Release\Root\Program Files\Bonjour\Resources" mkdir "Release\Root\Program Files\Bonjour\Resources"\r
+if not exist "Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources" mkdir "Release\Root\Program Files\Bonjour\Resources\PrinterWizard.exe.Resources""/>\r
<Tool\r
Name="VCResourceCompilerTool"\r
PreprocessorDefinitions="NDEBUG"\r
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"
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"";
{
DEBUG_UNUSED( service );
- Queue * q = service->SelectedQueue();
HANDLE hPrinter = NULL;
PRINTER_INFO_2 pInfo;
OSStatus err;
-
- check( q );
//
// add the printer
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;
CPrinterSetupWizardSheet * self;
Service * service;
Queue * q;
+ uint32_t qpriority = kDefaultPriority;
+ CString qname;
int idx;
OSStatus err;
//
service->portNumber = ntohs(inPort);
+ //
+ // parse the text record.
+ //
+
+ err = self->ParseTextRecord( service, inTXTSize, inTXT, qname, qpriority );
+ require_noerr( err, exit );
+
if ( service->qtotal == 1 )
{
//
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 );
//
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 );
//
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;
// <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 )
{
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->name );
+ err = UTF8StringToStringObject( buf, qname );
require_noerr( err, exit );
}
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->pdl );
+ err = UTF8StringToStringObject( buf, service->pdl );
require_noerr( err, exit );
}
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->usb_MFG );
+ err = UTF8StringToStringObject( buf, service->usb_MFG );
require_noerr( err, exit );
}
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->usb_MDL );
+ err = UTF8StringToStringObject( buf, service->usb_MDL );
require_noerr( err, exit );
}
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->description );
+ err = UTF8StringToStringObject( buf, service->description );
require_noerr( err, exit );
}
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->product );
+ err = UTF8StringToStringObject( buf, service->product );
require_noerr( err, exit );
}
memcpy( buf, val, len );
buf[len] = '\0';
- err = UTF8StringToStringObject( buf, q->location );
+ err = UTF8StringToStringObject( buf, service->location );
require_noerr( err, exit );
}
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;
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()
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();
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
// 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:
Printer * printer;
Printers::iterator it;
OSStatus err = kNoErr;
- BOOL b;
-
- b = CPropertyPage::OnSetActive();
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_action( psheet, exit, err = kUnknownErr );
exit:
- return b;
+ return CPropertyPage::OnSetActive();
}
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()
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
{
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
//
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
{
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 );
}
-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 )
{
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.
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(
CStatic m_descriptionField;\r
CStatic m_locationLabel;\r
CStatic m_locationField;\r
-
- bool m_gotChoice;
};
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
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 ) );
}
//
//
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 )
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 )
// 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);
nIndex = m_manufacturerListCtrl.InsertItem(0, manufacturer->name);
m_manufacturerListCtrl.SetItemData(nIndex, (DWORD_PTR) manufacturer);
-
- m_manufacturerListCtrl.SetColumnWidth( 0, LVSCW_AUTOSIZE_USEHEADER );
}
return 0;
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);
printer = psheet->GetSelectedPrinter();
require_quiet( printer, exit );
- printer->deflt = ( m_defaultPrinterCtrl.GetCheck() == BST_CHECKED ) ? true : false;
+ printer->deflt = m_defaultPrinterCtrl.GetState() ? true : false;
exit:
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
~Service();
- Queue*
- SelectedQueue();
-
void
EmptyQueues();
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;
CString name;
uint32_t priority;
- CString pdl;
- CString usb_MFG;
- CString usb_MDL;
- CString description;
- CString location;
- CString product;
};
EmptyQueues();
}
- inline Queue*
- Service::SelectedQueue()
- {
- return queues.front();
- }
-
inline void
Service::EmptyQueues()
{
{
Model * model = *it;
- if ( model->name == name )
+ if ( model->name = name )
{
return model;
}
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;
}
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)
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;
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)
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
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;
}
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
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
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;
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.
// 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.
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);
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
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);
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)
}
-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
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
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);
}
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;
}
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;
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)
{
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;
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;
}
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
// 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)
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;
{
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)
}
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; }
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)
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;
// 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);
}
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
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:
}
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:
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;
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:
info->ClientCallbackDeferred = mDNStrue;
info->DeferredStatus = err;
}
- info->SRVChanged = mDNSfalse;
+ info->SRVChanged = mDNSfalse;
UpdateSRV(m, srs);
return;
}
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)
{
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);
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
+ }
}
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,
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;
// 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;
mDNSs32 timenow = mDNSPlatformTimeNow(m);
uDNS_GlobalInfo *u = &m->uDNS_info;
- if (IsPrivateV4Addr(&u->PrimaryIP))
+ if (IsPrivateV4Addr(&u->AdvertisedV4))
{
if (!u->LLQNatInfo)
{
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;
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)
typedef struct
{
DNSQuestion *question;
- DNSMessage reply;
+ DNSMessage *reply;
mDNSu16 replylen;
int nread;
mDNS *m;
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]);
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);
}
}
error:
mDNSPlatformTCPCloseConnection(sd);
+ if (info->reply) ufree(info->reply);
ufree(info);
mDNS_Unlock(m);
}
#pragma mark - Dynamic Updates
#endif
-
-
mDNSlocal void sendRecordRegistration(mDNS *const m, AuthRecord *rr)
{
DNSMessage msg;
// set zone
ptr = putZone(&msg, ptr, end, ®Info->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; }
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:
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;
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;
{
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:
return mStatus_NoError;
}
- if (n) FreeNATInfo(m, n);
rr->uDNS_info.NATinfo = mDNSNULL;
-
+ if (n) FreeNATInfo(m, n);
+
SendRecordDeregistration(m, rr);
return mStatus_NoError;
}
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);
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;
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:
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
}
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
{
#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;
// 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)
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;
}
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
#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"
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
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/"
};
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
(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);
{
// ssize_t n;
struct sockaddr_in recvaddr;
- int recvaddrlen;
+ socklen_t recvaddrlen;
fd_set readfds;
struct timeval timeout;
int sEvent;
for (;;) {
ssize_t n;
struct sockaddr_in recvaddr;
- int recvaddrlen;
+ socklen_t recvaddrlen;
fd_set readfds;
//struct timeval timeout;
//int i;
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)
{
}
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);
char szPort[10];
Property propArgs[3];
PHTTPResponse resp;
- unsigned long ip;
+ unsigned long ip = 0;
sprintf( szPort, "%u", eport);
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
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;
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;
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);
}
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; }
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
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
// 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
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);
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)
{
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;
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);
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);
}
}
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;
}
// 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);
}
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));
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 = {
# 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
#
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
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
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 \
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
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);
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;
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;
}
}
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;
{
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; }
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
#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;
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;
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);
#ifdef NOT_HAVE_DAEMON
#include <fcntl.h>
#include <sys/stat.h>
-#include <signal.h>
-
int daemon(int nochdir, int noclose)
{
switch (fork())
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
#include <net/if.h>
#include <netinet/in.h>
-#ifdef HAVE_LINUX
-#include <linux/socket.h>
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
#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 ? \
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): */
{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
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
"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))
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
{
}
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;
}
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
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.
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)
// 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
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;
}
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
#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. */
#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.
{
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
}
// 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);
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);
}
-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
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)
{
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;
{
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));
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);
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;
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);
}
-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;
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);
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);
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;
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)
{
}
-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;
{
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));
}
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);
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;
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)
{
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);
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);
}
-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)
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);
}
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);
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;
{
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)
{
}
-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;
{
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
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);
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)
{
}
-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;
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;
#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];
}
-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;
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
#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
#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
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)"
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
};
-void DNSSD_API TXTRecordCreate
+void TXTRecordCreate
(
TXTRecordRef *txtRecord,
uint16_t bufferLen,
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,
return(kDNSServiceErr_NoError);
}
-DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
+DNSServiceErrorType TXTRecordRemoveValue
(
TXTRecordRef *txtRecord,
const char *key
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); }
/*********************************************************************************************
*
*
*********************************************************************************************/
-int DNSSD_API TXTRecordContainsKey
+int TXTRecordContainsKey
(
uint16_t txtLen,
const void *txtRecord,
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
}
-const void * DNSSD_API TXTRecordGetValuePtr
+const void * TXTRecordGetValuePtr
(
uint16_t txtLen,
const void *txtRecord,
return (item + 1 + keylen + 1);
}
-uint16_t DNSSD_API TXTRecordGetCount
+uint16_t TXTRecordGetCount
(
uint16_t txtLen,
const void *txtRecord
return((p>e) ? (uint16_t)0 : count);
}
-DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
+DNSServiceErrorType TXTRecordGetItemAtIndex
(
uint16_t txtLen,
const void *txtRecord,
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
char *msg = NULL;
ipc_msg_hdr *hdr;
int datalen;
-#if !defined(USE_TCP_LOOPBACK)
char ctrl_path[256];
-#endif
if (!reuse_socket)
{
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;
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
deliver_error(rstate, mStatus_BadParamErr);
abort_request(rstate);
unlink_request(rstate);
+ return;
}
// allocate context structures
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
-/*\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)
+};
-;\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
-/*\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();
-// 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
+
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
:
CPropertyPage(CFirstPage::IDD),
m_ignoreHostnameChange( false ),
- m_statusKey( NULL ),
- m_setupKey( NULL )
+ m_statusKey( NULL )
{
//{{AFX_DATA_INIT(CFirstPage)
//}}AFX_DATA_INIT
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;
}
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
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 );
}
CSecondPage::~CSecondPage()
{
- if ( m_setupKey )
- {
- RegCloseKey( m_setupKey );
- m_setupKey = NULL;
- }
}
CSecondPage::OnSetActive()
{
CConfigPropertySheet * psheet;
+ HKEY key = NULL;
DWORD dwSize;
DWORD enabled;
DWORD err;
// 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;
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 );
}
}
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();
}
string = (TCHAR*) malloc( stringLen );
require_action( string, exit, err = kUnknownErr );
- *string = '\0';
err = RegQueryValueEx( key, valueName, 0, NULL, (LPBYTE) string, &stringLen );
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
CButton m_advertiseServicesButton;
CButton m_sharedSecretButton;
BOOL m_modified;
- HKEY m_setupKey;
public:
afx_msg void OnCbnSelChange();
-/*\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;
+}
-/*\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;
+};
-//{{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
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
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
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
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)
// 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 );
//
if (gServiceManageLLRouting == true)
{
- SetLLRoute( &gMDNSRecord );
+ SetLLRoute();
}
exit:
static void
CoreCallback(mDNS * const inMDNS, mStatus status)
{
+ DEBUG_UNUSED( inMDNS );
+
if (status == mStatus_ConfigChanged)
{
if (gServiceManageLLRouting == true)
{
- SetLLRoute( inMDNS );
+ SetLLRoute();
}
}
}
//===========================================================================================================================
-// HaveRoute
+// HaveLLRoute
//===========================================================================================================================
static bool
-HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr )
+HaveLLRoute(PMIB_IPFORWARDROW rowExtant)
{
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
DWORD dwSize = 0;
//
for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
{
- if ( pIpForwardTable->table[i].dwForwardDest == addr )
+ if (pIpForwardTable->table[i].dwForwardDest == inet_addr(kLLNetworkAddr))
{
memcpy( rowExtant, &(pIpForwardTable->table[i]), sizeof(*rowExtant) );
found = true;
}
-//===========================================================================================================================
-// 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;
//
// 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.
}
//
- // 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;
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 );
IP_ADAPTER_INFO * pAdapterInfo = NULL;
IP_ADAPTER_INFO * pAdapter = NULL;
ULONG bufLen;
- mDNSBool done = mDNSfalse;
OSStatus err;
//
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:
return( err );
}
+
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
+ }
--- /dev/null
+<?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>
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
#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."
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>
{
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;
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);
}
}
{
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);
}
{
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
{
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)
#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;
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]);
if ( !strcmp( appPathNameA, "" ) )
{
char folder[MAX_PATH];
- char * ext;
char * app;
GetModuleFileNameA( module, folder, MAX_PATH );
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);
{
wchar_t folder[MAX_PATH];
wchar_t * app;
- wchar_t * ext;
GetModuleFileNameW( module, folder, MAX_PATH);
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);
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
static GUID kWSARecvMsgGUID = WSAID_WSARECVMSG;
#endif
-#define kIPv6IfIndexBase (10000000L)
-
#if 0
#pragma mark == Prototypes ==
// 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
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
{
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:
mDNSexport mDNSs32 mDNSPlatformUTC( void )
{
- return ( mDNSs32 ) time( NULL );
+ return( -1 );
}
//===========================================================================================================================
//===========================================================================================================================
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
// 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 )
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;
exit:
- if ( pAdapterInfo )
- {
- free( pAdapterInfo );
- }
-
if ( fixedInfo )
{
GlobalFree( fixedInfo );
DWORD bufLen = sizeof( IP_ADAPTER_INFO );
int i;
BOOL found;
- DWORD index;
mStatus err = mStatus_NoError;
DEBUG_UNUSED( m );
}
}
- 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 )
{
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
}
}
+ 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 )
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.
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 )
}
if( p->ifa_flags & IFF_LOOPBACK )
{
- if( !loopbackv4 )
+ if( !loopback )
{
- loopbackv4 = p;
+ loopback = p;
}
continue;
}
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
*next = ifd;
next = &ifd->next;
++inMDNS->p->interfaceCount;
+
+
}
#endif
}
if( p->ifa_flags & IFF_LOOPBACK )
{
- if( !loopbackv6 )
+ if( !loopback )
{
- loopbackv6 = p;
+ loopback = p;
}
continue;
}
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
{
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 )
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';
// 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 )
{
if (!ifd->interfaceInfo.InterfaceID)
{
+ p->scopeID = ifd->scopeID;
ifd->interfaceInfo.InterfaceID = (mDNSInterfaceID) p;
}
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;
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;
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.
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 ) )
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))
// 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( ;; )
{
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;
}
{
case AF_INET:
{
- struct sockaddr_in * sa4;
+ struct sockaddr_in * sa4;
require_action( prefixLength <= 32, exit, err = ERROR_INVALID_DATA );
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;
}
// 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!
}
}
-
-//===========================================================================================================================
-// 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
//===========================================================================================================================
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
//===========================================================================================================================
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 );
//===========================================================================================================================
mDNSlocal OSStatus
-MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input )
+ConvertUTF8ToLsaString( const char * input, PLSA_UNICODE_STRING output )
{
int size;
OSStatus err;
//===========================================================================================================================
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;
}
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
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
( ( 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 );
}
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