Commit 498d9c8e authored by Fawzi Mohamed's avatar Fawzi Mohamed
Browse files

mdnssd: More robust behaviour on windows



* use user local register key to store settings (reduces failures)
* more unique names (avoid clashes with apple version)
* more robust error handling in general
* added (disabled) registry free method to detect tcp/ip changes
* add resource for event logging

Change-Id: I4cf00d09be2731ba294f72edbaa04e1f254adef4
Reviewed-by: default avatarOliver Wolff <oliver.wolff@nokia.com>
Reviewed-by: default avatarJoerg Bornemann <joerg.bornemann@nokia.com>
Reviewed-by: default avatarFawzi Mohamed <fawzi.mohamed@nokia.com>
parent f0c22215
......@@ -23,8 +23,8 @@
# define kServiceParametersSoftware L"SOFTWARE"
# define kServiceParametersAppleComputer L"Apple Computer, Inc."
# define kServiceParametersBonjour L"Bonjour"
# define kServiceParametersNode L"SOFTWARE\\Apple Inc.\\Bonjour"
# define kServiceParametersBonjour L"BonjourFallback"
# define kServiceParametersNode L"SOFTWARE\\Nokia\\Bonjour"
# define kServiceName L"Bonjour Service"
# define kServiceDynDNSBrowseDomains L"BrowseDomains"
# define kServiceDynDNSHostNames L"HostNames"
......@@ -41,8 +41,8 @@
# define kServiceParametersSoftware "SOFTWARE"
# define kServiceParametersAppleComputer "Apple Computer, Inc."
# define kServiceParametersBonjour "Bonjour"
# define kServiceParametersNode "SOFTWARE\\Apple Inc.\\Bonjour"
# define kServiceParametersBonjour "BonjourFallback"
# define kServiceParametersNode "SOFTWARE\\Nokia\\Bonjour"
# define kServiceName "Bonjour Service"
# define kServiceDynDNSBrowseDomains "BrowseDomains"
# define kServiceDynDNSHostNames "HostNames"
......
......@@ -120,6 +120,7 @@ static void CALLBACK PowerResumeNotification( HANDLE event, void * context );
static void CALLBACK InterfaceListNotification( SOCKET socket, LPWSANETWORKEVENTS event, void *context );
static void CALLBACK ComputerDescriptionNotification( HANDLE event, void *context );
static void CALLBACK TCPChangedNotification( HANDLE event, void *context );
static void CALLBACK TCPChangedNotification2( HANDLE event, void *context );
static void CALLBACK DDNSChangedNotification( HANDLE event, void *context );
static void CALLBACK FileSharingChangedNotification( HANDLE event, void *context );
static void CALLBACK FirewallChangedNotification( HANDLE event, void *context );
......@@ -178,6 +179,8 @@ DEBUG_LOCAL HKEY gDescKey = NULL;
DEBUG_LOCAL HANDLE gDescChangedEvent = NULL; // Computer description changed event
DEBUG_LOCAL HKEY gTcpipKey = NULL;
DEBUG_LOCAL HANDLE gTcpipChangedEvent = NULL; // TCP/IP config changed
DEBUG_LOCAL HANDLE gTcpipChangedEvent2Handle = NULL; // handle for overlapped comm of gTcpipChangedEvent2
DEBUG_LOCAL OVERLAPPED gTcpipChangedEvent2; // TCP/IP config changed (using NotiyAddrChanges)
DEBUG_LOCAL HKEY gDdnsKey = NULL;
DEBUG_LOCAL HANDLE gDdnsChangedEvent = NULL; // DynDNS config changed
DEBUG_LOCAL HKEY gFileSharingKey = NULL;
......@@ -477,7 +480,7 @@ static OSStatus SetServiceParameters()
//
// Add/Open Parameters section under service entry in registry
//
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode, &key );
require_noerr( err, exit );
//
......@@ -522,7 +525,7 @@ static OSStatus GetServiceParameters()
//
// Add/Open Parameters section under service entry in registry
//
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode, &key );
require_noerr( err, exit );
valueLen = sizeof(DWORD);
......@@ -621,7 +624,7 @@ static OSStatus CheckFirewall()
}
}
require_action( isRunning, exit, err = kUnknownErr );
// require_action( isRunning, exit, err = kUnknownErr );
// Check to see if we've managed the firewall.
// This package might have been installed, then
......@@ -629,7 +632,7 @@ static OSStatus CheckFirewall()
// the case, then we need to manipulate the firewall
// so networking works correctly.
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode, &key );
require_noerr( err, exit );
valueLen = sizeof(DWORD);
......@@ -919,7 +922,7 @@ static OSStatus ServiceSetupEventLogging( void )
// Add/Open source name as a sub-key under the Application key in the EventLog registry key.
s = TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\") kServiceName;
err = RegCreateKey( HKEY_LOCAL_MACHINE, s, &key );
err = RegCreateKey( HKEY_CURRENT_USER, s, &key );
require_noerr( err, exit );
// Add the name to the EventMessageFile subkey.
......@@ -1459,6 +1462,7 @@ mDNSlocal mStatus SetupNotifications()
err = mDNSPollRegisterEvent( gDescChangedEvent, ComputerDescriptionNotification, NULL );
require_noerr( err, exit );
#ifndef TCP_CHANGES_NO_REGISTRY
// This will catch all changes to tcp/ip networking, including changes to the domain search list
gTcpipChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
......@@ -1470,13 +1474,28 @@ mDNSlocal mStatus SetupNotifications()
require_noerr( err, exit );
err = mDNSPollRegisterEvent( gTcpipChangedEvent, TCPChangedNotification, NULL );
require_noerr( err, exit );
#else
// This is another way to catch tcp/ip changes, which avoid the registry
// (better if the registry does not work reliably)
{
DWORD ret;
gTcpipChangedEvent2.hEvent = WSACreateEvent();
err = gTcpipChangedEvent2.hEvent == WSA_INVALID_EVENT;
require_noerr( err, skipTCP2 );
ret = NotifyAddrChange(&gTcpipChangedEvent2Handle, &gTcpipChangedEvent2);
if (ret != NO_ERROR)
err = (WSAGetLastError() != WSA_IO_PENDING );
require_noerr( err, skipTCP2 );
err = mDNSPollRegisterEvent( gTcpipChangedEvent2.hEvent, &TCPChangedNotification2, NULL );
check_noerr( err );
}
#endif
// This will catch all changes to ddns configuration
gDdnsChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
err = translate_errno( gDdnsChangedEvent, (mStatus) GetLastError(), kUnknownErr );
require_noerr( err, exit );
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup"), &gDdnsKey );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode TEXT("\\DynDNS\\Setup"), &gDdnsKey );
require_noerr( err, exit );
err = RegNotifyChangeKeyValue( gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
require_noerr( err, exit );
......@@ -1536,7 +1555,7 @@ mDNSlocal mStatus SetupNotifications()
gAdvertisedServicesChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
err = translate_errno( gAdvertisedServicesChangedEvent, (mStatus) GetLastError(), kUnknownErr );
require_noerr( err, exit );
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\Services"), &gAdvertisedServicesKey );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode TEXT("\\Services"), &gAdvertisedServicesKey );
require_noerr( err, exit );
err = RegNotifyChangeKeyValue( gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
require_noerr( err, exit );
......@@ -1601,6 +1620,14 @@ mDNSlocal mStatus TearDownNotifications()
gTcpipChangedEvent = NULL;
}
if ( gTcpipChangedEvent2Handle != NULL || gTcpipChangedEvent2.hEvent != NULL )
{
mDNSPollUnregisterEvent( gTcpipChangedEvent2.hEvent );
CancelIPChangeNotify(&gTcpipChangedEvent2);
gTcpipChangedEvent2Handle = NULL;
gTcpipChangedEvent2.hEvent = NULL;
}
if ( gDdnsChangedEvent != NULL )
{
mDNSPollUnregisterEvent( gDdnsChangedEvent );
......@@ -1827,6 +1854,8 @@ TCPChangedNotification( HANDLE event, void *context )
DEBUG_UNUSED( event );
DEBUG_UNUSED( context );
dlog( kDebugLevelInfo, DEBUG_NAME "TCPChangeNotification\n" );
TCPIPConfigDidChange( &gMDNSRecord );
udsserver_handle_configchange( &gMDNSRecord );
......@@ -1840,6 +1869,34 @@ TCPChangedNotification( HANDLE event, void *context )
}
mDNSlocal void CALLBACK
TCPChangedNotification2( HANDLE event, void *context ){
int err;
DWORD dwRetVal;
DEBUG_UNUSED( event );
DEBUG_UNUSED( context );
dlog( kDebugLevelInfo, DEBUG_NAME "TCPChangeNotification2\n" );
err = WSAResetEvent(gTcpipChangedEvent2.hEvent);
check_noerr(err);
//std::cout << "WSAResetEvent() failed. Error code: " << WSAGetLastError() << std::endl;
// The TCP/IP might have changed
TCPIPConfigDidChange( &gMDNSRecord );
udsserver_handle_configchange( &gMDNSRecord );
// and reset the event handler
// call NotifyAddrChange in synchronous mode
dwRetVal = NotifyAddrChange(&gTcpipChangedEvent2Handle, &gTcpipChangedEvent2);
check_noerr(dwRetVal != ERROR_IO_PENDING);
}
mDNSlocal void CALLBACK
DDNSChangedNotification( HANDLE event, void *context )
{
......@@ -2142,7 +2199,7 @@ SystemWakeForNetworkAccess( LARGE_INTEGER * timeout )
// Make sure the user enabled bonjour sleep proxy client
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode L"\\Power Management", &key );
require_action( !err, exit, ok = FALSE );
dwSize = sizeof( DWORD );
err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
......
......@@ -1640,7 +1640,7 @@ mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mSt
check( strlen( p ) <= MAX_ESCAPED_DOMAIN_NAME );
name = kServiceParametersNode TEXT("\\DynDNS\\State\\HostNames");
err = RegCreateKey( HKEY_LOCAL_MACHINE, name, &key );
err = RegCreateKey( HKEY_CURRENT_USER, name, &key );
require_noerr( err, exit );
bStatus = ( status ) ? 0 : 1;
......@@ -2918,7 +2918,7 @@ mDNSlocal mStatus SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAdd
// for IPv4, but the IPv6 stack in Windows currently doesn't support IPv4-mapped IPv6 addresses and doesn't
// support the IPV6_V6ONLY socket option so the following code would typically not be executed (or needed).
#if( defined( IPV6_V6ONLY ) && ! defined( WIN_32 ) )
#if( defined( IPV6_V6ONLY ) && ! defined( WIN32 ) )
option = 1;
err = setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &option, sizeof( option ) );
check_translated_errno( err == 0, errno_compat(), kOptionErr );
......@@ -4462,7 +4462,7 @@ mDNSlocal void GetDDNSFQDN( domainname *const fqdn )
// Get info from Bonjour registry key
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
require_noerr( err, exit );
err = RegQueryString( key, "", &name, &dwSize, &enabled );
......@@ -4513,7 +4513,7 @@ mDNSlocal void GetDDNSConfig( DNameListElem ** domains, LPCSTR lpSubKey )
*domains = NULL;
err = RegCreateKey( HKEY_LOCAL_MACHINE, lpSubKey, &key );
err = RegCreateKey( HKEY_CURRENT_USER, lpSubKey, &key );
require_noerr( err, exit );
// Get information about this node
......@@ -4743,7 +4743,7 @@ CheckFileShares( mDNS * const m )
require_action_quiet( m->AdvertiseLocalAddresses && !m->ShutdownTime, exit, err = kNoErr );
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Services\\SMB", &key );
err = RegCreateKey( HKEY_CURRENT_USER, kServiceParametersNode L"\\Services\\SMB", &key );
if ( !err )
{
......
......@@ -89,10 +89,11 @@ win32 {
$$MC_FILES \
Service.rc
DEFINES += HAVE_IPV6 _WIN32_WINNT=0x0501 NDEBUG MDNS_DEBUGMSGS=0 TARGET_OS_WIN32 WIN32_LEAN_AND_MEAN USE_TCP_LOOPBACK PLATFORM_NO_STRSEP PLATFORM_NO_EPIPE PLATFORM_NO_RLIMIT UNICODE _UNICODE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 _LEGACY_NAT_TRAVERSAL_
DEFINES += NDEBUG
DEFINES += HAVE_IPV6 _WIN32_WINNT=0x0501 MDNS_DEBUGMSGS=0 TARGET_OS_WIN32 WIN32_LEAN_AND_MEAN USE_TCP_LOOPBACK PLATFORM_NO_STRSEP PLATFORM_NO_EPIPE PLATFORM_NO_RLIMIT UNICODE _UNICODE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 _LEGACY_NAT_TRAVERSAL_
LIBS += ws2_32.lib advapi32.lib ole32.lib oleaut32.lib iphlpapi.lib netapi32.lib user32.lib powrprof.lib shell32.lib
mc.output = ${QMAKE_FILE_BASE}.h
mc.output = ${QMAKE_FILE_BASE}.rc
mc.commands = mc ${QMAKE_FILE_NAME}
mc.input = MC_FILES
mc.CONFIG += no_link target_predeps explicit_dependencies
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment