--- /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 <commdb.h>
+#else
+# include <commsdattypesv1_1.h>
+# include <commsdattypesv1_1_partner.h>
+ 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<TSoInetInterfaceInfo> opt(*info);
+
+ TPckgBuf<TSoInetIfQuery> 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<KCommsDbSvrMaxFieldLength> 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<CCDIAPRecord *>(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<CCDDialOutISPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameDialInISP))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDDialInISPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdDialInISPRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameLANService))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDLANServiceRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdLANServiceRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameWLANServiceExt))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDWLANServiceExtRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdWLANServiceExtRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameVPNService))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDVPNServiceRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdVPNServiceRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameVPNService))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDVPNServiceRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdVPNServiceRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameOutgoingWCDMA))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDOutgoingGprsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameIncomingWCDMA))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDIncomingGprsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdIncomingGprsRecord));
+ }
+ else if (servType.CompareF(TPtrC(KCDTypeNameDefaultWCDMA))==0)
+ {
+ iap->iService.iLinkedRecord = static_cast<CCDDefaultWCDMARecord*>(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<CCDServiceRecordBase *>(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