diff -r 000000000000 -r af10295192d8 networkprotocols/dnsproxy/dnsproxyserver/src/dnsproxyservconf.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkprotocols/dnsproxy/dnsproxyserver/src/dnsproxyservconf.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,333 @@ +// Copyright (c) 2008-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: +// This class builds the DNS server list which are configured on all the available +// interfaces.This is derived from active object. +// + + + +/** + @file + @internalTechnology +*/ +#include "e32debug.h" +#include "inet6log.h" +#include +#include +#include + +#include "dnsproxyservconf.h" +#include "dnsproxyengine.h" +#include "dnsproxylistener.h" +#include "dnsproxylog.h" + +//Constructor for dns server configuration class +CDnsServerConfig::CDnsServerConfig(CDnsProxyEngine &aEngine):CActive(CActive::EPriorityStandard),iProxyEngine(aEngine) + { + + } +//Destructor for dns server config class +CDnsServerConfig::~CDnsServerConfig() + { + Cancel(); + //Free the list + iServerList.ResetAndDestroy(); + //Close the open socket + iSocket.Close(); + //connection close + iConn.Close(); + //Socket server + iSocketServer.Close(); + } + +//Creates an instance of +CDnsServerConfig* CDnsServerConfig::NewL(CDnsProxyEngine &aEngine) +/** + * + * Create an instance of config server + * + * @param &aEngine Instance of engine + * @return The only CDnsServerConfig instance to be used + * + * @internalTechnology + */ + { + CDnsServerConfig* server = new(ELeave)CDnsServerConfig(aEngine); + CleanupStack::PushL(server); + server->ConstructL(); + CleanupStack::Pop(); + return server; + } + +void CDnsServerConfig::ConstructL() +/** + * Second phase of construction + * Initializes array list and creates socket server handle and + * socket for retrieving DNS server configuration on the available + * interface + * + * @internalTechnology + */ + { + User::LeaveIfError(iSocketServer.Connect()); + User::LeaveIfError(iConn.Open(iSocketServer,KConnectionTypeDefault)); + User::LeaveIfError(iSocket.Open(iSocketServer,KAfInet, KSockDatagram, KProtocolInetUdp)); + + CActiveScheduler::Add(this); + } + +void CDnsServerConfig::RunL() +/** + * + * Builds server list on interface notification. + * This is RunL of an active object. + * + * @internalTechnology + */ + { + __LOG1("\n CDnsServerConfig::RunL() Entry Status is:", iStatus.Int()); + iServerList.ResetAndDestroy(); + } + +void CDnsServerConfig::DoCancel() +/** + * + * Implements DoCancel() method of an active object. This cancels the registration + * for interface notification. + * + * @internalTechnology + */ + { + iConn.CancelAllInterfaceNotification(); + } + +// CDnsServerConfig::AddDnsServerToList +// ********************************** +void CDnsServerConfig::AddDnsServerToListL(const TInetAddr &aAddr, RSocket &aSocket, TUint32 aIapId) +/** + * Add new address to the server list. + * + * @param aAddr address of the DNS server + * @param aSocket Socket + * + * @internalTechnology +*/ + { + __LOG("\n CDnsServerConfig::AddDnsServerToListL() Entry") + if (aAddr.IsUnspecified()) + return; // No address, nothing to add + + // Check if DNS server address is same as one we are listening on + if(iProxyEngine.iProxyIfAddr.Address() == aAddr.Address()) + { + return; + } + + // + // Normalize all addresses into IPv6 format + // + TDnsServerInfo* sd = new(ELeave)TDnsServerInfo; + if(sd == NULL) + { + return; + } + sd->iAddr = aAddr; + if (sd->iAddr.Family() == KAfInet) + sd->iAddr.ConvertToV4Mapped(); + else if (sd->iAddr.Family() != KAfInet6) + return; // Only IPv4 or IPv6 addresses are valid + if (sd->iAddr.IsMulticast() || sd->iAddr.IsLoopback() || sd->iAddr.IsLinkLocal() || sd->iAddr.IsSiteLocal()) + { + delete sd; + return; + } + else + sd->iScope = KDnsServerScopeGlobal; + + if (!sd->iAddr.Port()) + sd->iAddr.SetPort(KDnsProxyPort); + + TBuf dst; + sd->iAddr.OutputWithScope(dst); + TBuf src; + // DNS Proxy does not bring up interfaces. Hence server addresses must have a + // valid route, before they can be used. Thus, check it... + TPckgBuf opt; + opt().iDstAddr = aAddr; + const TBool has_route = + (aSocket.GetOpt(KSoInetIfQueryByDstAddr, KSolInetIfQuery, opt) == KErrNone) && !opt().iSrcAddr.IsUnspecified(); + + if (!has_route) + { + __LOG2("\n CDnsServerConfig::AddDnsServerToListL() nameserver: [%S] has no route (src=%S)",&dst, &src) + delete sd; + return; // No route, unusable for now -- ignore + } + + //Add IapId for the interface + sd->iIapId = aIapId; + + //Check the connection status and add DNS server to the list + if(GetConnectionStatus(*sd)) + { + __LOG2("\n CDnsServerConfig::AddDnsServerToListL() nameserver: [%S] (src=%S)",&dst, &src) + iServerList.AppendL(sd); + } + else + { + //Connection is not existing, hence don't add DNS server address to the list + __LOG2("\n CDnsServerConfig::AddDnsServerToListL() no connection for nameserver: [%S] (src=%S)",&dst, &src) + delete sd; + } + __LOG("\n CDnsServerConfig::AddDnsServerToListL() Exit") + } + +// CDnsServerConfig::BuildGlobalDnsServerListL +// ********************************** +void CDnsServerConfig::BuildGlobalDnsServerListL(TUint32 aIapId) +/** + * This method enumerates interfaces and builds the list of available. + * DNS servers. + * The method also gets called whenever any interface notification is received. + * + * @internalTechnology +*/ + + { + __LOG("\n CDnsServerConfig::BuildGlobalDnsServerListL() Entry") + TInt err; + TSoInetInterfaceInfo* info = new TSoInetInterfaceInfo; // allocate large struct from heap! + + iServerList.ResetAndDestroy(); + TInetAddr localaddr = iProxyEngine.GetProxyListener()->GetInterfaceIpAddress(); + iProxyEngine.UpdateLocalAddr(localaddr); + if (info && (err = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl)) == KErrNone) + { + TPckg opt(*info); + while (iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone) + { + TSoInetIfQuery ifquery; + TPckg queryopt(ifquery); + + ifquery.iName = opt().iName; + err = iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, queryopt); + + if(err == KErrNone) + { + if (opt().iName.Length() == 0) + continue; // "null" interface, ignore + // Add DNS servers configured on specified Iap only + if (!opt().iAddress.IsUnspecified() && (aIapId == ifquery.iZone[1])) + { + // Add name server information to the list + AddDnsServerToListL((TInetAddr&)(opt().iNameSer1), iSocket, ifquery.iZone[1]); + AddDnsServerToListL((TInetAddr&)(opt().iNameSer2), iSocket, ifquery.iZone[1]); + } + + } + + } + } + delete info; + NotifyInterfaceChange(); + __LOG("\n CDnsServerConfig::BuildGlobalDnsServerListL() Exit") + } + +TDnsServerInfo* CDnsServerConfig::GetDnsServerInfo(TInt aServerIndex) +/** + * This method returns the DNS server info based on the list index/ server id. + * @param aServerId + * @internalTechnology +*/ + + { + TDnsServerInfo* serverinfo = NULL; + // Check if there are any dns servers in the list and the index is less than the number + // of servers available + if(iServerList.Count() > 0 && aServerIndex < iServerList.Count()) + serverinfo = iServerList[aServerIndex]; + + return serverinfo; + } + + +//Returns number of servers in the list +TInt CDnsServerConfig::GetServerCount() const +/** + * This method returns the DNS server count. + * + * @internalTechnology +*/ + + { + __LOG1("\n CDnsServerConfig::GetServerCount Server count is %d", iServerList.Count()) + return (iServerList.Count()); + } + + + +void CDnsServerConfig::NotifyInterfaceChange() +/** + * This method registers for interface notification and sets the active object. + * + * @internalTechnology +*/ + + { + __LOG("\n CDnsServerConfig::NotifyInterfaceChange() Entry") + if(IsActive()) + return; + + iConn.AllInterfaceNotification(info, iStatus); + SetActive(); + __LOG("\n CDnsServerConfig::NotifyInterfaceChange() Exit") + } + +TBool CDnsServerConfig::GetConnectionStatus(TDnsServerInfo& aInfo) +/** + * This method checks for uplink connection status. + * @param aInfo - Dns server info structure containing IAP id for the interface + * + * + * @internalTechnology +*/ + { + __LOG("\n CDnsServerConfig::GetConnectionStatus Entry") + TBool connected = EFalse; + TUint connectionCount = 0; + TPckgBuf connectionInfo; + TInt err = iConn.EnumerateConnections(connectionCount); + + if(err != KErrNone) + { + __LOG("\n CDnsServerConfig::GetConnectionStatus, Enumerate Connections failure"); + return connected; + } + + for (TUint i = 1; i <= connectionCount; ++i) + { + iConn.GetConnectionInfo(i, connectionInfo); + + if (aInfo.iIapId == connectionInfo().iIapId) + { + __LOG("\n CDnsServerConfig::GetConnectionStatus Conn Info for IAP is present") + //Set the Up flag to True + connected = ETrue; + //Copy this connection information to information + aInfo.iConnInfo = connectionInfo; + } + } + __LOG("\n CDnsServerConfig::GetConnectionStatus Exit") + return connected; + }