diff -r 000000000000 -r af10295192d8 tcpiputils/dnd/src/llmnrnotifyhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tcpiputils/dnd/src/llmnrnotifyhandler.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,234 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// llmnrnotifyhandler.cpp - Link-local multicast name resolution +// notify handler +// CDndLlmnrNotifyHandler +// + +#ifdef LLMNR_ENABLED + +#if defined(TCPIP6_USE_COMMDB) +# include +#else +# include +# include + using namespace CommsDat; +#endif + +#include "engine.h" +#include "llmnrresponder.h" +#include "inet6log.h" + +CDndLlmnrNotifyHandler::CDndLlmnrNotifyHandler(CDndLlmnrResponder &aMaster) + : iTimeout(CLlmnrNotifyHandlerTimeoutLinkage::Timeout), iMaster(aMaster) + { + } + +CDndLlmnrNotifyHandler::~CDndLlmnrNotifyHandler() + { + iTimeout.Cancel(); + } + +void CDndLlmnrNotifyHandler::ConstructL() + { + LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::ConstructL() size=%d\r\n"), (TInt)sizeof(*this))); + } + +void CDndLlmnrNotifyHandler::ConfigurationChanged() + { + iMaster.iControl.Timer().Set(iTimeout, iMaster.iLlmnrConf->iNotifyTime); + } + +void CDndLlmnrNotifyHandler::ScanInterfaces() + { + (void)iMaster.iControl.CheckResult + (_L("Setting Socket options"), + iMaster.iControl.iSocket.SetOpt(KSoInetEnumInterfaces, + KSolInetIfCtrl)); + + TSoInetInterfaceInfo *info = new TSoInetInterfaceInfo; // allocate large struct from heap! + if (info == NULL) + return; // No memory! + TPckg opt(*info); + + TPckgBuf opt2; + opt2().iName.SetLength(0); + + TUint32 iap_id = 0; // Current IAP ID (== iZone[1]) + TInt llmnr_disabled = 0; // (init just to silence warning! this value is never used). + + iMaster.UpdateStart(); + while(iMaster.iControl.iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) + { + // Check address configured + if(opt().iAddress.IsUnspecified()) + continue; // No address, ignore + // KSoInetNextInterface returns an entry for each configured + // address. Skip entry, if previous entry was the same real + // interface. [This is only optimization that lessens the + // generated log messages--not for speed]. + if (opt().iName.Compare(opt2().iName) == 0) + continue; + opt2().iName = opt().iName; + TInt err = iMaster.iControl.iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, opt2); + if(err != KErrNone) + { + LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::ScanInterfaces GetOpt KSoInetIfQueryByName error: %d"),err)); + } + else + { + LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::ScanInterfaces - Interface up, name: %S\r\n"), &opt().iName)); + + if (iap_id != opt2().iZone[1]) + { + // Different IAP, need to find whether LLMNR is to be enabled or disabled + iap_id = opt2().iZone[1]; + TRAPD(err, llmnr_disabled = IsLlmnrDisabledL(iap_id)); + if (err != KErrNone) + llmnr_disabled = 1; // By default (if no configuration present), disable it. + } + TIpVer ipver; + if(opt().iAddress.Family() == KAfInet || opt().iAddress.IsV4Mapped()) + ipver = EIPv4; + else + ipver = EIPv6; + iMaster.UpdateInterface(opt2().iName, ipver, opt2().iZone, opt().iHwAddr, llmnr_disabled); + } + } + delete info; + iMaster.UpdateFinish(); + } + +void CDndLlmnrNotifyHandler::Timeout(const TTime &) + { + LOG(Log::Printf(_L("--> CDndLlmnrNotifyHandler::Timeout() -start-"))); + ScanInterfaces(); + LOG(Log::Printf(_L("<-- CDndLlmnrNotifyHandler::Timeout() -exit-"))); + } + + + +/** +* Acquire LLMNR configuration flag for the IAP from the CommDB. +* +* @return +* @li 0, if configuration not found or LLMNR is enabled by the configuration +* @li 1, if LLMNR is disabled by the configuration. +* +* Leave is implicit disable. +*/ +TInt CDndLlmnrNotifyHandler::IsLlmnrDisabledL(TUint32 aIap) + { + TBool enable = 1; // If CommsDB does not have SERVICE_ENABLE_LLMNR, the default is enabled! +#if defined(TCPIP6_USE_COMMDB) +# ifdef SERVICE_ENABLE_LLMNR + CCommsDatabase* db = CCommsDatabase::NewL(); + CleanupStack::PushL(db); // cleanup 1 + + CCommsDbTableView* iap = db->OpenViewMatchingUintLC(TPtrC(IAP), TPtrC(COMMDB_ID), aIap); // cleanup 2 + User::LeaveIfError(iap->GotoFirstRecord()); + TBuf service_type; + TUint32 service; + iap->ReadTextL(TPtrC(IAP_SERVICE_TYPE), service_type); + iap->ReadUintL(TPtrC(IAP_SERVICE), service); + CCommsDbTableView *srv = db->OpenViewMatchingUintLC(service_type, TPtrC(COMMDB_ID), service); // cleanup 3 + User::LeaveIfError(srv->GotoFirstRecord()); + srv->ReadBoolL(TPtrC(SERVICE_ENABLE_LLMNR), enable); + CleanupStack::PopAndDestroy(3); +# else + (void)aIap; +# endif +#else +#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY + CMDBSession *dB = CMDBSession::NewLC(KCDVersion1_2); +#else + CMDBSession *dB = CMDBSession::NewLC(KCDVersion1_1); +#endif + + + // Reveal hidden or private IAP records if a licensee has chosen to protect a record + // using one of these flags - the API to do this is public so internal components + // have to support the use of such records. + dB->SetAttributeMask( ECDHidden | ECDPrivate ); + + CCDIAPRecord* iap = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord)); + CleanupStack::PushL(iap); + iap->SetRecordId(aIap); + LOG(Log::Printf(_L("IsLlmnrDisabledL: LoadL for IAP=%d"), aIap)); + iap->LoadL(*dB); + LOG(Log::Printf(_L("IsLlmnrDisabledL: LoadL OK, doing LoadL for service"))); +#if 0 + iap->iService.LoadL(*dB); +#else + const TDesC& servType = iap->iServiceType; + + if (servType.CompareF(TPtrC(KCDTypeNameDialOutISP))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameDialInISP))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDialInISPRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameLANService))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdLANServiceRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameWLANServiceExt))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWLANServiceExtRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameVPNService))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdVPNServiceRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameVPNService))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdVPNServiceRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameOutgoingWCDMA))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameIncomingWCDMA))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdIncomingGprsRecord)); + } + else if (servType.CompareF(TPtrC(KCDTypeNameDefaultWCDMA))==0) + { + iap->iService.iLinkedRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDefaultWCDMARecord)); + } + else + { + LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::IsLlmnrDisabledL() service type not supported (%S)\r\n"), &servType)); + goto fail; + } + iap->iService.iLinkedRecord->SetRecordId(iap->iService); + iap->iService.iLinkedRecord->LoadL(*dB); +#endif +fail: + CCDServiceRecordBase *const ptrService = static_cast(iap->iService.iLinkedRecord); + LOG(Log::Printf(_L("IsLlmnrDisabledL: LoadL for service returns=[%u]"), (TInt)ptrService)); + if (ptrService) + enable = ptrService->iServiceEnableLlmnr; + else + enable = 0; + CleanupStack::PopAndDestroy(2); +#endif + LOG(Log::Printf(_L("IsLlmnrDisabledL: enable=%d"), enable)); + return enable == 0; + } + + +#endif