tcpiputils/dnd/src/llmnrnotifyhandler.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // llmnrnotifyhandler.cpp - Link-local multicast name resolution 
       
    15 // notify handler
       
    16 // CDndLlmnrNotifyHandler
       
    17 //
       
    18 
       
    19 #ifdef LLMNR_ENABLED
       
    20 
       
    21 #if defined(TCPIP6_USE_COMMDB)
       
    22 #	include <commdb.h>
       
    23 #else
       
    24 #	include <commsdattypesv1_1.h>
       
    25 #       include <commsdattypesv1_1_partner.h>
       
    26 	using namespace CommsDat;
       
    27 #endif
       
    28 
       
    29 #include "engine.h"
       
    30 #include "llmnrresponder.h"
       
    31 #include "inet6log.h"
       
    32 
       
    33 CDndLlmnrNotifyHandler::CDndLlmnrNotifyHandler(CDndLlmnrResponder &aMaster)
       
    34  : iTimeout(CLlmnrNotifyHandlerTimeoutLinkage::Timeout), iMaster(aMaster)
       
    35  	{
       
    36  	}
       
    37 
       
    38 CDndLlmnrNotifyHandler::~CDndLlmnrNotifyHandler()
       
    39 	{
       
    40 	iTimeout.Cancel();
       
    41 	}
       
    42 
       
    43 void CDndLlmnrNotifyHandler::ConstructL()
       
    44 	{
       
    45 	LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::ConstructL() size=%d\r\n"), (TInt)sizeof(*this)));
       
    46 	}
       
    47 
       
    48 void CDndLlmnrNotifyHandler::ConfigurationChanged()
       
    49 	{
       
    50 	iMaster.iControl.Timer().Set(iTimeout, iMaster.iLlmnrConf->iNotifyTime);
       
    51 	}
       
    52 
       
    53 void CDndLlmnrNotifyHandler::ScanInterfaces()
       
    54 	{
       
    55 	(void)iMaster.iControl.CheckResult
       
    56 		(_L("Setting Socket options"),
       
    57 		 iMaster.iControl.iSocket.SetOpt(KSoInetEnumInterfaces,
       
    58 		 KSolInetIfCtrl));
       
    59 
       
    60 	TSoInetInterfaceInfo *info = new TSoInetInterfaceInfo; // allocate large struct from heap!
       
    61 	if (info == NULL)
       
    62 		return; // No memory!
       
    63 	TPckg<TSoInetInterfaceInfo> opt(*info);
       
    64 
       
    65 	TPckgBuf<TSoInetIfQuery> opt2;
       
    66 	opt2().iName.SetLength(0);
       
    67 
       
    68 	TUint32 iap_id = 0;			// Current IAP ID (== iZone[1])
       
    69 	TInt llmnr_disabled = 0;	// (init just to silence warning! this value is never used).
       
    70 
       
    71 	iMaster.UpdateStart();
       
    72 	while(iMaster.iControl.iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone)
       
    73 		{
       
    74 		// Check address configured
       
    75 		if(opt().iAddress.IsUnspecified())
       
    76 			continue; // No address, ignore
       
    77 		// KSoInetNextInterface returns an entry for each configured
       
    78 		// address. Skip entry, if previous entry was the same real
       
    79 		// interface. [This is only optimization that lessens the
       
    80 		// generated log messages--not for speed].
       
    81 		if (opt().iName.Compare(opt2().iName) == 0)
       
    82 			continue;
       
    83 		opt2().iName = opt().iName;
       
    84 		TInt err = iMaster.iControl.iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, opt2);
       
    85 		if(err != KErrNone)
       
    86 			{
       
    87 			LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::ScanInterfaces GetOpt KSoInetIfQueryByName error: %d"),err));
       
    88 			}
       
    89 		else
       
    90 			{
       
    91 			LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::ScanInterfaces - Interface up, name: %S\r\n"), &opt().iName));
       
    92 
       
    93 			if (iap_id != opt2().iZone[1])
       
    94 				{
       
    95 				// Different IAP, need to find whether LLMNR is to be enabled or disabled
       
    96 				iap_id = opt2().iZone[1];
       
    97 				TRAPD(err, llmnr_disabled = IsLlmnrDisabledL(iap_id));
       
    98 				if (err != KErrNone)
       
    99 					llmnr_disabled = 1;	// By default (if no configuration present), disable it.
       
   100 				}
       
   101 			TIpVer ipver;
       
   102 			if(opt().iAddress.Family() == KAfInet || opt().iAddress.IsV4Mapped())
       
   103 				ipver = EIPv4;
       
   104 			else
       
   105 				ipver = EIPv6;
       
   106 			iMaster.UpdateInterface(opt2().iName, ipver, opt2().iZone, opt().iHwAddr, llmnr_disabled);
       
   107 			}
       
   108 		}
       
   109 	delete info;
       
   110 	iMaster.UpdateFinish();
       
   111 	}
       
   112 
       
   113 void CDndLlmnrNotifyHandler::Timeout(const TTime &)
       
   114 	{
       
   115 	LOG(Log::Printf(_L("--> CDndLlmnrNotifyHandler::Timeout() -start-")));
       
   116 	ScanInterfaces();
       
   117 	LOG(Log::Printf(_L("<-- CDndLlmnrNotifyHandler::Timeout() -exit-")));
       
   118 	}
       
   119 
       
   120 
       
   121 
       
   122 /**
       
   123 * Acquire LLMNR configuration flag for the IAP from the CommDB.
       
   124 *
       
   125 * @return
       
   126 *	@li 0, if configuration not found or LLMNR is enabled by the configuration
       
   127 *	@li 1, if LLMNR is disabled by the configuration.
       
   128 *
       
   129 * Leave is implicit disable.
       
   130 */
       
   131 TInt CDndLlmnrNotifyHandler::IsLlmnrDisabledL(TUint32 aIap)
       
   132 	{
       
   133 	TBool enable = 1;	// If CommsDB does not have SERVICE_ENABLE_LLMNR, the default is enabled!
       
   134 #if defined(TCPIP6_USE_COMMDB)
       
   135 #	ifdef SERVICE_ENABLE_LLMNR
       
   136 	CCommsDatabase* db = CCommsDatabase::NewL();
       
   137 	CleanupStack::PushL(db);	// cleanup 1
       
   138 
       
   139 	CCommsDbTableView* iap = db->OpenViewMatchingUintLC(TPtrC(IAP), TPtrC(COMMDB_ID), aIap);	// cleanup 2
       
   140 	User::LeaveIfError(iap->GotoFirstRecord());
       
   141 	TBuf<KCommsDbSvrMaxFieldLength> service_type;
       
   142 	TUint32 service;
       
   143 	iap->ReadTextL(TPtrC(IAP_SERVICE_TYPE), service_type);
       
   144 	iap->ReadUintL(TPtrC(IAP_SERVICE), service);
       
   145 	CCommsDbTableView *srv = db->OpenViewMatchingUintLC(service_type, TPtrC(COMMDB_ID), service);	// cleanup 3
       
   146 	User::LeaveIfError(srv->GotoFirstRecord());
       
   147 	srv->ReadBoolL(TPtrC(SERVICE_ENABLE_LLMNR), enable);
       
   148 	CleanupStack::PopAndDestroy(3);
       
   149 #	else
       
   150 	(void)aIap;
       
   151 #	endif
       
   152 #else
       
   153 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   154 	CMDBSession *dB = CMDBSession::NewLC(KCDVersion1_2);
       
   155 #else
       
   156 	CMDBSession *dB = CMDBSession::NewLC(KCDVersion1_1);
       
   157 #endif
       
   158 
       
   159 	
       
   160 	// Reveal hidden or private IAP records if a licensee has chosen to protect a record
       
   161 	// using one of these flags - the API to do this is public so internal components
       
   162 	// have to support the use of such records.
       
   163 	dB->SetAttributeMask( ECDHidden | ECDPrivate );
       
   164 
       
   165 	CCDIAPRecord* iap = static_cast<CCDIAPRecord *>(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord));
       
   166 	CleanupStack::PushL(iap);
       
   167 	iap->SetRecordId(aIap);
       
   168 	LOG(Log::Printf(_L("IsLlmnrDisabledL: LoadL for IAP=%d"), aIap));
       
   169 	iap->LoadL(*dB);
       
   170 	LOG(Log::Printf(_L("IsLlmnrDisabledL: LoadL OK, doing LoadL for service")));
       
   171 #if 0
       
   172 	iap->iService.LoadL(*dB);
       
   173 #else
       
   174 	const TDesC& servType = iap->iServiceType;
       
   175 
       
   176 	if (servType.CompareF(TPtrC(KCDTypeNameDialOutISP))==0)
       
   177 		{
       
   178 		iap->iService.iLinkedRecord = static_cast<CCDDialOutISPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord));
       
   179 		}
       
   180 	else if (servType.CompareF(TPtrC(KCDTypeNameDialInISP))==0)
       
   181 		{
       
   182 		iap->iService.iLinkedRecord = static_cast<CCDDialInISPRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdDialInISPRecord));
       
   183 		}
       
   184 	else if (servType.CompareF(TPtrC(KCDTypeNameLANService))==0)
       
   185 		{
       
   186 		iap->iService.iLinkedRecord = static_cast<CCDLANServiceRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdLANServiceRecord));
       
   187 		}
       
   188 	else if (servType.CompareF(TPtrC(KCDTypeNameWLANServiceExt))==0)
       
   189 		{
       
   190 		iap->iService.iLinkedRecord = static_cast<CCDWLANServiceExtRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdWLANServiceExtRecord));
       
   191 		}
       
   192 	else if (servType.CompareF(TPtrC(KCDTypeNameVPNService))==0)
       
   193 		{
       
   194 		iap->iService.iLinkedRecord = static_cast<CCDVPNServiceRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdVPNServiceRecord));
       
   195 		}
       
   196 	else if (servType.CompareF(TPtrC(KCDTypeNameVPNService))==0)
       
   197 		{
       
   198 		iap->iService.iLinkedRecord = static_cast<CCDVPNServiceRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdVPNServiceRecord));
       
   199 		}
       
   200 	else if (servType.CompareF(TPtrC(KCDTypeNameOutgoingWCDMA))==0)
       
   201 		{
       
   202 		iap->iService.iLinkedRecord = static_cast<CCDOutgoingGprsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord));
       
   203 		}
       
   204 	else if (servType.CompareF(TPtrC(KCDTypeNameIncomingWCDMA))==0)
       
   205 		{
       
   206 		iap->iService.iLinkedRecord = static_cast<CCDIncomingGprsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdIncomingGprsRecord));
       
   207 		}
       
   208 	else if (servType.CompareF(TPtrC(KCDTypeNameDefaultWCDMA))==0)
       
   209 		{
       
   210 		iap->iService.iLinkedRecord = static_cast<CCDDefaultWCDMARecord*>(CCDRecordBase::RecordFactoryL(KCDTIdDefaultWCDMARecord));
       
   211 		}
       
   212 	else
       
   213 		{
       
   214 		LOG(Log::Printf(_L("CDndLlmnrNotifyHandler::IsLlmnrDisabledL() service type not supported (%S)\r\n"), &servType));
       
   215 		goto fail;
       
   216 		}
       
   217 	iap->iService.iLinkedRecord->SetRecordId(iap->iService);
       
   218 	iap->iService.iLinkedRecord->LoadL(*dB);
       
   219 #endif
       
   220 fail:
       
   221 	CCDServiceRecordBase *const ptrService = static_cast<CCDServiceRecordBase *>(iap->iService.iLinkedRecord);
       
   222 	LOG(Log::Printf(_L("IsLlmnrDisabledL: LoadL for service returns=[%u]"), (TInt)ptrService));
       
   223 	if (ptrService)
       
   224 		enable = ptrService->iServiceEnableLlmnr;
       
   225 	else
       
   226 		enable = 0;
       
   227 	CleanupStack::PopAndDestroy(2);		
       
   228 #endif
       
   229 	LOG(Log::Printf(_L("IsLlmnrDisabledL: enable=%d"), enable));
       
   230 	return enable == 0;
       
   231 	}
       
   232 
       
   233 
       
   234 #endif